

# Calling Amazon Web Services services from the Amazon SDK for C\$1\$1
<a name="working-with-aws-services"></a>

The following sections contain examples, tutorials, tasks, and guides that show you how to use the Amazon SDK for C\$1\$1 to work with Amazon services.

If you're new to the Amazon SDK for C\$1\$1, you might want to read through the [Getting started](getting-started.md) topic first.

You can find more code examples in the [C\$1\$1 example folder](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/cpp/example_code) on GitHub.

You can find more code examples in the [Code examples](cpp_code_examples.md) chapter of this guide or in the [Amazon Code Examples Repository](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/cpp/example_code) on GitHub. 

**Topics**
+ [Getting started on code examples](getting-started-code-examples.md)
+ [Getting started troubleshooting runtime errors](troubleshooting-runtime-errors.md)
+ [Guided examples](programming-services.md)

# Getting started with the Amazon SDK for C\$1\$1 code examples
<a name="getting-started-code-examples"></a>

## Structure of the code examples
<a name="structure"></a>

The [C\$1\$1 example folder](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/cpp/example_code) on Github contains project folders for each Amazon service. Typically, individual .cpp source files in the folders demonstrate a specific functionality or action for that service. For example, for Amazon DynamoDB, *getting* an item from the database and *uploading* an item to the database are two different types of action, so there is a separate file for each in the DynamoDB folder: `get_item.cpp` and `put_item.cpp`. Each .cpp file contains a `main()` function as an entrypoint to a standalone executable. The project executables are generated in a folder designated by your build system, and there is one executable file corresponding to each example source file. The file name of the executable follows the conventions of the platform such as `{name}.exe` or just `{name}` and any custom prefix `CMakeLists.txt` applies such as `run_`. 

**To run an example functionality**

1. Download the desired code example from the [Amazon Code Examples Repository](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/cpp/example_code) on GitHub. 

1. Open a .cpp file to explore its `main()` function and any called methods. 

1. Build the project, as demonstrated with the starter example in [Getting started using the Amazon SDK for C\$1\$1](getting-started.md). Note that building the project generates each executable for every source file in the project.

1. Run the executable for the selected functionality.
   + In a command prompt, run that program using the executable based on the name of the `*.cpp` file.
   + If you are working within an IDE, choose the `.cpp` file of the functionality you want to demonstrate and select it as the startup option (or startup object).

### Unit tests
<a name="unittest"></a>

Tests for examples are written using the GoogleTest framework. To learn more, see [GoogleTest Primer](https://google.github.io/googletest/primer.html) on the GoogleTest website.

The unit tests for each example are in a `tests` subfolder containing its own `CMakeLists.txt` file. For each example source file there is a corresponding test file named `gtest_<source file>`. The test executable for the subfolder is named `<Amazon Web Services service>_gtests`.

### CMakeLists.txt file
<a name="CMakeLists"></a>

The folder for each service contains a file named `CMakeLists.txt` file. Many of these files contain a construct similar to the following:

```
foreach(EXAMPLE IN LISTS EXAMPLES)
         add_executable(${EXAMPLE} ${EXAMPLE}.cpp)
         target_link_libraries(${EXAMPLE} aws-cpp-sdk-email aws-cpp-sdk-core)
endforeach()
```

 For each .cpp file in the folder, the `CMakeLists.txt` file builds an executable (cmake: `add_executable`) with a name based on the name of the source code file without the file extension. 

## Building and Debugging Code Examples in Visual Studio
<a name="buildingOnVisualStudio"></a>

**Building and running the Amazon S3 code example**

1. Obtain the Amazon S3 example source code. This procedure uses the [Amazon S3 code examples using the Amazon SDK for C\$1\$1](examples-s3.md) code example to get up and running using Visual Studio. 

1. In Windows Explorer, navigate to the `s3` folder (e.g. `\aws-doc-sdk-examples\cpp\example_code\s3`). 

1. Right click on the `s3` example folder and choose **Open with Visual Studio**.  Visual Studio for CMake projects don’t have a 'project' file, rather, it is the whole folder. 

1. In the **Configuration Selector** dropdown in the top menu of Visual Studio, ensure that the selected configuration matches the build type that you selected when building the SDK from source.  E.g. a **Debug** configuration should be selected if you built from source using debug (`-DCMAKE_BUILD_TYPE=Debug` in the CMake command line from the SDK installation instructions). 

1. Open file `CMakeLists.txt`. 

1. Click **Save**. Every time you click **Save** on the `CMakeLists.txt` file, Visual Studio refreshes the CMake-generated files.  If you have your **Output** tab displayed, you can see the resulting log messages from this generation. 
   + There is a drop-down box within the **Output** tab that says: "**Show output from:**" and **CMake** should be the option selected by default. 
   + Last message output should say "**CMake generation finished.**"  
   + If last message is not this, then the CMake file has issues. Do not proceed to further steps until this is resolved.  See [Troubleshooting Amazon SDK for C\$1\$1 build issues](troubleshooting-cmake.md). 
   + Note that the CMake cache is used by CMake for speed. If you are working through CMake issues, you want to ensure a ‘clean slate’ so that the error messages you are given is actually reflective of your most recent changes.  In the Solution Explorer, right-click on `CMakeLists.txt` and choose **CMake Cache**, then choose **Delete Cache**. Do this frequently when working progressively through CMake issues. 

1. To build and run examples from within Visual Studio, Visual Studio places executables in a different folder structure than the command line. To run the code, the SDK executables must be copied to the right place.  Find the “`TODO`” line of the CMakeLists file (\$1line 40) and choose the one commented for use in Visual Studio. Visual Studio does not use a subfolder dedicated to the build type so this is not included.  Switch the commented-out line in the `CMakeLists.txt` file for Visual Studio use. 

1. Delete the CMake cache (as described above), click in the `CMakeLists.txt` file to select/activate the tab, and choose **Save** on the `CMakeLists.txt` file again to initiate the CMake build files generation. 

1. Open the source file of the ‘program’ you wish to run.
   + For example, open `list_buckets.cpp`.
   + The Amazon S3 example folder is coded so that each showcased ‘feature’ of Amazon S3 is demonstrated in a dedicated executable for just that feature.  E.g. `list_buckets.cpp` will become an executable that only demonstrates the listing of buckets. 

1. In the top menu, choose **Build**, then choose **Build All**. 
   + The **Output** tab’s **Show output from** should reflect the selection of **Build**, and show all the building and linking messages. 
   + The last output should be: "**Build All succeeded.**" 
   + Now executables for each of the individual source files are generated.  You can confirm this by looking in the build output directory (e.g. `\aws-doc-sdk-examples\cpp\example_code\s3\out\build\x64-Debug`).
   + Note that the executables are prefixed with “run\$1” because the `CMakeLists.txt` file dictates this. 

1. In the top menu, there is a **green arrow** and a **drop-down selector** for **Debug Target**.  Choose `run_list_buckets.exe`. 

1. Click the **green arrow run button** to **Select Startup Item**. 

1. A Visual Studio Debug Console window will open and display the output of the code. 

1. Press a key to close the window, or manually close the window, to terminate the program.  You can also set breakpoints in the code and when you click run again the breakpoints will be hit. 

# Getting started troubleshooting runtime errors in the Amazon SDK for C\$1\$1
<a name="troubleshooting-runtime-errors"></a>

As you learn to develop applications with the Amazon SDK for C\$1\$1, it's also valuable to get comfortable in using both the Amazon Web Services Management Console and the Amazon CLI. These tools can be used interchangeably for various troubleshooting and diagnostics when runtime errors are encountered.

The following tutorial shows you an example of these troubleshooting and diagnostics tasks. It focuses on the `Access denied` error, which can be encountered for several different reasons. The tutorial shows an example of how you might determine the actual cause of the error. It focuses on two of the possible causes: incorrect permissions for the current user and a resource that isn't available to the current user.

**To get the project source and executables**

1. Download the Amazon S3 code example folder from [Amazon Code Examples Repository](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/cpp/example_code) on GitHub. 

1. Open `delete_bucket.cpp` and notice that there are two methods: `main()` and `DeleteBucket()`. `DeleteBucket()` uses the SDK to delete the bucket. 

1. Build the Amazon S3 example, using the same build steps explained in [Getting started using the Amazon SDK for C\$1\$1](getting-started.md). The build process generates an executable for each source file.

1. Open a command prompt to the folder where your build system generated your build executables. Run the executable `run_create_bucket` (your actual executable filename will differ based on your operating system). This creates a bucket in your account (so that you have one to delete). 

1. In the command prompt, run the executable `run_delete_bucket`. This example expects a parameter of the name of the bucket that you want to delete. Provide an incorrect bucket name; intentionally create a typo in this bucket name for now, so that we can explore troubleshooting.

1. Confirm that you get an `Access Denied` error message. *Getting an `Access Denied` error message leads you to question whether you created a user with full permissions for Amazon S3, which you'll verify next.*

**To install the Amazon CLI and find the **username** that is making calls to Amazon**

1. To install the latest Amazon CLI to your development machine, see [Installing the Amazon CLI](https://docs.amazonaws.cn/cli/latest/userguide/cli-chap-install.html) in the *Amazon Command Line Interface User Guide*.

1. To verify the Amazon CLI is working, open a command prompt and run command `aws -\-version`

   ```
   $ aws -\-version
   aws-cli/2.1.29 Python/3.8.8 Windows/10 exe/AMD64 prompt/off
   ```

1. To obtain the username that is actually making the calls to Amazon, run the Amazon CLI command `aws sts get-caller-identity`. In the following example output, that username is *userX*

   ```
   $ aws sts get-caller-identity
   {
       "UserId": "A12BCD34E5FGHI6JKLM",
       "Account": "1234567890987",
       "Arn": "arn:aws:iam::1234567890987:user/userX"
   }
   ```

   There are many ways to specify credentials, but if you followed the approach in [Authenticating with Amazon using Amazon SDK for C\$1\$1](credentials.md) then this username comes from your Amazon shared credentials file. During that procedure you granted your user **AmazonS3FullAccess** permissions.
**Note**  
Generally, most Amazon CLI commands follow the syntax structure of:  

   ```
   $ aws <command> <subcommand> [options and parameters]
   ```
where *command* is the service, and *subcommand* is the method being called on that service. For more details, see [Command structure in the Amazon CLI](https://docs.amazonaws.cn/cli/latest/userguide/cli-usage-commandstructure.html) in the *Amazon Command Line Interface User Guide*.

**To verify whether a user has permission to delete a bucket**

1. Open the [Amazon Web Services Management Console](https://console.amazonaws.cn/) and log in. For more details, see [Getting Started with the Amazon Web Services Management Console](https://docs.amazonaws.cn/awsconsolehelpdocs/latest/gsg/getting-started.html). 

1. In the main navigation bar, for **Search for services...**, enter **IAM** and select the IAM service from the results.

1. From the **Dashboard** sidebar, or under **IAM Resources**, select **Users**.

1. From the table of users available for your account, select the username obtained in the preceding procedure.

1. Choose the **Permissions** tab of the **Summary** page, under the **Policy name** table, select **AmazonS3FullAccess**.

1. Look at the **Policy summary** and the JSON data. Verify that this user has full rights for the Amazon S3 service.

   ```
               "Effect": "Allow",
               "Action": "s3:*",
               "Resource": "*"
   ```

This process of elimination is common in ruling *out* where the problem might be. In this case, you've veriﬁed that the user does have the correct permissions, so the problem must be something else. That is, since you have the correct permissions to access your buckets, the `Access Denied` error may mean that you are trying to access a bucket that isn't yours. When troubleshooting, you'd next review the bucket name that was provided to the program, and notice that a bucket with that name doesn't exist in your account, and thus, you cannot 'access' it. 

**To update the code example so it runs successfully**

1. Back in `delete_bucket.cpp`'s `main()` function, change the Region, using the enum, to the Region of your account. To find your Region of your account, log into the Amazon Web Services Management Console, and locate the Region in the upper right-hand corner. Also in `main()`, change the bucket name to a bucket that **does** exist in your account. There are several ways to find your current bucket names:
   + You can use the `run_list_buckets` executable that also exists in this code example's folder to programatically get the names of your buckets.
   + Alternatively, you can also use the following Amazon CLI command to list your Amazon S3 buckets.

     ```
     $ aws s3 ls
     2022-01-05 14:27:48 amzn-s3-demo-bucket
     ```
   + Alternatively, you can also use the [Amazon Web Services Management Console](https://console.amazonaws.cn/). In the main navigation bar, in **Search for services...**, enter **S3**. The Buckets page lists your account's buckets.

1. Rebuild the code and run the updated executable `run_delete_bucket`.

1. Using either the Amazon Web Services Management Console or the Amazon CLI, verify that the Amazon S3 bucket that you created earlier has been deleted.

# Guided examples for calling Amazon Web Services services using the Amazon SDK for C\$1\$1
<a name="programming-services"></a>

If you are new to Amazon or the Amazon code examples, we recommend you start with [Getting started on code examples](getting-started-code-examples.md).

Source code that shows how to work with Amazon services using the Amazon SDK for C\$1\$1 is available in the [Code examples](cpp_code_examples.md) chapter of this guide or directly in the [Amazon Code Examples Repository](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/cpp/example_code) on GitHub. 

This section selects several Amazon services and guides you through the examples using them. The following guided examples are a subset of what is available on Github.


**Service examples with additional explanation (see [Amazon Code Examples Repository](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/cpp/example_code) for full list)**  

| Service | Summary of what the service provides to your program | 
| --- | --- | 
| [Amazon CloudWatch](examples-cloudwatch.md) | Collects and monitors metrics for Amazon resources you are using | 
| [Amazon DynamoDB](examples-dynamodb.md) | A NoSQL database service | 
| [Amazon Elastic Compute Cloud](examples-ec2.md) (Amazon EC2) | Secure, resizable compute capacity | 
| [Amazon Simple Storage Service](examples-s3.md) (Amazon S3) | Data storage and retrieval (objects into buckets) | 
| [Amazon Simple Queue Service](examples-sqs.md) (Amazon SQS) | Message queuing service to send, store, and receive messages between software components | 

There are also examples that show how to use [Asynchronous methods](async-methods.md).

To propose a new code example to the Amazon documentation team, see [Contributing guidelines](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/CONTRIBUTING.md) on GitHub to create a new request. The team prefers to create code examples that show broad scenarios rather than individual API calls.

**Using the Code Examples on Windows**

If you are building the examples on Windows with SDK version 1.9, see [Troubleshooting Amazon SDK for C\$1\$1 build issues](troubleshooting-cmake.md).

# Amazon CloudWatch examples using the Amazon SDK for C\$1\$1
<a name="examples-cloudwatch"></a>

Amazon CloudWatch (CloudWatch) is a monitoring service for Amazon cloud resources and the applications you run on Amazon. You can use the following examples to program [CloudWatch](http://www.amazonaws.cn/cloudwatch) using the Amazon SDK for C\$1\$1.

Amazon CloudWatch monitors your Amazon resources and the applications you run on Amazon in real time. You can use CloudWatch to collect and track metrics, which are variables you can measure for your resources and applications. CloudWatch alarms send notifications or automatically make changes to the resources you are monitoring based on rules that you define.

For more information about CloudWatch, see the [Amazon CloudWatch User Guide](https://docs.amazonaws.cn/AmazonCloudWatch/latest/DeveloperGuide/).

**Note**  
Only the code that is necessary to demonstrate certain techniques is supplied in this Guide, but the [complete example code is available on GitHub](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/cpp). On GitHub you can download a single source file or you can clone the repository locally to get, build, and run all examples.

**Topics**
+ [

# Getting Metrics from CloudWatch
](examples-cloudwatch-get-metrics.md)
+ [

# Publishing Custom Metric Data
](examples-cloudwatch-publish-custom-metrics.md)
+ [

# Working with CloudWatch Alarms
](examples-cloudwatch-create-alarms.md)
+ [

# Using Alarm Actions in CloudWatch
](examples-cloudwatch-use-alarm-actions.md)
+ [

# Sending Events to CloudWatch
](examples-cloudwatch-send-events.md)

# Getting Metrics from CloudWatch
<a name="examples-cloudwatch-get-metrics"></a>

## Prerequisites
<a name="codeExamplePrereq"></a>

Before you begin, we recommend you read [Getting started using the Amazon SDK for C\$1\$1](getting-started.md). 

Download the example code and build the solution as described in [Getting started on code examples](getting-started-code-examples.md). 

To run the examples, the user profile your code uses to make the requests must have proper permissions in Amazon (for the service and the action). For more information, see [Providing Amazon credentials](credentials.md).

## Listing Metrics
<a name="listing-metrics"></a>

To list CloudWatch metrics, create a [ListMetricsRequest](https://docs.amazonaws.cn/sdk-for-cpp/latest/api/aws-cpp-sdk-monitoring/html/class_aws_1_1_cloud_watch_1_1_model_1_1_list_metrics_request.html) and call the CloudWatchClient’s `ListMetrics` function. You can use the `ListMetricsRequest` to filter the returned metrics by namespace, metric name, or dimensions.

**Note**  
A list of metrics and dimensions that are posted by Amazon services can be found within the [Amazon CloudWatch Metrics and Dimensions Reference](https://docs.amazonaws.cn/AmazonCloudWatch/latest/monitoring/CW_Support_For_AWS.html) in the Amazon CloudWatch User Guide.

 **Includes** 

```
#include <aws/core/Aws.h>
#include <aws/monitoring/CloudWatchClient.h>
#include <aws/monitoring/model/ListMetricsRequest.h>
#include <aws/monitoring/model/ListMetricsResult.h>
#include <iomanip>
#include <iostream>
```

 **Code** 

```
        Aws::CloudWatch::CloudWatchClient cw;
        Aws::CloudWatch::Model::ListMetricsRequest request;

        if (argc > 1)
        {
            request.SetMetricName(argv[1]);
        }

        if (argc > 2)
        {
            request.SetNamespace(argv[2]);
        }

        bool done = false;
        bool header = false;
        while (!done)
        {
            auto outcome = cw.ListMetrics(request);
            if (!outcome.IsSuccess())
            {
                std::cout << "Failed to list CloudWatch metrics:" <<
                    outcome.GetError().GetMessage() << std::endl;
                break;
            }

            if (!header)
            {
                std::cout << std::left << std::setw(48) << "MetricName" <<
                    std::setw(32) << "Namespace" << "DimensionNameValuePairs" <<
                    std::endl;
                header = true;
            }

            const auto &metrics = outcome.GetResult().GetMetrics();
            for (const auto &metric : metrics)
            {
                std::cout << std::left << std::setw(48) <<
                    metric.GetMetricName() << std::setw(32) <<
                    metric.GetNamespace();
                const auto &dimensions = metric.GetDimensions();
                for (auto iter = dimensions.cbegin();
                    iter != dimensions.cend(); ++iter)
                {
                    const auto &dimkv = *iter;
                    std::cout << dimkv.GetName() << " = " << dimkv.GetValue();
                    if (iter + 1 != dimensions.cend())
                    {
                        std::cout << ", ";
                    }
                }
                std::cout << std::endl;
            }

            const auto &next_token = outcome.GetResult().GetNextToken();
            request.SetNextToken(next_token);
            done = next_token.empty();
        }
```

The metrics are returned in a [ListMetricsResult](https://docs.amazonaws.cn/sdk-for-cpp/latest/api/aws-cpp-sdk-monitoring/html/class_aws_1_1_cloud_watch_1_1_model_1_1_list_metrics_result.html) by calling its `GetMetrics` function. The results may be *paged*. To retrieve the next batch of results, call `SetNextToken` on the original request object with the return value of the `ListMetricsResult` object’s `GetNextToken` function, and pass the modified request object back to another call to `ListMetrics`.

See the [complete example](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/cpp/example_code/cloudwatch/list_metrics.cpp).

## More Information
<a name="more-information"></a>
+  [ListMetrics](https://docs.amazonaws.cn/AmazonCloudWatch/latest/APIReference/ListMetrics.html) in the Amazon CloudWatch API Reference.

# Publishing Custom Metric Data
<a name="examples-cloudwatch-publish-custom-metrics"></a>

A number of Amazon services publish [their own metrics](https://docs.amazonaws.cn/AmazonCloudWatch/latest/monitoring/aws-namespaces.html) in namespaces beginning with `AWS/` You can also publish custom metric data using your own namespace (as long as it doesn’t begin with `AWS/`).

## Prerequisites
<a name="codeExamplePrereq"></a>

Before you begin, we recommend you read [Getting started using the Amazon SDK for C\$1\$1](getting-started.md). 

Download the example code and build the solution as described in [Getting started on code examples](getting-started-code-examples.md). 

To run the examples, the user profile your code uses to make the requests must have proper permissions in Amazon (for the service and the action). For more information, see [Providing Amazon credentials](credentials.md).

## Publish Custom Metric Data
<a name="publish-custom-metric-data"></a>

To publish your own metric data, call the CloudWatchClient’s `PutMetricData` function with a [PutMetricDataRequest](https://docs.amazonaws.cn/sdk-for-cpp/latest/api/aws-cpp-sdk-monitoring/html/class_aws_1_1_cloud_watch_1_1_model_1_1_put_metric_data_request.html). The `PutMetricDataRequest` must include the custom namespace to use for the data, and information about the data point itself in a [MetricDatum](https://docs.amazonaws.cn/sdk-for-cpp/latest/api/aws-cpp-sdk-monitoring/html/class_aws_1_1_cloud_watch_1_1_model_1_1_metric_datum.html) object.

**Note**  
You cannot specify a namespace that begins with `AWS/`. Namespaces that begin with `AWS/` are reserved for use by Amazon Web Services products.

 **Includes** 

```
#include <aws/core/Aws.h>
#include <aws/monitoring/CloudWatchClient.h>
#include <aws/monitoring/model/PutMetricDataRequest.h>
#include <iostream>
```

 **Code** 

```
        Aws::CloudWatch::CloudWatchClient cw;

        Aws::CloudWatch::Model::Dimension dimension;
        dimension.SetName("UNIQUE_PAGES");
        dimension.SetValue("URLS");

        Aws::CloudWatch::Model::MetricDatum datum;
        datum.SetMetricName("PAGES_VISITED");
        datum.SetUnit(Aws::CloudWatch::Model::StandardUnit::None);
        datum.SetValue(data_point);
        datum.AddDimensions(dimension);

        Aws::CloudWatch::Model::PutMetricDataRequest request;
        request.SetNamespace("SITE/TRAFFIC");
        request.AddMetricData(datum);

        auto outcome = cw.PutMetricData(request);
        if (!outcome.IsSuccess())
        {
            std::cout << "Failed to put sample metric data:" <<
                outcome.GetError().GetMessage() << std::endl;
        }
        else
        {
            std::cout << "Successfully put sample metric data" << std::endl;
        }
```

See the [complete example](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/cpp/example_code/cloudwatch/put_metric_data.cpp).

## More Information
<a name="more-information"></a>
+  [Using Amazon CloudWatch Metrics](https://docs.amazonaws.cn/AmazonCloudWatch/latest/monitoring/working_with_metrics.html) in the Amazon CloudWatch User Guide.
+  [Amazon Namespaces](https://docs.amazonaws.cn/AmazonCloudWatch/latest/monitoring/aws-namespaces.html) in the Amazon CloudWatch User Guide.
+  [PutMetricData](https://docs.amazonaws.cn/AmazonCloudWatch/latest/APIReference/PutMetricData.html) in the Amazon CloudWatch API Reference.

# Working with CloudWatch Alarms
<a name="examples-cloudwatch-create-alarms"></a>

## Prerequisites
<a name="codeExamplePrereq"></a>

Before you begin, we recommend you read [Getting started using the Amazon SDK for C\$1\$1](getting-started.md). 

Download the example code and build the solution as described in [Getting started on code examples](getting-started-code-examples.md). 

To run the examples, the user profile your code uses to make the requests must have proper permissions in Amazon (for the service and the action). For more information, see [Providing Amazon credentials](credentials.md).

## Create an Alarm
<a name="create-an-alarm"></a>

To create an alarm based on a CloudWatch metric, call the CloudWatchClient’s `PutMetricAlarm` function with a [PutMetricAlarmRequest](https://docs.amazonaws.cn/sdk-for-cpp/latest/api/aws-cpp-sdk-monitoring/html/class_aws_1_1_cloud_watch_1_1_model_1_1_put_metric_alarm_request.html) filled with the alarm conditions.

 **Includes** 

```
#include <aws/core/Aws.h>
#include <aws/monitoring/CloudWatchClient.h>
#include <aws/monitoring/model/PutMetricAlarmRequest.h>
#include <iostream>
```

 **Code** 

```
        Aws::CloudWatch::CloudWatchClient cw;
        Aws::CloudWatch::Model::PutMetricAlarmRequest request;
        request.SetAlarmName(alarm_name);
        request.SetComparisonOperator(
            Aws::CloudWatch::Model::ComparisonOperator::GreaterThanThreshold);
        request.SetEvaluationPeriods(1);
        request.SetMetricName("CPUUtilization");
        request.SetNamespace("AWS/EC2");
        request.SetPeriod(60);
        request.SetStatistic(Aws::CloudWatch::Model::Statistic::Average);
        request.SetThreshold(70.0);
        request.SetActionsEnabled(false);
        request.SetAlarmDescription("Alarm when server CPU exceeds 70%");
        request.SetUnit(Aws::CloudWatch::Model::StandardUnit::Seconds);

        Aws::CloudWatch::Model::Dimension dimension;
        dimension.SetName("InstanceId");
        dimension.SetValue(instanceId);

        request.AddDimensions(dimension);

        auto outcome = cw.PutMetricAlarm(request);
        if (!outcome.IsSuccess())
        {
            std::cout << "Failed to create CloudWatch alarm:" <<
                outcome.GetError().GetMessage() << std::endl;
        }
        else
        {
            std::cout << "Successfully created CloudWatch alarm " << alarm_name
                << std::endl;
        }
```

See the [complete example](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/cpp/example_code/cloudwatch/put_metric_alarm.cpp).

## List Alarms
<a name="list-alarms"></a>

To list the CloudWatch alarms that you have created, call the CloudWatchClient’s `DescribeAlarms` function with a [DescribeAlarmsRequest](https://docs.amazonaws.cn/sdk-for-cpp/latest/api/aws-cpp-sdk-monitoring/html/class_aws_1_1_cloud_watch_1_1_model_1_1_describe_alarms_request.html) that you can use to set options for the result.

 **Includes** 

```
#include <aws/core/Aws.h>
#include <aws/monitoring/CloudWatchClient.h>
#include <aws/monitoring/model/DescribeAlarmsRequest.h>
#include <aws/monitoring/model/DescribeAlarmsResult.h>
#include <iomanip>
#include <iostream>
```

 **Code** 

```
        Aws::CloudWatch::CloudWatchClient cw;
        Aws::CloudWatch::Model::DescribeAlarmsRequest request;
        request.SetMaxRecords(1);

        bool done = false;
        bool header = false;
        while (!done)
        {
            auto outcome = cw.DescribeAlarms(request);
            if (!outcome.IsSuccess())
            {
                std::cout << "Failed to describe CloudWatch alarms:" <<
                    outcome.GetError().GetMessage() << std::endl;
                break;
            }

            if (!header)
            {
                std::cout << std::left <<
                    std::setw(32) << "Name" <<
                    std::setw(64) << "Arn" <<
                    std::setw(64) << "Description" <<
                    std::setw(20) << "LastUpdated" <<
                    std::endl;
                header = true;
            }

            const auto &alarms = outcome.GetResult().GetMetricAlarms();
            for (const auto &alarm : alarms)
            {
                std::cout << std::left <<
                    std::setw(32) << alarm.GetAlarmName() <<
                    std::setw(64) << alarm.GetAlarmArn() <<
                    std::setw(64) << alarm.GetAlarmDescription() <<
                    std::setw(20) <<
                    alarm.GetAlarmConfigurationUpdatedTimestamp().ToGmtString(
                        SIMPLE_DATE_FORMAT_STR) <<
                    std::endl;
            }

            const auto &next_token = outcome.GetResult().GetNextToken();
            request.SetNextToken(next_token);
            done = next_token.empty();
        }
```

The list of alarms can be obtained by calling `getMetricAlarms` on the [DescribeAlarmsResult](https://docs.amazonaws.cn/sdk-for-cpp/latest/api/aws-cpp-sdk-monitoring/html/class_aws_1_1_cloud_watch_1_1_model_1_1_describe_alarms_result.html) that is returned by `DescribeAlarms`.

The results may be *paged*. To retrieve the next batch of results, call `SetNextToken` on the original request object with the return value of the `DescribeAlarmsResult` object’s `GetNextToken` function, and pass the modified request object back to another call to `DescribeAlarms`.

**Note**  
You can also retrieve alarms for a specific metric by using the CloudWatchClient’s `DescribeAlarmsForMetric` function. Its use is similar to `DescribeAlarms`.

See the [complete example](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/cpp/example_code/cloudwatch/describe_alarms.cpp).

## Delete Alarms
<a name="delete-alarms"></a>

To delete CloudWatch alarms, call the CloudWatchClient’s `DeleteAlarms` function with a [DeleteAlarmsRequest](https://docs.amazonaws.cn/sdk-for-cpp/latest/api/aws-cpp-sdk-monitoring/html/class_aws_1_1_cloud_watch_1_1_model_1_1_delete_alarms_request.html) containing one or more names of alarms that you want to delete.

 **Includes** 

```
#include <aws/core/Aws.h>
#include <aws/monitoring/CloudWatchClient.h>
#include <aws/monitoring/model/DeleteAlarmsRequest.h>
#include <iostream>
```

 **Code** 

```
        Aws::CloudWatch::CloudWatchClient cw;
        Aws::CloudWatch::Model::DeleteAlarmsRequest request;
        request.AddAlarmNames(alarm_name);

        auto outcome = cw.DeleteAlarms(request);
        if (!outcome.IsSuccess())
        {
            std::cout << "Failed to delete CloudWatch alarm:" <<
                outcome.GetError().GetMessage() << std::endl;
        }
        else
        {
            std::cout << "Successfully deleted CloudWatch alarm " << alarm_name
                << std::endl;
        }
```

See the [complete example](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/cpp/example_code/cloudwatch/delete_alarm.cpp).

## More Information
<a name="more-information"></a>
+  [Creating Amazon CloudWatch Alarms](https://docs.amazonaws.cn/AmazonCloudWatch/latest/monitoring/AlarmThatSendsEmail.html) in the Amazon CloudWatch User Guide
+  [PutMetricAlarm](https://docs.amazonaws.cn/AmazonCloudWatch/latest/APIReference/PutMetricAlarm.html) in the Amazon CloudWatch API Reference
+  [DescribeAlarms](https://docs.amazonaws.cn/AmazonCloudWatch/latest/APIReference/DescribeAlarms.html) in the Amazon CloudWatch API Reference
+  [DeleteAlarms](https://docs.amazonaws.cn/AmazonCloudWatch/latest/APIReference/DeleteAlarms.html) in the Amazon CloudWatch API Reference

# Using Alarm Actions in CloudWatch
<a name="examples-cloudwatch-use-alarm-actions"></a>

Using CloudWatch alarm actions, you can create alarms that perform actions such as automatically stopping, terminating, rebooting, or recovering Amazon EC2 instances.

Alarm actions can be added to an alarm by using the [PutMetricAlarmRequest](https://docs.amazonaws.cn/sdk-for-cpp/latest/api/aws-cpp-sdk-monitoring/html/class_aws_1_1_cloud_watch_1_1_model_1_1_put_metric_alarm_request.html)’s `SetAlarmActions` function when [creating an alarm](examples-cloudwatch-create-alarms.md).

## Prerequisites
<a name="codeExamplePrereq"></a>

Before you begin, we recommend you read [Getting started using the Amazon SDK for C\$1\$1](getting-started.md). 

Download the example code and build the solution as described in [Getting started on code examples](getting-started-code-examples.md). 

To run the examples, the user profile your code uses to make the requests must have proper permissions in Amazon (for the service and the action). For more information, see [Providing Amazon credentials](credentials.md).

## Enable Alarm Actions
<a name="enable-alarm-actions"></a>

To enable alarm actions for a CloudWatch alarm, call the CloudWatchClient’s `EnableAlarmActions` with a [EnableAlarmActionsRequest](https://docs.amazonaws.cn/sdk-for-cpp/latest/api/aws-cpp-sdk-monitoring/html/class_aws_1_1_cloud_watch_1_1_model_1_1_enable_alarm_actions_request.html) containing one or more names of alarms whose actions you want to enable.

 **Includes** 

```
#include <aws/core/Aws.h>
#include <aws/monitoring/CloudWatchClient.h>
#include <aws/monitoring/model/EnableAlarmActionsRequest.h>
#include <aws/monitoring/model/PutMetricAlarmRequest.h>
#include <iostream>
```

 **Code** 

```
    Aws::CloudWatch::CloudWatchClient cw;
    Aws::CloudWatch::Model::PutMetricAlarmRequest request;
    request.SetAlarmName(alarm_name);
    request.SetComparisonOperator(
        Aws::CloudWatch::Model::ComparisonOperator::GreaterThanThreshold);
    request.SetEvaluationPeriods(1);
    request.SetMetricName("CPUUtilization");
    request.SetNamespace("AWS/EC2");
    request.SetPeriod(60);
    request.SetStatistic(Aws::CloudWatch::Model::Statistic::Average);
    request.SetThreshold(70.0);
    request.SetActionsEnabled(false);
    request.SetAlarmDescription("Alarm when server CPU exceeds 70%");
    request.SetUnit(Aws::CloudWatch::Model::StandardUnit::Seconds);
    request.AddAlarmActions(actionArn);

    Aws::CloudWatch::Model::Dimension dimension;
    dimension.SetName("InstanceId");
    dimension.SetValue(instanceId);
    request.AddDimensions(dimension);

    auto outcome = cw.PutMetricAlarm(request);
    if (!outcome.IsSuccess())
    {
        std::cout << "Failed to create CloudWatch alarm:" <<
            outcome.GetError().GetMessage() << std::endl;
        return;
    }

    Aws::CloudWatch::Model::EnableAlarmActionsRequest enable_request;
    enable_request.AddAlarmNames(alarm_name);

    auto enable_outcome = cw.EnableAlarmActions(enable_request);
    if (!enable_outcome.IsSuccess())
    {
        std::cout << "Failed to enable alarm actions:" <<
            enable_outcome.GetError().GetMessage() << std::endl;
        return;
    }

    std::cout << "Successfully created alarm " << alarm_name <<
        " and enabled actions on it." << std::endl;
```

See the [complete example](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/cpp/example_code/cloudwatch/enable_alarm_actions.cpp).

## Disable Alarm Actions
<a name="disable-alarm-actions"></a>

To disable alarm actions for a CloudWatch alarm, call the CloudWatchClient’s `DisableAlarmActions` with a [DisableAlarmActionsRequest](https://docs.amazonaws.cn/sdk-for-cpp/latest/api/aws-cpp-sdk-monitoring/html/class_aws_1_1_cloud_watch_1_1_model_1_1_disable_alarm_actions_request.html) containing one or more names of alarms whose actions you want to disable.

 **Includes** 

```
#include <aws/core/Aws.h>
#include <aws/monitoring/CloudWatchClient.h>
#include <aws/monitoring/model/DisableAlarmActionsRequest.h>
#include <iostream>
```

 **Code** 

```
        Aws::CloudWatch::CloudWatchClient cw;

        Aws::CloudWatch::Model::DisableAlarmActionsRequest disableAlarmActionsRequest;
        disableAlarmActionsRequest.AddAlarmNames(alarm_name);

        auto disableAlarmActionsOutcome = cw.DisableAlarmActions(disableAlarmActionsRequest);
        if (!disableAlarmActionsOutcome.IsSuccess())
        {
            std::cout << "Failed to disable actions for alarm " << alarm_name <<
                ": " << disableAlarmActionsOutcome.GetError().GetMessage() <<
                std::endl;
        }
        else
        {
            std::cout << "Successfully disabled actions for alarm " <<
                alarm_name << std::endl;
        }
```

See the [complete example](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/cpp/example_code/cloudwatch/disable_alarm_actions.cpp).

## More Information
<a name="more-information"></a>
+  [Create Alarms to Stop, Terminate, Reboot, or Recover an Instance](https://docs.amazonaws.cn/AmazonCloudWatch/latest/monitoring/UsingAlarmActions.html) in the Amazon CloudWatch User Guide
+  [PutMetricAlarm](https://docs.amazonaws.cn/AmazonCloudWatch/latest/APIReference/PutMetricAlarm.html) in the Amazon CloudWatch API Reference
+  [EnableAlarmActions](https://docs.amazonaws.cn/AmazonCloudWatch/latest/APIReference/EnableAlarmActions.html) in the Amazon CloudWatch API Reference
+  [DisableAlarmActions](https://docs.amazonaws.cn/AmazonCloudWatch/latest/APIReference/DisableAlarmActions.html) in the Amazon CloudWatch API Reference

# Sending Events to CloudWatch
<a name="examples-cloudwatch-send-events"></a>

CloudWatch Events delivers a near real-time stream of system events that describe changes in Amazon resources to Amazon EC2 instances, Lambda functions, Kinesis streams, Amazon ECS tasks, Step Functions state machines, Amazon SNS topics, Amazon SQS queues, or built-in targets. You can match events and route them to one or more target functions or streams by using simple rules.

**Note**  
These code snippets assume that you understand the material in [Getting Started Using the Amazon SDK for C\$1\$1](getting-started.md) and have configured default Amazon credentials using the information in [Providing Amazon Credentials](credentials.md).

## Add Events
<a name="add-events"></a>

To add custom CloudWatch events, call the CloudWatchEventsClient’s `PutEvents` function with a [PutEventsRequest](https://docs.amazonaws.cn/sdk-for-cpp/latest/api/aws-cpp-sdk-eventbridge/html/class_aws_1_1_event_bridge_1_1_model_1_1_put_events_request.html) object that contains one or more [PutEventsRequestEntry](https://docs.amazonaws.cn/sdk-for-cpp/latest/api/aws-cpp-sdk-eventbridge/html/class_aws_1_1_event_bridge_1_1_model_1_1_put_events_request_entry.html) objects that provide details about each event. You can specify several parameters for the entry such as the source and type of the event, resources associated with the event, and so on.

**Note**  
You can specify a maximum of 10 events per call to `putEvents`.

 **Includes** 

```
#include <aws/core/Aws.h>
#include <aws/events/EventBridgeClient.h>
#include <aws/events/model/PutEventsRequest.h>
#include <aws/events/model/PutEventsResult.h>
#include <aws/core/utils/Outcome.h>
#include <iostream>
```

 **Code** 

```
        Aws::CloudWatchEvents::EventBridgeClient cwe;

        Aws::CloudWatchEvents::Model::PutEventsRequestEntry event_entry;
        event_entry.SetDetail(MakeDetails(event_key, event_value));
        event_entry.SetDetailType("sampleSubmitted");
        event_entry.AddResources(resource_arn);
        event_entry.SetSource("aws-sdk-cpp-cloudwatch-example");

        Aws::CloudWatchEvents::Model::PutEventsRequest request;
        request.AddEntries(event_entry);

        auto outcome = cwe.PutEvents(request);
        if (!outcome.IsSuccess())
        {
            std::cout << "Failed to post CloudWatch event: " <<
                outcome.GetError().GetMessage() << std::endl;
        }
        else
        {
            std::cout << "Successfully posted CloudWatch event" << std::endl;
        }
```

## Add Rules
<a name="add-rules"></a>

To create or update a rule, call the CloudWatchEventsClient’s `PutRule` function with a [PutRuleRequest](https://docs.amazonaws.cn/sdk-for-cpp/latest/api/aws-cpp-sdk-eventbridge/html/class_aws_1_1_event_bridge_1_1_model_1_1_put_rule_request.html) with the name of the rule and optional parameters such as the [event pattern](https://docs.amazonaws.cn/AmazonCloudWatch/latest/events/CloudWatchEventsandEventPatterns.html), IAM role to associate with the rule, and a [scheduling expression](https://docs.amazonaws.cn/AmazonCloudWatch/latest/events/ScheduledEvents.html) that describes how often the rule is run.

 **Includes** 

```
#include <aws/core/Aws.h>
#include <aws/events/EventBridgeClient.h>
#include <aws/events/model/PutRuleRequest.h>
#include <aws/events/model/PutRuleResult.h>
#include <aws/core/utils/Outcome.h>
#include <iostream>
```

 **Code** 

```
        Aws::CloudWatchEvents::EventBridgeClient cwe;
        Aws::CloudWatchEvents::Model::PutRuleRequest request;
        request.SetName(rule_name);
        request.SetRoleArn(role_arn);
        request.SetScheduleExpression("rate(5 minutes)");
        request.SetState(Aws::CloudWatchEvents::Model::RuleState::ENABLED);

        auto outcome = cwe.PutRule(request);
        if (!outcome.IsSuccess())
        {
            std::cout << "Failed to create CloudWatch events rule " <<
                rule_name << ": " << outcome.GetError().GetMessage() <<
                std::endl;
        }
        else
        {
            std::cout << "Successfully created CloudWatch events rule " <<
                rule_name << " with resulting Arn " <<
                outcome.GetResult().GetRuleArn() << std::endl;
        }
```

## Add Targets
<a name="add-targets"></a>

Targets are the resources that are invoked when a rule is triggered. Example targets include Amazon EC2 instances, Lambda functions, Kinesis streams, Amazon ECS tasks, Step Functions state machines, and built-in targets.

To add a target to a rule, call the CloudWatchEventsClient’s `PutTargets` function with a [PutTargetsRequest](https://docs.amazonaws.cn/sdk-for-cpp/latest/api/aws-cpp-sdk-eventbridge/html/class_aws_1_1_event_bridge_1_1_model_1_1_put_targets_request.html) containing the rule to update and a list of targets to add to the rule.

 **Includes** 

```
#include <aws/core/Aws.h>
#include <aws/events/EventBridgeClient.h>
#include <aws/events/model/PutTargetsRequest.h>
#include <aws/events/model/PutTargetsResult.h>
#include <aws/core/utils/Outcome.h>
#include <iostream>
```

 **Code** 

```
        Aws::CloudWatchEvents::EventBridgeClient cwe;

        Aws::CloudWatchEvents::Model::Target target;
        target.SetArn(lambda_arn);
        target.SetId(target_id);

        Aws::CloudWatchEvents::Model::PutTargetsRequest request;
        request.SetRule(rule_name);
        request.AddTargets(target);

        auto putTargetsOutcome = cwe.PutTargets(request);
        if (!putTargetsOutcome.IsSuccess())
        {
            std::cout << "Failed to create CloudWatch events target for rule "
                << rule_name << ": " <<
                putTargetsOutcome.GetError().GetMessage() << std::endl;
        }
        else
        {
            std::cout <<
                "Successfully created CloudWatch events target for rule "
                << rule_name << std::endl;
        }
```

See the [complete example](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/cpp/example_code/eventbridge/put_targets.cpp).

## More Information
<a name="more-information"></a>
+  [Adding Events with PutEvents](https://docs.amazonaws.cn/AmazonCloudWatch/latest/events/AddEventsPutEvents.html) in the Amazon CloudWatch Events User Guide
+  [Schedule Expressions for Rules](https://docs.amazonaws.cn/AmazonCloudWatch/latest/events/ScheduledEvents.html) in the Amazon CloudWatch Events User Guide
+  [Event Types for CloudWatch Events](https://docs.amazonaws.cn/AmazonCloudWatch/latest/events/EventTypes.html) in the Amazon CloudWatch Events User Guide
+  [Events and Event Patterns](https://docs.amazonaws.cn/AmazonCloudWatch/latest/events/CloudWatchEventsandEventPatterns.html) in the Amazon CloudWatch Events User Guide
+  [PutEvents](https://docs.amazonaws.cn/AmazonCloudWatchEvents/latest/APIReference/PutEvents.html) in the Amazon CloudWatch Events API Reference
+  [PutTargets](https://docs.amazonaws.cn/AmazonCloudWatchEvents/latest/APIReference/PutTargets.html) in the Amazon CloudWatch Events API Reference
+  [PutRule](https://docs.amazonaws.cn/AmazonCloudWatchEvents/latest/APIReference/PutRule.html) in the Amazon CloudWatch Events API Reference

# Amazon DynamoDB examples using the Amazon SDK for C\$1\$1
<a name="examples-dynamodb"></a>

Amazon DynamoDB is a fully managed NoSQL database service that provides fast and predictable performance with seamless scalability. The following examples show how you can program [Amazon DynamoDB](http://www.amazonaws.cn/dynamodb) using the Amazon SDK for C\$1\$1.

**Note**  
Only the code that is necessary to demonstrate certain techniques is supplied in this Guide, but the [complete example code is available on GitHub](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/cpp). On GitHub you can download a single source file or you can clone the repository locally to get, build, and run all examples.

**Topics**
+ [

# Working with Tables in DynamoDB
](examples-dynamodb-tables.md)
+ [

# Working with Items in DynamoDB
](examples-dynamodb-items.md)

# Working with Tables in DynamoDB
<a name="examples-dynamodb-tables"></a>

Tables are the containers for all items in a DynamoDB database. Before you can add or remove data from DynamoDB, you must create a table.

For each table, you must define:
+ A table *name* that is unique for your Amazon Web Services account and Amazon Web Services Region.
+ A *primary key* for which every value must be unique. No two items in your table can have the same primary key value.

  A primary key can be *simple*, consisting of a single partition (HASH) key, or *composite*, consisting of a partition and a sort (RANGE) key.

  Each key value has an associated *data type*, enumerated by the [ScalarAttributeType](https://docs.amazonaws.cn/sdk-for-cpp/latest/api/aws-cpp-sdk-dynamodb/html/namespace_aws_1_1_dynamo_d_b_1_1_model.html#a4b39ae66214e022d3737079d071e4bcb.html) class. The key value can be binary (B), numeric (N), or a string (S). For more information, see [Naming Rules and Data Types](https://docs.amazonaws.cn/amazondynamodb/latest/developerguide/HowItWorks.NamingRulesDataTypes.html) in the Amazon DynamoDB Developer Guide.
+  *Provisioned throughput* values that define the number of reserved read/write capacity units for the table.
**Note**  
 [Amazon DynamoDB pricing](http://www.amazonaws.cn/dynamodb/pricing/) is based on the provisioned throughput values that you set on your tables, so reserve only as much capacity as you think you’ll need for your table.  
Provisioned throughput for a table can be modified at any time, so you can adjust capacity if your needs change.

## Create a Table
<a name="dynamodb-create-table"></a>

Use the [DynamoDB client](https://docs.amazonaws.cn/sdk-for-cpp/latest/api/aws-cpp-sdk-dynamodb/html/class_aws_1_1_dynamo_d_b_1_1_dynamo_d_b_client.html) `CreateTable` method to create a new DynamoDB table. You need to construct table attributes and a table schema, both of which are used to identify the primary key of your table. You must also supply initial provisioned throughput values and a table name. `CreateTable` is an asynchronous operation. `GetTableStatus` will return CREATING until the table is ACTIVE and ready for use.

### Create a Table with a Simple Primary Key
<a name="dynamodb-create-table-simple"></a>

This code creates a table with a simple primary key (“Name”).

 **Includes** 

```
#include <aws/core/Aws.h>
#include <aws/dynamodb/DynamoDBClient.h>
#include <aws/dynamodb/model/AttributeDefinition.h>
#include <aws/dynamodb/model/CreateTableRequest.h>
#include <aws/dynamodb/model/KeySchemaElement.h>
#include <aws/dynamodb/model/ProvisionedThroughput.h>
#include <aws/dynamodb/model/ScalarAttributeType.h>
#include <iostream>
```

 **Code** 

```
//! Create an Amazon DynamoDB table.
/*!
  \sa createTable()
  \param tableName: Name for the DynamoDB table.
  \param primaryKey: Primary key for the DynamoDB table.
  \param clientConfiguration: AWS client configuration.
  \return bool: Function succeeded.
 */
bool AwsDoc::DynamoDB::createTable(const Aws::String &tableName,
                                   const Aws::String &primaryKey,
                                   const Aws::Client::ClientConfiguration &clientConfiguration) {
    Aws::DynamoDB::DynamoDBClient dynamoClient(clientConfiguration);

    std::cout << "Creating table " << tableName <<
              " with a simple primary key: \"" << primaryKey << "\"." << std::endl;

    Aws::DynamoDB::Model::CreateTableRequest request;

    Aws::DynamoDB::Model::AttributeDefinition hashKey;
    hashKey.SetAttributeName(primaryKey);
    hashKey.SetAttributeType(Aws::DynamoDB::Model::ScalarAttributeType::S);
    request.AddAttributeDefinitions(hashKey);

    Aws::DynamoDB::Model::KeySchemaElement keySchemaElement;
    keySchemaElement.WithAttributeName(primaryKey).WithKeyType(
            Aws::DynamoDB::Model::KeyType::HASH);
    request.AddKeySchema(keySchemaElement);

    Aws::DynamoDB::Model::ProvisionedThroughput throughput;
    throughput.WithReadCapacityUnits(5).WithWriteCapacityUnits(5);
    request.SetProvisionedThroughput(throughput);
    request.SetTableName(tableName);

    const Aws::DynamoDB::Model::CreateTableOutcome &outcome = dynamoClient.CreateTable(
            request);
    if (outcome.IsSuccess()) {
        std::cout << "Table \""
                  << outcome.GetResult().GetTableDescription().GetTableName() <<
                  " created!" << std::endl;
    }
    else {
        std::cerr << "Failed to create table: " << outcome.GetError().GetMessage()
                  << std::endl;
        return false;
    }

    return waitTableActive(tableName, dynamoClient);
}
```

See the [complete example](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/cpp/example_code/dynamodb/create_table.cpp).

### Create a Table with a Composite Primary Key
<a name="dynamodb-create-table-composite"></a>

Add another [AttributeDefinition](https://docs.amazonaws.cn/sdk-for-cpp/latest/api/aws-cpp-sdk-dynamodb/html/class_aws_1_1_dynamo_d_b_1_1_model_1_1_attribute_definition.html) and [KeySchemaElement](https://docs.amazonaws.cn/sdk-for-cpp/latest/api/aws-cpp-sdk-dynamodb/html/class_aws_1_1_dynamo_d_b_1_1_model_1_1_key_schema_element.html) to [CreateTableRequest](https://docs.amazonaws.cn/sdk-for-cpp/latest/api/aws-cpp-sdk-dynamodb/html/class_aws_1_1_dynamo_d_b_1_1_model_1_1_create_table_request.html).

 **Includes** 

```
#include <aws/core/Aws.h>
#include <aws/dynamodb/DynamoDBClient.h>
#include <aws/dynamodb/model/AttributeDefinition.h>
#include <aws/dynamodb/model/CreateTableRequest.h>
#include <aws/dynamodb/model/KeySchemaElement.h>
#include <aws/dynamodb/model/ProvisionedThroughput.h>
#include <aws/dynamodb/model/ScalarAttributeType.h>
#include <iostream>
```

 **Code** 

```
//! Create an Amazon DynamoDB table with a composite key.
/*!
  \sa createTableWithCompositeKey()
  \param tableName: Name for the DynamoDB table.
  \param partitionKey: Name for the partition (hash) key.
  \param sortKey: Name for the sort (range) key.
  \param clientConfiguration: AWS client configuration.
  \return bool: Function succeeded.
 */
bool AwsDoc::DynamoDB::createTableWithCompositeKey(const Aws::String &tableName,
                                                   const Aws::String &partitionKey,
                                                   const Aws::String &sortKey,
                                                   const Aws::Client::ClientConfiguration &clientConfiguration) {
    Aws::DynamoDB::DynamoDBClient dynamoClient(clientConfiguration);

    std::cout << "Creating table " << tableName <<
              " with a composite primary key:\n" \
            "* " << partitionKey << " - partition key\n" \
            "* " << sortKey << " - sort key\n";

    Aws::DynamoDB::Model::CreateTableRequest request;

    Aws::DynamoDB::Model::AttributeDefinition hashKey1, hashKey2;
    hashKey1.WithAttributeName(partitionKey).WithAttributeType(
            Aws::DynamoDB::Model::ScalarAttributeType::S);
    request.AddAttributeDefinitions(hashKey1);
    hashKey2.WithAttributeName(sortKey).WithAttributeType(
            Aws::DynamoDB::Model::ScalarAttributeType::S);
    request.AddAttributeDefinitions(hashKey2);

    Aws::DynamoDB::Model::KeySchemaElement keySchemaElement1, keySchemaElement2;
    keySchemaElement1.WithAttributeName(partitionKey).WithKeyType(
            Aws::DynamoDB::Model::KeyType::HASH);
    request.AddKeySchema(keySchemaElement1);
    keySchemaElement2.WithAttributeName(sortKey).WithKeyType(
            Aws::DynamoDB::Model::KeyType::RANGE);
    request.AddKeySchema(keySchemaElement2);

    Aws::DynamoDB::Model::ProvisionedThroughput throughput;
    throughput.WithReadCapacityUnits(5).WithWriteCapacityUnits(5);
    request.SetProvisionedThroughput(throughput);

    request.SetTableName(tableName);

    const Aws::DynamoDB::Model::CreateTableOutcome &outcome = dynamoClient.CreateTable(
            request);
    if (outcome.IsSuccess()) {
        std::cout << "Table \""
                  << outcome.GetResult().GetTableDescription().GetTableName() <<
                  "\" was created!" << std::endl;
    }
    else {
        std::cerr << "Failed to create table:" << outcome.GetError().GetMessage()
                  << std::endl;
        return false;
    }

    return waitTableActive(tableName, dynamoClient);
}
```

See the [complete example](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/cpp/example_code/dynamodb/create_table_composite_key.cpp) on GitHub.

## List Tables
<a name="dynamodb-list-tables"></a>

You can list the tables in a particular region by calling the [DynamoDB client](https://docs.amazonaws.cn/sdk-for-cpp/latest/api/aws-cpp-sdk-dynamodb/html/class_aws_1_1_dynamo_d_b_1_1_dynamo_d_b_client.html) `ListTables` method.

 **Includes** 

```
#include <aws/core/Aws.h>
#include <aws/core/utils/Outcome.h>
#include <aws/dynamodb/DynamoDBClient.h>
#include <aws/dynamodb/model/ListTablesRequest.h>
#include <aws/dynamodb/model/ListTablesResult.h>
#include <iostream>
```

 **Code** 

```
//! List the Amazon DynamoDB tables for the current AWS account.
/*!
  \sa listTables()
  \param clientConfiguration: AWS client configuration.
  \return bool: Function succeeded.
 */

bool AwsDoc::DynamoDB::listTables(
        const Aws::Client::ClientConfiguration &clientConfiguration) {
    Aws::DynamoDB::DynamoDBClient dynamoClient(clientConfiguration);

    Aws::DynamoDB::Model::ListTablesRequest listTablesRequest;
    listTablesRequest.SetLimit(50);
    do {
        const Aws::DynamoDB::Model::ListTablesOutcome &outcome = dynamoClient.ListTables(
                listTablesRequest);
        if (!outcome.IsSuccess()) {
            std::cout << "Error: " << outcome.GetError().GetMessage() << std::endl;
            return false;
        }

        for (const auto &tableName: outcome.GetResult().GetTableNames())
            std::cout << tableName << std::endl;
        listTablesRequest.SetExclusiveStartTableName(
                outcome.GetResult().GetLastEvaluatedTableName());

    } while (!listTablesRequest.GetExclusiveStartTableName().empty());

    return true;
}
```

By default, up to 100 tables are returned per call. Use `GetExclusiveStartTableName` on the returned [ListTablesOutcome](https://docs.amazonaws.cn/sdk-for-cpp/latest/api/aws-cpp-sdk-dynamodb/html/class_aws_1_1_dynamo_d_b_1_1_dynamo_d_b_client.html) object to get the last table that was evaluated. You can use this value to start the listing after the last returned value of the previous listing.

See the [complete example](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/cpp/example_code/dynamodb/list_tables.cpp).

## Retrieve Information about a Table
<a name="dynamodb-describe-table"></a>

You can find out more about a table by calling the [DynamoDB client](https://docs.amazonaws.cn/sdk-for-cpp/latest/api/aws-cpp-sdk-dynamodb/html/class_aws_1_1_dynamo_d_b_1_1_dynamo_d_b_client.html) `DescribeTable` method.

 **Includes** 

```
#include <aws/core/Aws.h>
#include <aws/dynamodb/DynamoDBClient.h>
#include <aws/dynamodb/model/DescribeTableRequest.h>
#include <iostream>
```

 **Code** 

```
//! Describe an Amazon DynamoDB table.
/*!
  \sa describeTable()
  \param tableName: The DynamoDB table name.
  \param clientConfiguration: AWS client configuration.
  \return bool: Function succeeded.
*/
bool AwsDoc::DynamoDB::describeTable(const Aws::String &tableName,
                                     const Aws::Client::ClientConfiguration &clientConfiguration) {
    Aws::DynamoDB::DynamoDBClient dynamoClient(clientConfiguration);

    Aws::DynamoDB::Model::DescribeTableRequest request;
    request.SetTableName(tableName);

    const Aws::DynamoDB::Model::DescribeTableOutcome &outcome = dynamoClient.DescribeTable(
            request);

    if (outcome.IsSuccess()) {
        const Aws::DynamoDB::Model::TableDescription &td = outcome.GetResult().GetTable();
        std::cout << "Table name  : " << td.GetTableName() << std::endl;
        std::cout << "Table ARN   : " << td.GetTableArn() << std::endl;
        std::cout << "Status      : "
                  << Aws::DynamoDB::Model::TableStatusMapper::GetNameForTableStatus(
                          td.GetTableStatus()) << std::endl;
        std::cout << "Item count  : " << td.GetItemCount() << std::endl;
        std::cout << "Size (bytes): " << td.GetTableSizeBytes() << std::endl;

        const Aws::DynamoDB::Model::ProvisionedThroughputDescription &ptd = td.GetProvisionedThroughput();
        std::cout << "Throughput" << std::endl;
        std::cout << "  Read Capacity : " << ptd.GetReadCapacityUnits() << std::endl;
        std::cout << "  Write Capacity: " << ptd.GetWriteCapacityUnits() << std::endl;

        const Aws::Vector<Aws::DynamoDB::Model::AttributeDefinition> &ad = td.GetAttributeDefinitions();
        std::cout << "Attributes" << std::endl;
        for (const auto &a: ad)
            std::cout << "  " << a.GetAttributeName() << " (" <<
                      Aws::DynamoDB::Model::ScalarAttributeTypeMapper::GetNameForScalarAttributeType(
                              a.GetAttributeType()) <<
                      ")" << std::endl;
    }
    else {
        std::cerr << "Failed to describe table: " << outcome.GetError().GetMessage();
    }

    return outcome.IsSuccess();
}
```

See the [complete example](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/cpp/example_code/dynamodb/describe_table.cpp) on GitHub.

## Modify a Table
<a name="dynamodb-update-table"></a>

You can modify your table’s provisioned throughput values at any time by calling the [DynamoDB client](https://docs.amazonaws.cn/sdk-for-cpp/latest/api/aws-cpp-sdk-dynamodb/html/class_aws_1_1_dynamo_d_b_1_1_dynamo_d_b_client.html) `UpdateTable` method.

 **Includes** 

```
#include <aws/core/Aws.h>
#include <aws/core/utils/Outcome.h>
#include <aws/dynamodb/DynamoDBClient.h>
#include <aws/dynamodb/model/ProvisionedThroughput.h>
#include <aws/dynamodb/model/UpdateTableRequest.h>
#include <iostream>
```

 **Code** 

```
//! Update a DynamoDB table.
/*!
  \sa updateTable()
  \param tableName: Name for the DynamoDB table.
  \param readCapacity: Provisioned read capacity.
  \param writeCapacity: Provisioned write capacity.
  \param clientConfiguration: AWS client configuration.
  \return bool: Function succeeded.
 */
bool AwsDoc::DynamoDB::updateTable(const Aws::String &tableName,
                                   long long readCapacity, long long writeCapacity,
                                   const Aws::Client::ClientConfiguration &clientConfiguration) {
    Aws::DynamoDB::DynamoDBClient dynamoClient(clientConfiguration);

    std::cout << "Updating " << tableName << " with new provisioned throughput values"
              << std::endl;
    std::cout << "Read capacity : " << readCapacity << std::endl;
    std::cout << "Write capacity: " << writeCapacity << std::endl;

    Aws::DynamoDB::Model::UpdateTableRequest request;
    Aws::DynamoDB::Model::ProvisionedThroughput provisionedThroughput;
    provisionedThroughput.WithReadCapacityUnits(readCapacity).WithWriteCapacityUnits(
            writeCapacity);
    request.WithProvisionedThroughput(provisionedThroughput).WithTableName(tableName);

    const Aws::DynamoDB::Model::UpdateTableOutcome &outcome = dynamoClient.UpdateTable(
            request);
    if (outcome.IsSuccess()) {
        std::cout << "Successfully updated the table." << std::endl;
    } else {
        const Aws::DynamoDB::DynamoDBError &error = outcome.GetError();
        if (error.GetErrorType() == Aws::DynamoDB::DynamoDBErrors::VALIDATION &&
            error.GetMessage().find("The provisioned throughput for the table will not change") != std::string::npos) {
            std::cout << "The provisioned throughput for the table will not change." << std::endl;
        } else {
            std::cerr << outcome.GetError().GetMessage() << std::endl;
            return false;
        }
    }

    return waitTableActive(tableName, dynamoClient);
}
```

See the [complete example](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/cpp/example_code/dynamodb/update_table.cpp).

## Delete a Table
<a name="dynamodb-delete-table"></a>

Call the [DynamoDB client](https://docs.amazonaws.cn/sdk-for-cpp/latest/api/aws-cpp-sdk-dynamodb/html/class_aws_1_1_dynamo_d_b_1_1_dynamo_d_b_client.html) `DeleteTable` method and pass it the table’s name.

 **Includes** 

```
#include <aws/core/Aws.h>
#include <aws/dynamodb/DynamoDBClient.h>
#include <aws/dynamodb/model/DeleteTableRequest.h>
#include <iostream>
```

 **Code** 

```
//! Delete an Amazon DynamoDB table.
/*!
  \sa deleteTable()
  \param tableName: The DynamoDB table name.
  \param clientConfiguration: AWS client configuration.
  \return bool: Function succeeded.
*/
bool AwsDoc::DynamoDB::deleteTable(const Aws::String &tableName,
                                   const Aws::Client::ClientConfiguration &clientConfiguration) {
    Aws::DynamoDB::DynamoDBClient dynamoClient(clientConfiguration);

    Aws::DynamoDB::Model::DeleteTableRequest request;
    request.SetTableName(tableName);

    const Aws::DynamoDB::Model::DeleteTableOutcome &result = dynamoClient.DeleteTable(
            request);
    if (result.IsSuccess()) {
        std::cout << "Your table \""
                  << result.GetResult().GetTableDescription().GetTableName()
                  << " was deleted.\n";
    }
    else {
        std::cerr << "Failed to delete table: " << result.GetError().GetMessage()
                  << std::endl;
    }

    return result.IsSuccess();
}
```

See the [complete example](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/cpp/example_code/dynamodb/delete_table.cpp) on GitHub.

## More Info
<a name="more-info"></a>
+  [Guidelines for Working with Tables](https://docs.amazonaws.cn/amazondynamodb/latest/developerguide/GuidelinesForTables.html) in the Amazon DynamoDB Developer Guide
+  [Working with Tables in DynamoDB](https://docs.amazonaws.cn/amazondynamodb/latest/developerguide/WorkingWithTables.html) in the Amazon DynamoDB Developer Guide

# Working with Items in DynamoDB
<a name="examples-dynamodb-items"></a>

In DynamoDB, an item is a collection of *attributes*, each of which has a *name* and a *value*. An attribute value can be a scalar, set, or document type. For more information, see [Naming Rules and Data Types](https://docs.amazonaws.cn/amazondynamodb/latest/developerguide/HowItWorks.NamingRulesDataTypes.html) in the Amazon DynamoDB Developer Guide.

## Retrieve an Item from a Table
<a name="dynamodb-get-item"></a>

Call the [DynamoDB client](https://docs.amazonaws.cn/sdk-for-cpp/latest/api/aws-cpp-sdk-dynamodb/html/class_aws_1_1_dynamo_d_b_1_1_dynamo_d_b_client.html) `GetItem` method. Pass it a [GetItemRequest](https://docs.amazonaws.cn/sdk-for-cpp/latest/api/aws-cpp-sdk-dynamodb/html/class_aws_1_1_dynamo_d_b_1_1_model_1_1_get_item_request.html) object with the table name and primary key value of the item you want. It returns a [GetItemResult](https://docs.amazonaws.cn/sdk-for-cpp/latest/api/aws-cpp-sdk-dynamodb/html/class_aws_1_1_dynamo_d_b_1_1_model_1_1_get_item_result.html) object.

You can use the returned `GetItemResult` object’s `GetItem()` method to retrieve an `Aws::Map` of key `Aws::String` and value [AttributeValue](https://docs.amazonaws.cn/sdk-for-cpp/latest/api/aws-cpp-sdk-dynamodb/html/class_aws_1_1_dynamo_d_b_1_1_model_1_1_attribute_value.html) pairs associated with the item.

 **Includes** 

```
#include <aws/core/Aws.h>
#include <aws/dynamodb/DynamoDBClient.h>
#include <aws/dynamodb/model/AttributeDefinition.h>
#include <aws/dynamodb/model/GetItemRequest.h>
#include <iostream>
```

 **Code** 

```
//! Get an item from an Amazon DynamoDB table.
/*!
  \sa getItem()
  \param tableName: The table name.
  \param partitionKey: The partition key.
  \param partitionValue: The value for the partition key.
  \param clientConfiguration: AWS client configuration.
  \return bool: Function succeeded.
 */

bool AwsDoc::DynamoDB::getItem(const Aws::String &tableName,
                               const Aws::String &partitionKey,
                               const Aws::String &partitionValue,
                               const Aws::Client::ClientConfiguration &clientConfiguration) {
    Aws::DynamoDB::DynamoDBClient dynamoClient(clientConfiguration);
    Aws::DynamoDB::Model::GetItemRequest request;

    // Set up the request.
    request.SetTableName(tableName);
    request.AddKey(partitionKey,
                   Aws::DynamoDB::Model::AttributeValue().SetS(partitionValue));

    // Retrieve the item's fields and values.
    const Aws::DynamoDB::Model::GetItemOutcome &outcome = dynamoClient.GetItem(request);
    if (outcome.IsSuccess()) {
        // Reference the retrieved fields/values.
        const Aws::Map<Aws::String, Aws::DynamoDB::Model::AttributeValue> &item = outcome.GetResult().GetItem();
        if (!item.empty()) {
            // Output each retrieved field and its value.
            for (const auto &i: item)
                std::cout << "Values: " << i.first << ": " << i.second.GetS()
                          << std::endl;
        }
        else {
            std::cout << "No item found with the key " << partitionKey << std::endl;
        }
    }
    else {
        std::cerr << "Failed to get item: " << outcome.GetError().GetMessage();
    }

    return outcome.IsSuccess();
}
```

See the [complete example](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/cpp/example_code/dynamodb/get_item.cpp) on GitHub.

## Add an Item to a Table
<a name="dynamodb-add-item"></a>

Create key `Aws::String` and value [AttributeValue](https://docs.amazonaws.cn/sdk-for-cpp/latest/api/aws-cpp-sdk-dynamodb/html/class_aws_1_1_dynamo_d_b_1_1_model_1_1_attribute_value.html) pairs that represent each item. These must include values for the table’s primary key fields. If the item identified by the primary key already exists, its fields are *updated* by the request. Add them to the [PutItemRequest](https://docs.amazonaws.cn/sdk-for-cpp/latest/api/aws-cpp-sdk-dynamodb/html/class_aws_1_1_dynamo_d_b_1_1_model_1_1_put_item_request.html) using the `AddItem` method.

 **Includes** 

```
#include <aws/core/Aws.h>
#include <aws/dynamodb/DynamoDBClient.h>
#include <aws/dynamodb/model/AttributeDefinition.h>
#include <aws/dynamodb/model/PutItemRequest.h>
#include <aws/dynamodb/model/PutItemResult.h>
#include <iostream>
```

 **Code** 

```
//! Put an item in an Amazon DynamoDB table.
/*!
  \sa putItem()
  \param tableName: The table name.
  \param artistKey: The artist key. This is the partition key for the table.
  \param artistValue: The artist value.
  \param albumTitleKey: The album title key.
  \param albumTitleValue: The album title value.
  \param awardsKey: The awards key.
  \param awardsValue: The awards value.
  \param songTitleKey: The song title key.
  \param songTitleValue: The song title value.
  \param clientConfiguration: AWS client configuration.
  \return bool: Function succeeded.
 */
bool AwsDoc::DynamoDB::putItem(const Aws::String &tableName,
                               const Aws::String &artistKey,
                               const Aws::String &artistValue,
                               const Aws::String &albumTitleKey,
                               const Aws::String &albumTitleValue,
                               const Aws::String &awardsKey,
                               const Aws::String &awardsValue,
                               const Aws::String &songTitleKey,
                               const Aws::String &songTitleValue,
                               const Aws::Client::ClientConfiguration &clientConfiguration) {
    Aws::DynamoDB::DynamoDBClient dynamoClient(clientConfiguration);

    Aws::DynamoDB::Model::PutItemRequest putItemRequest;
    putItemRequest.SetTableName(tableName);

    putItemRequest.AddItem(artistKey, Aws::DynamoDB::Model::AttributeValue().SetS(
            artistValue)); // This is the hash key.
    putItemRequest.AddItem(albumTitleKey, Aws::DynamoDB::Model::AttributeValue().SetS(
            albumTitleValue));
    putItemRequest.AddItem(awardsKey,
                           Aws::DynamoDB::Model::AttributeValue().SetS(awardsValue));
    putItemRequest.AddItem(songTitleKey,
                           Aws::DynamoDB::Model::AttributeValue().SetS(songTitleValue));

    const Aws::DynamoDB::Model::PutItemOutcome outcome = dynamoClient.PutItem(
            putItemRequest);
    if (outcome.IsSuccess()) {
        std::cout << "Successfully added Item!" << std::endl;
    }
    else {
        std::cerr << outcome.GetError().GetMessage() << std::endl;
        return false;
    }

    return waitTableActive(tableName, dynamoClient);
}
```

See the [complete example](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/cpp/example_code/dynamodb/put_item.cpp) on GitHub.

## Update an Existing Item in a Table
<a name="dynamodb-update-item"></a>

You can update an attribute for an item that already exists in a table by using the DynamoDBClient’s `UpdateItem` method, providing a table name, primary key value, and fields to update and their corresponding value.

 **Imports** 

```
#include <aws/core/Aws.h>
#include <aws/dynamodb/DynamoDBClient.h>
#include <aws/dynamodb/model/UpdateItemRequest.h>
#include <aws/dynamodb/model/UpdateItemResult.h>
#include <iostream>
```

 **Code** 

```
//! Update an Amazon DynamoDB table item.
/*!
  \sa updateItem()
  \param tableName: The table name.
  \param partitionKey: The partition key.
  \param partitionValue: The value for the partition key.
  \param attributeKey: The key for the attribute to be updated.
  \param attributeValue: The value for the attribute to be updated.
  \param clientConfiguration: AWS client configuration.
  \return bool: Function succeeded.
  */

/*
 *  The example code only sets/updates an attribute value. It processes
 *  the attribute value as a string, even if the value could be interpreted
 *  as a number. Also, the example code does not remove an existing attribute
 *  from the key value.
 */

bool AwsDoc::DynamoDB::updateItem(const Aws::String &tableName,
                                  const Aws::String &partitionKey,
                                  const Aws::String &partitionValue,
                                  const Aws::String &attributeKey,
                                  const Aws::String &attributeValue,
                                  const Aws::Client::ClientConfiguration &clientConfiguration) {
    Aws::DynamoDB::DynamoDBClient dynamoClient(clientConfiguration);

    // *** Define UpdateItem request arguments.
    // Define TableName argument.
    Aws::DynamoDB::Model::UpdateItemRequest request;
    request.SetTableName(tableName);

    // Define KeyName argument.
    Aws::DynamoDB::Model::AttributeValue attribValue;
    attribValue.SetS(partitionValue);
    request.AddKey(partitionKey, attribValue);

    // Construct the SET update expression argument.
    Aws::String update_expression("SET #a = :valueA");
    request.SetUpdateExpression(update_expression);

    // Construct attribute name argument.
    Aws::Map<Aws::String, Aws::String> expressionAttributeNames;
    expressionAttributeNames["#a"] = attributeKey;
    request.SetExpressionAttributeNames(expressionAttributeNames);

    // Construct attribute value argument.
    Aws::DynamoDB::Model::AttributeValue attributeUpdatedValue;
    attributeUpdatedValue.SetS(attributeValue);
    Aws::Map<Aws::String, Aws::DynamoDB::Model::AttributeValue> expressionAttributeValues;
    expressionAttributeValues[":valueA"] = attributeUpdatedValue;
    request.SetExpressionAttributeValues(expressionAttributeValues);

    // Update the item.
    const Aws::DynamoDB::Model::UpdateItemOutcome &outcome = dynamoClient.UpdateItem(
            request);
    if (outcome.IsSuccess()) {
        std::cout << "Item was updated" << std::endl;
    } else {
        std::cerr << outcome.GetError().GetMessage() << std::endl;
        return false;
    }

    return waitTableActive(tableName, dynamoClient);
}
```

See the [complete example](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/cpp/example_code/dynamodb/update_item.cpp).

## More Info
<a name="more-info"></a>
+  [Guidelines for Working with Items](https://docs.amazonaws.cn/amazondynamodb/latest/developerguide/GuidelinesForItems.html) in the Amazon DynamoDB Developer Guide
+  [Working with Items in DynamoDB](https://docs.amazonaws.cn/amazondynamodb/latest/developerguide/WorkingWithItems.html) in the Amazon DynamoDB Developer Guide

# Amazon EC2 examples using the Amazon SDK for C\$1\$1
<a name="examples-ec2"></a>

Amazon Elastic Compute Cloud (Amazon EC2) is a web service that provides resizable computing capacity—literally servers in Amazon’s data centers—that you use to build and host your software systems. You can use the following examples to program [Amazon EC2](http://www.amazonaws.cn/ec2) using the Amazon SDK for C\$1\$1.

**Note**  
Only the code that is necessary to demonstrate certain techniques is supplied in this Guide, but the [complete example code is available on GitHub](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/cpp). On GitHub you can download a single source file or you can clone the repository locally to get, build, and run all examples.

**Topics**
+ [

# Managing Amazon EC2 Instances
](examples-ec2-instances.md)
+ [

# Using Elastic IP Addresses in Amazon EC2
](examples-ec2-elastic-ip.md)
+ [

# Using Regions and Availability Zones for Amazon EC2
](examples-ec2-regions-zones.md)
+ [

# Working with Amazon EC2 Key Pairs
](examples-ec2-key-pairs.md)
+ [

# Working with Security Groups in Amazon EC2
](examples-ec2-security-groups.md)

# Managing Amazon EC2 Instances
<a name="examples-ec2-instances"></a>

## Prerequisites
<a name="codeExamplePrereq"></a>

Before you begin, we recommend you read [Getting started using the Amazon SDK for C\$1\$1](getting-started.md). 

Download the example code and build the solution as described in [Getting started on code examples](getting-started-code-examples.md). 

To run the examples, the user profile your code uses to make the requests must have proper permissions in Amazon (for the service and the action). For more information, see [Providing Amazon credentials](credentials.md).

## Create an Instance
<a name="create-an-instance"></a>

Create a new Amazon EC2 instance by calling the EC2Client’s `RunInstances` function, providing it with a [RunInstancesRequest](https://docs.amazonaws.cn/sdk-for-cpp/latest/api/aws-cpp-sdk-ec2/html/class_aws_1_1_e_c2_1_1_model_1_1_run_instances_request.html) containing the [Amazon Machine Image (AMI)](https://docs.amazonaws.cn/AWSEC2/latest/UserGuide/AMIs.html) to use and an [instance type](https://docs.amazonaws.cn/AWSEC2/latest/UserGuide/instance-types.html).

 **Includes** 

```
#include <aws/core/Aws.h>
#include <aws/ec2/EC2Client.h>
#include <aws/ec2/model/RunInstancesRequest.h>
#include <iostream>
```

 **Code** 

```
    Aws::EC2::EC2Client ec2Client(clientConfiguration);

    Aws::EC2::Model::RunInstancesRequest runRequest;
    runRequest.SetImageId(amiId);
    runRequest.SetInstanceType(Aws::EC2::Model::InstanceType::t1_micro);
    runRequest.SetMinCount(1);
    runRequest.SetMaxCount(1);

    Aws::EC2::Model::RunInstancesOutcome runOutcome = ec2Client.RunInstances(
            runRequest);
    if (!runOutcome.IsSuccess()) {
        std::cerr << "Failed to launch EC2 instance " << instanceName <<
                  " based on ami " << amiId << ":" <<
                  runOutcome.GetError().GetMessage() << std::endl;
        return false;
    }

    const Aws::Vector<Aws::EC2::Model::Instance> &instances = runOutcome.GetResult().GetInstances();
    if (instances.empty()) {
        std::cerr << "Failed to launch EC2 instance " << instanceName <<
                  " based on ami " << amiId << ":" <<
                  runOutcome.GetError().GetMessage() << std::endl;
        return false;
    }
```

See the [complete example](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/cpp/example_code/ec2/run_instances.cpp).

## Start an Instance
<a name="start-an-instance"></a>

To start an Amazon EC2 instance, call the EC2Client’s `StartInstances` function, providing it with a [StartInstancesRequest](https://docs.amazonaws.cn/sdk-for-cpp/latest/api/aws-cpp-sdk-ec2/html/class_aws_1_1_e_c2_1_1_model_1_1_start_instances_request.html) containing the ID of the instance to start.

 **Includes** 

```
#include <aws/ec2/EC2Client.h>
#include <aws/ec2/model/StartInstancesRequest.h>
```

 **Code** 

```
    Aws::EC2::EC2Client ec2Client(clientConfiguration);

    Aws::EC2::Model::StartInstancesRequest startRequest;
    startRequest.AddInstanceIds(instanceId);
    startRequest.SetDryRun(true);

    Aws::EC2::Model::StartInstancesOutcome dryRunOutcome = ec2Client.StartInstances(startRequest);
    if (dryRunOutcome.IsSuccess()) {
        std::cerr
                << "Failed dry run to start instance. A dry run should trigger an error."
                << std::endl;
        return false;
    } else if (dryRunOutcome.GetError().GetErrorType() !=
               Aws::EC2::EC2Errors::DRY_RUN_OPERATION) {
        std::cout << "Failed dry run to start instance " << instanceId << ": "
                  << dryRunOutcome.GetError().GetMessage() << std::endl;
        return false;
    }

    startRequest.SetDryRun(false);
    Aws::EC2::Model::StartInstancesOutcome startInstancesOutcome = ec2Client.StartInstances(startRequest);

    if (!startInstancesOutcome.IsSuccess()) {
        std::cout << "Failed to start instance " << instanceId << ": " <<
                  startInstancesOutcome.GetError().GetMessage() << std::endl;
    } else {
        std::cout << "Successfully started instance " << instanceId <<
                  std::endl;
    }
```

See the [complete example](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/cpp/example_code/ec2/start_stop_instance.cpp).

## Stop an Instance
<a name="stop-an-instance"></a>

To stop an Amazon EC2 instance, call the EC2Client’s `StopInstances` function, providing it with a [StopInstancesRequest](https://docs.amazonaws.cn/sdk-for-cpp/latest/api/aws-cpp-sdk-ec2/html/class_aws_1_1_e_c2_1_1_model_1_1_stop_instances_request.html) containing the ID of the instance to stop.

 **Includes** 

```
#include <aws/ec2/model/StopInstancesRequest.h>
```

 **Code** 

```
    Aws::EC2::EC2Client ec2Client(clientConfiguration);
    Aws::EC2::Model::StopInstancesRequest request;
    request.AddInstanceIds(instanceId);
    request.SetDryRun(true);

    Aws::EC2::Model::StopInstancesOutcome dryRunOutcome = ec2Client.StopInstances(request);
    if (dryRunOutcome.IsSuccess()) {
        std::cerr
                << "Failed dry run to stop instance. A dry run should trigger an error."
                << std::endl;
        return false;
    } else if (dryRunOutcome.GetError().GetErrorType() !=
               Aws::EC2::EC2Errors::DRY_RUN_OPERATION) {
        std::cout << "Failed dry run to stop instance " << instanceId << ": "
                  << dryRunOutcome.GetError().GetMessage() << std::endl;
        return false;
    }

    request.SetDryRun(false);
    Aws::EC2::Model::StopInstancesOutcome outcome = ec2Client.StopInstances(request);
    if (!outcome.IsSuccess()) {
        std::cout << "Failed to stop instance " << instanceId << ": " <<
                  outcome.GetError().GetMessage() << std::endl;
    } else {
        std::cout << "Successfully stopped instance " << instanceId <<
                  std::endl;
    }
```

See the [complete example](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/cpp/example_code/ec2/start_stop_instance.cpp).

## Reboot an Instance
<a name="reboot-an-instance"></a>

To reboot an Amazon EC2 instance, call the EC2Client’s `RebootInstances` function, providing it with a [RebootInstancesRequest](https://docs.amazonaws.cn/sdk-for-cpp/latest/api/aws-cpp-sdk-ec2/html/class_aws_1_1_e_c2_1_1_model_1_1_reboot_instances_request.html) containing the ID of the instance to reboot.

 **Includes** 

```
#include <aws/ec2/EC2Client.h>
#include <aws/ec2/model/RebootInstancesRequest.h>
#include <iostream>
```

 **Code** 

```
    Aws::EC2::EC2Client ec2Client(clientConfiguration);

    Aws::EC2::Model::RebootInstancesRequest request;
    request.AddInstanceIds(instanceId);
    request.SetDryRun(true);

    Aws::EC2::Model::RebootInstancesOutcome dry_run_outcome = ec2Client.RebootInstances(request);
    if (dry_run_outcome.IsSuccess()) {
        std::cerr
                << "Failed dry run to reboot on instance. A dry run should trigger an error."
                <<
                std::endl;
        return false;
    } else if (dry_run_outcome.GetError().GetErrorType()
               != Aws::EC2::EC2Errors::DRY_RUN_OPERATION) {
        std::cout << "Failed dry run to reboot instance " << instanceId << ": "
                  << dry_run_outcome.GetError().GetMessage() << std::endl;
        return false;
    }

    request.SetDryRun(false);
    Aws::EC2::Model::RebootInstancesOutcome outcome = ec2Client.RebootInstances(request);
    if (!outcome.IsSuccess()) {
        std::cout << "Failed to reboot instance " << instanceId << ": " <<
                  outcome.GetError().GetMessage() << std::endl;
    } else {
        std::cout << "Successfully rebooted instance " << instanceId <<
                  std::endl;
    }
```

See the [complete example](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/cpp/example_code/ec2/reboot_instance.cpp).

## Describe Instances
<a name="describe-instances"></a>

To list your instances, create a [DescribeInstancesRequest](https://docs.amazonaws.cn/sdk-for-cpp/latest/api/aws-cpp-sdk-ec2/html/class_aws_1_1_e_c2_1_1_model_1_1_describe_instances_request.html) and call the EC2Client’s `DescribeInstances` function. It will return a [DescribeInstancesResponse](https://docs.amazonaws.cn/sdk-for-cpp/latest/api/aws-cpp-sdk-ec2/html/class_aws_1_1_e_c2_1_1_model_1_1_describe_instances_response.html) object that you can use to list the Amazon EC2 instances for your Amazon Web Services account and Amazon Web Services Region.

Instances are grouped by *reservation*. Each reservation corresponds to the call to `StartInstances` that launched the instance. To list your instances, you must first call the `DescribeInstancesResponse` class’ `GetReservations` function, and then call `getInstances` on each returned Reservation object.

 **Includes** 

```
#include <aws/ec2/EC2Client.h>
#include <aws/ec2/model/DescribeInstancesRequest.h>
#include <aws/ec2/model/DescribeInstancesResponse.h>
#include <iomanip>
#include <iostream>
```

 **Code** 

```
    Aws::EC2::EC2Client ec2Client(clientConfiguration);
    Aws::EC2::Model::DescribeInstancesRequest request;
    bool header = false;
    bool done = false;
    while (!done) {
        Aws::EC2::Model::DescribeInstancesOutcome outcome = ec2Client.DescribeInstances(request);
        if (outcome.IsSuccess()) {
            if (!header) {
                std::cout << std::left <<
                          std::setw(48) << "Name" <<
                          std::setw(20) << "ID" <<
                          std::setw(25) << "Ami" <<
                          std::setw(15) << "Type" <<
                          std::setw(15) << "State" <<
                          std::setw(15) << "Monitoring" << std::endl;
                header = true;
            }

            const std::vector<Aws::EC2::Model::Reservation> &reservations =
                    outcome.GetResult().GetReservations();

            for (const auto &reservation: reservations) {
                const std::vector<Aws::EC2::Model::Instance> &instances =
                        reservation.GetInstances();
                for (const auto &instance: instances) {
                    Aws::String instanceStateString =
                            Aws::EC2::Model::InstanceStateNameMapper::GetNameForInstanceStateName(
                                    instance.GetState().GetName());

                    Aws::String typeString =
                            Aws::EC2::Model::InstanceTypeMapper::GetNameForInstanceType(
                                    instance.GetInstanceType());

                    Aws::String monitorString =
                            Aws::EC2::Model::MonitoringStateMapper::GetNameForMonitoringState(
                                    instance.GetMonitoring().GetState());
                    Aws::String name = "Unknown";

                    const std::vector<Aws::EC2::Model::Tag> &tags = instance.GetTags();
                    auto nameIter = std::find_if(tags.cbegin(), tags.cend(),
                                                 [](const Aws::EC2::Model::Tag &tag) {
                                                     return tag.GetKey() == "Name";
                                                 });
                    if (nameIter != tags.cend()) {
                        name = nameIter->GetValue();
                    }
                    std::cout <<
                              std::setw(48) << name <<
                              std::setw(20) << instance.GetInstanceId() <<
                              std::setw(25) << instance.GetImageId() <<
                              std::setw(15) << typeString <<
                              std::setw(15) << instanceStateString <<
                              std::setw(15) << monitorString << std::endl;
                }
            }

            if (!outcome.GetResult().GetNextToken().empty()) {
                request.SetNextToken(outcome.GetResult().GetNextToken());
            } else {
                done = true;
            }
        } else {
            std::cerr << "Failed to describe EC2 instances:" <<
                      outcome.GetError().GetMessage() << std::endl;
            return false;
        }
    }
```

Results are paged; you can get further results by passing the value returned from the result object’s `GetNextToken` function to your original request object’s `SetNextToken` function, then using the same request object in your next call to `DescribeInstances`.

See the [complete example](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/cpp/example_code/ec2/describe_instances.cpp).

## Enable Instance Monitoring
<a name="enable-instance-monitoring"></a>

You can monitor various aspects of your Amazon EC2 instances, such as CPU and network utilization, available memory, and disk space remaining. To learn more about instance monitoring, see [Monitoring Amazon EC2](https://docs.amazonaws.cn/AWSEC2/latest/UserGuide/monitoring_ec2.html) in the Amazon EC2 User Guide.

To start monitoring an instance, you must create a [MonitorInstancesRequest](https://docs.amazonaws.cn/sdk-for-cpp/latest/api/aws-cpp-sdk-ec2/html/class_aws_1_1_e_c2_1_1_model_1_1_monitor_instances_request.html) with the ID of the instance to monitor, and pass it to the EC2Client’s `MonitorInstances` function.

 **Includes** 

```
#include <aws/ec2/EC2Client.h>
#include <aws/ec2/model/MonitorInstancesRequest.h>
#include <aws/ec2/model/UnmonitorInstancesRequest.h>
#include <iostream>
```

 **Code** 

```
    Aws::EC2::EC2Client ec2Client(clientConfiguration);
    Aws::EC2::Model::MonitorInstancesRequest request;
    request.AddInstanceIds(instanceId);
    request.SetDryRun(true);

    Aws::EC2::Model::MonitorInstancesOutcome dryRunOutcome = ec2Client.MonitorInstances(request);
    if (dryRunOutcome.IsSuccess()) {
        std::cerr
                << "Failed dry run to enable monitoring on instance. A dry run should trigger an error."
                <<
                std::endl;
        return false;
    } else if (dryRunOutcome.GetError().GetErrorType()
               != Aws::EC2::EC2Errors::DRY_RUN_OPERATION) {
        std::cerr << "Failed dry run to enable monitoring on instance " <<
                  instanceId << ": " << dryRunOutcome.GetError().GetMessage() <<
                  std::endl;
        return false;
    }

    request.SetDryRun(false);
    Aws::EC2::Model::MonitorInstancesOutcome monitorInstancesOutcome = ec2Client.MonitorInstances(request);
    if (!monitorInstancesOutcome.IsSuccess()) {
        std::cerr << "Failed to enable monitoring on instance " <<
                  instanceId << ": " <<
                  monitorInstancesOutcome.GetError().GetMessage() << std::endl;
    } else {
        std::cout << "Successfully enabled monitoring on instance " <<
                  instanceId << std::endl;
    }
```

See the [complete example](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/cpp/example_code/ec2/monitor_instance.cpp).

## Disable Instance Monitoring
<a name="disable-instance-monitoring"></a>

To stop monitoring an instance, create an [UnmonitorInstancesRequest](https://docs.amazonaws.cn/sdk-for-cpp/latest/api/aws-cpp-sdk-ec2/html/class_aws_1_1_e_c2_1_1_model_1_1_unmonitor_instances_request.html) with the ID of the instance to stop monitoring, and pass it to the EC2Client’s `UnmonitorInstances` function.

 **Includes** 

```
#include <aws/ec2/EC2Client.h>
#include <aws/ec2/model/MonitorInstancesRequest.h>
#include <aws/ec2/model/UnmonitorInstancesRequest.h>
#include <iostream>
```

 **Code** 

```
    Aws::EC2::EC2Client ec2Client(clientConfiguration);
    Aws::EC2::Model::UnmonitorInstancesRequest unrequest;
    unrequest.AddInstanceIds(instanceId);
    unrequest.SetDryRun(true);

    Aws::EC2::Model::UnmonitorInstancesOutcome dryRunOutcome = ec2Client.UnmonitorInstances(unrequest);
    if (dryRunOutcome.IsSuccess()) {
        std::cerr
                << "Failed dry run to disable monitoring on instance. A dry run should trigger an error."
                <<
                std::endl;
        return false;
    } else if (dryRunOutcome.GetError().GetErrorType() !=
               Aws::EC2::EC2Errors::DRY_RUN_OPERATION) {
        std::cout << "Failed dry run to disable monitoring on instance " <<
                  instanceId << ": " << dryRunOutcome.GetError().GetMessage() <<
                  std::endl;
        return false;
    }

    unrequest.SetDryRun(false);
    Aws::EC2::Model::UnmonitorInstancesOutcome unmonitorInstancesOutcome = ec2Client.UnmonitorInstances(unrequest);
    if (!unmonitorInstancesOutcome.IsSuccess()) {
        std::cout << "Failed to disable monitoring on instance " << instanceId
                  << ": " << unmonitorInstancesOutcome.GetError().GetMessage() <<
                  std::endl;
    } else {
        std::cout << "Successfully disable monitoring on instance " <<
                  instanceId << std::endl;
    }
```

See the [complete example](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/cpp/example_code/ec2/monitor_instance.cpp).

## More Information
<a name="more-information"></a>
+  [RunInstances](https://docs.amazonaws.cn/AWSEC2/latest/APIReference/API_RunInstances.html) in the Amazon EC2 API Reference
+  [DescribeInstances](https://docs.amazonaws.cn/AWSEC2/latest/APIReference/API_DescribeInstances.html) in the Amazon EC2 API Reference
+  [StartInstances](https://docs.amazonaws.cn/AWSEC2/latest/APIReference/API_StartInstances.html) in the Amazon EC2 API Reference
+  [StopInstances](https://docs.amazonaws.cn/AWSEC2/latest/APIReference/API_StopInstances.html) in the Amazon EC2 API Reference
+  [RebootInstances](https://docs.amazonaws.cn/AWSEC2/latest/APIReference/API_RebootInstances.html) in the Amazon EC2 API Reference
+  [DescribeInstances](https://docs.amazonaws.cn/AWSEC2/latest/APIReference/API_DescribeInstances.html) in the Amazon EC2 API Reference
+  [MonitorInstances](https://docs.amazonaws.cn/AWSEC2/latest/APIReference/API_MonitorInstances.html) in the Amazon EC2 API Reference
+  [UnmonitorInstances](https://docs.amazonaws.cn/AWSEC2/latest/APIReference/API_UnmonitorInstances.html) in the Amazon EC2 API Reference

# Using Elastic IP Addresses in Amazon EC2
<a name="examples-ec2-elastic-ip"></a>

## Prerequisites
<a name="codeExamplePrereq"></a>

Before you begin, we recommend you read [Getting started using the Amazon SDK for C\$1\$1](getting-started.md). 

Download the example code and build the solution as described in [Getting started on code examples](getting-started-code-examples.md). 

To run the examples, the user profile your code uses to make the requests must have proper permissions in Amazon (for the service and the action). For more information, see [Providing Amazon credentials](credentials.md).

## Allocate an Elastic IP Address
<a name="allocate-an-elastic-ip-address"></a>

To use an Elastic IP address, you first allocate one to your account, and then associate it with your instance or a network interface.

To allocate an Elastic IP address, call the EC2Client’s `AllocateAddress` function with an [AllocateAddressRequest](https://docs.amazonaws.cn/sdk-for-cpp/latest/api/aws-cpp-sdk-ec2/html/class_aws_1_1_e_c2_1_1_model_1_1_allocate_address_request.html) object containing the network type (classic EC2 or VPC). 

**Warning**  
We are retiring EC2-Classic on August 15, 2022. We recommend that you migrate from EC2-Classic to a VPC. For more information, see **Migrate from EC2-Classic to a VPC** in the the [Amazon EC2 User Guide for Linux Instances](https://docs.amazonaws.cn/AWSEC2/latest/UserGuide/vpc-migrate.html) or the [Amazon EC2 User Guide for Windows Instances](https://docs.amazonaws.cn/AWSEC2/latest/WindowsGuide/vpc-migrate.html). Also see the blog post [EC2-Classic Networking is Retiring – Here's How to Prepare](https://amazonaws-china.com/blogs/aws/ec2-classic-is-retiring-heres-how-to-prepare/).

The [AllocateAddressResponse](https://docs.amazonaws.cn/sdk-for-cpp/latest/api/aws-cpp-sdk-ec2/html/class_aws_1_1_e_c2_1_1_model_1_1_allocate_address_response.html) class in the response object contains an allocation ID that you can use to associate the address with an instance, by passing the allocation ID and instance ID in a [AssociateAddressRequest](https://docs.amazonaws.cn/sdk-for-cpp/latest/api/aws-cpp-sdk-ec2/html/class_aws_1_1_e_c2_1_1_model_1_1_associate_address_request.html) to the EC2Client’s `AssociateAddress` function.

 **Includes** 

```
#include <aws/ec2/EC2Client.h>
#include <aws/ec2/model/AllocateAddressRequest.h>
#include <aws/ec2/model/AssociateAddressRequest.h>
#include <iostream>
```

 **Code** 

```
    Aws::EC2::EC2Client ec2Client(clientConfiguration);

    Aws::EC2::Model::AllocateAddressRequest request;
    request.SetDomain(Aws::EC2::Model::DomainType::vpc);

    const Aws::EC2::Model::AllocateAddressOutcome outcome =
            ec2Client.AllocateAddress(request);
    if (!outcome.IsSuccess()) {
        std::cerr << "Failed to allocate Elastic IP address:" <<
                  outcome.GetError().GetMessage() << std::endl;
        return false;
    }
    const Aws::EC2::Model::AllocateAddressResponse &response = outcome.GetResult();
    allocationID = response.GetAllocationId();
    publicIPAddress = response.GetPublicIp();


    Aws::EC2::Model::AssociateAddressRequest associate_request;
    associate_request.SetInstanceId(instanceId);
    associate_request.SetAllocationId(allocationID);

    const Aws::EC2::Model::AssociateAddressOutcome associate_outcome =
            ec2Client.AssociateAddress(associate_request);
    if (!associate_outcome.IsSuccess()) {
        std::cerr << "Failed to associate Elastic IP address " << allocationID
                  << " with instance " << instanceId << ":" <<
                  associate_outcome.GetError().GetMessage() << std::endl;
        return false;
    }

    std::cout << "Successfully associated Elastic IP address " << allocationID
              << " with instance " << instanceId << std::endl;
```

See the [complete example](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/cpp/example_code/ec2/allocate_address.cpp).

## Describe Elastic IP Addresses
<a name="describe-elastic-ip-addresses"></a>

To list the Elastic IP addresses assigned to your account, call the EC2Client’s `DescribeAddresses` function. It returns an outcome object that contains a [DescribeAddressesResponse](https://docs.amazonaws.cn/sdk-for-cpp/latest/api/aws-cpp-sdk-ec2/html/class_aws_1_1_e_c2_1_1_model_1_1_describe_addresses_response.html) which you can use to get a list of [Address](https://docs.amazonaws.cn/sdk-for-cpp/latest/api/aws-cpp-sdk-ec2/html/class_aws_1_1_e_c2_1_1_model_1_1_address.html) objects that represent the Elastic IP addresses on your account.

 **Includes** 

```
#include <aws/ec2/EC2Client.h>
#include <aws/ec2/model/DescribeAddressesRequest.h>
#include <aws/ec2/model/DescribeAddressesResponse.h>
#include <iomanip>
#include <iostream>
```

 **Code** 

```
    Aws::EC2::EC2Client ec2Client(clientConfiguration);
    Aws::EC2::Model::DescribeAddressesRequest request;
    Aws::EC2::Model::DescribeAddressesOutcome outcome = ec2Client.DescribeAddresses(request);
    if (outcome.IsSuccess()) {
        std::cout << std::left << std::setw(20) << "InstanceId" <<
                  std::setw(15) << "Public IP" << std::setw(10) << "Domain" <<
                  std::setw(30) << "Allocation ID" << std::setw(25) <<
                  "NIC ID" << std::endl;

        const Aws::Vector<Aws::EC2::Model::Address> &addresses = outcome.GetResult().GetAddresses();
        for (const auto &address: addresses) {
            Aws::String domainString =
                    Aws::EC2::Model::DomainTypeMapper::GetNameForDomainType(
                            address.GetDomain());

            std::cout << std::left << std::setw(20) <<
                      address.GetInstanceId() << std::setw(15) <<
                      address.GetPublicIp() << std::setw(10) << domainString <<
                      std::setw(30) << address.GetAllocationId() << std::setw(25)
                      << address.GetNetworkInterfaceId() << std::endl;
        }
    } else {
        std::cerr << "Failed to describe Elastic IP addresses:" <<
                  outcome.GetError().GetMessage() << std::endl;
    }
```

See the [complete example](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/cpp/example_code/ec2/describe_addresses.cpp).

## Release an Elastic IP Address
<a name="release-an-elastic-ip-address"></a>

To release an Elastic IP address, call the EC2Client’s `ReleaseAddress` function, passing it a [ReleaseAddressRequest](https://docs.amazonaws.cn/sdk-for-cpp/latest/api/aws-cpp-sdk-ec2/html/class_aws_1_1_e_c2_1_1_model_1_1_release_address_request.html) containing the allocation ID of the Elastic IP address you want to release.

 **Includes** 

```
#include <aws/ec2/EC2Client.h>
#include <aws/ec2/model/ReleaseAddressRequest.h>
#include <iostream>
```

 **Code** 

```
    Aws::EC2::EC2Client ec2(clientConfiguration);

    Aws::EC2::Model::ReleaseAddressRequest request;
    request.SetAllocationId(allocationID);

    Aws::EC2::Model::ReleaseAddressOutcome outcome = ec2.ReleaseAddress(request);
    if (!outcome.IsSuccess()) {
        std::cerr << "Failed to release Elastic IP address " <<
                  allocationID << ":" << outcome.GetError().GetMessage() <<
                  std::endl;
    } else {
        std::cout << "Successfully released Elastic IP address " <<
                  allocationID << std::endl;
    }
```

After you release an Elastic IP address, it is released to the Amazon IP address pool and might be unavailable to you afterward. Be sure to update your DNS records and any servers or devices that communicate with the address. If you attempt to release an Elastic IP address that you already released, you’ll get an *AuthFailure* error if the address is already allocated to another Amazon account.

If you are using a *default VPC*, then releasing an Elastic IP address automatically disassociates it from any instance that it’s associated with. To disassociate an Elastic IP address without releasing it, use the EC2Client’s `DisassociateAddress` function.

If you are using a non-default VPC, you *must* use `DisassociateAddress` to disassociate the Elastic IP address before you try to release it. Otherwise, Amazon EC2 returns an error (*InvalidIPAddress.InUse*).

See the [complete example](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/cpp/example_code/ec2/release_address.cpp).

## More Information
<a name="more-information"></a>
+  [Elastic IP Addresses](https://docs.amazonaws.cn/AWSEC2/latest/UserGuide/elastic-ip-addresses-eip.html) in the Amazon EC2 User Guide
+  [AllocateAddress](https://docs.amazonaws.cn/AWSEC2/latest/APIReference/API_AllocateAddress.html) in the Amazon EC2 API Reference
+  [DescribeAddresses](https://docs.amazonaws.cn/AWSEC2/latest/APIReference/API_DescribeAddresses.html) in the Amazon EC2 API Reference
+  [ReleaseAddress](https://docs.amazonaws.cn/AWSEC2/latest/APIReference/API_ReleaseAddress.html) in the Amazon EC2 API Reference

# Using Regions and Availability Zones for Amazon EC2
<a name="examples-ec2-regions-zones"></a>

## Prerequisites
<a name="codeExamplePrereq"></a>

Before you begin, we recommend you read [Getting started using the Amazon SDK for C\$1\$1](getting-started.md). 

Download the example code and build the solution as described in [Getting started on code examples](getting-started-code-examples.md). 

To run the examples, the user profile your code uses to make the requests must have proper permissions in Amazon (for the service and the action). For more information, see [Providing Amazon credentials](credentials.md).

## Describe Regions
<a name="describe-regions"></a>

To list the Amazon Web Services Regions available to your Amazon Web Services account, call the EC2Client’s `DescribeRegions` function with a [DescribeRegionsRequest](https://docs.amazonaws.cn/sdk-for-cpp/latest/api/aws-cpp-sdk-ec2/html/class_aws_1_1_e_c2_1_1_model_1_1_describe_regions_request.html).

You will receive a [DescribeRegionsResponse](https://docs.amazonaws.cn/sdk-for-cpp/latest/api/aws-cpp-sdk-ec2/html/class_aws_1_1_e_c2_1_1_model_1_1_describe_regions_response.html) in the outcome object. Call its `GetRegions` function to get a list of [Region](https://docs.amazonaws.cn/sdk-for-cpp/latest/api/aws-cpp-sdk-ec2/html/class_aws_1_1_e_c2_1_1_model_1_1_region.html) objects that represent each Region.

 **Includes** 

```
#include <aws/ec2/EC2Client.h>
#include <aws/ec2/model/DescribeRegionsRequest.h>
```

 **Code** 

```
    Aws::EC2::EC2Client ec2Client(clientConfiguration);

    Aws::EC2::Model::DescribeRegionsRequest request;
    Aws::EC2::Model::DescribeRegionsOutcome outcome = ec2Client.DescribeRegions(request);
    if (outcome.IsSuccess()) {
        std::cout << std::left <<
                  std::setw(32) << "RegionName" <<
                  std::setw(64) << "Endpoint" << std::endl;

        const auto &regions = outcome.GetResult().GetRegions();
        for (const auto &region: regions) {
            std::cout << std::left <<
                      std::setw(32) << region.GetRegionName() <<
                      std::setw(64) << region.GetEndpoint() << std::endl;
        }
    } else {
        std::cerr << "Failed to describe regions:" <<
                  outcome.GetError().GetMessage() << std::endl;
    }
```

See the [complete example](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/cpp/example_code/ec2/describe_regions_and_zones.cpp).

## Describe Availability Zones
<a name="describe-availability-zones"></a>

To list each availability zone available to your account, call the EC2Client’s `DescribeAvailabilityZones` function with a [DescribeAvailabilityZonesRequest](https://docs.amazonaws.cn/sdk-for-cpp/latest/api/aws-cpp-sdk-ec2/html/class_aws_1_1_e_c2_1_1_model_1_1_describe_availability_zones_request.html).

You will receive a [DescribeAvailabilityZonesResponse](https://docs.amazonaws.cn/sdk-for-cpp/latest/api/aws-cpp-sdk-ec2/html/class_aws_1_1_e_c2_1_1_model_1_1_describe_availability_zones_response.html) in the outcome object. Call its `GetAvailabilityZones` function to get a list of [AvailabilityZone](https://docs.amazonaws.cn/sdk-for-cpp/latest/api/aws-cpp-sdk-ec2/html/class_aws_1_1_e_c2_1_1_model_1_1_availability_zone.html) objects that represent each availability zone.

 **Includes** 

```
#include <aws/ec2/model/DescribeAvailabilityZonesRequest.h>
```

 **Code** 

```
    Aws::EC2::Model::DescribeAvailabilityZonesRequest request;
    Aws::EC2::Model::DescribeAvailabilityZonesOutcome outcome = ec2Client.DescribeAvailabilityZones(request);

    if (outcome.IsSuccess()) {
        std::cout << std::left <<
                  std::setw(32) << "ZoneName" <<
                  std::setw(20) << "State" <<
                  std::setw(32) << "Region" << std::endl;

        const auto &zones =
                outcome.GetResult().GetAvailabilityZones();

        for (const auto &zone: zones) {
            Aws::String stateString =
                    Aws::EC2::Model::AvailabilityZoneStateMapper::GetNameForAvailabilityZoneState(
                            zone.GetState());
            std::cout << std::left <<
                      std::setw(32) << zone.GetZoneName() <<
                      std::setw(20) << stateString <<
                      std::setw(32) << zone.GetRegionName() << std::endl;
        }
    } else {
        std::cerr << "Failed to describe availability zones:" <<
                  outcome.GetError().GetMessage() << std::endl;

    }
```

See the [complete example](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/cpp/example_code/ec2/describe_regions_and_zones.cpp).

## More Information
<a name="more-information"></a>
+  [Regions and Availability Zones](https://docs.amazonaws.cn/AWSEC2/latest/UserGuide/using-regions-availability-zones.html) in the Amazon EC2 User Guide
+  [DescribeRegions](https://docs.amazonaws.cn/AWSEC2/latest/APIReference/API_DescribeRegions.html) in the Amazon EC2 API Reference
+  [DescribeAvailabilityZones](https://docs.amazonaws.cn/AWSEC2/latest/APIReference/API_DescribeAvailabilityZones.html) in the Amazon EC2 API Reference

# Working with Amazon EC2 Key Pairs
<a name="examples-ec2-key-pairs"></a>

## Prerequisites
<a name="codeExamplePrereq"></a>

Before you begin, we recommend you read [Getting started using the Amazon SDK for C\$1\$1](getting-started.md). 

Download the example code and build the solution as described in [Getting started on code examples](getting-started-code-examples.md). 

To run the examples, the user profile your code uses to make the requests must have proper permissions in Amazon (for the service and the action). For more information, see [Providing Amazon credentials](credentials.md).

## Create a Key Pair
<a name="create-a-key-pair"></a>

To create a key pair, call the EC2Client’s `CreateKeyPair` function with a [CreateKeyPairRequest](https://docs.amazonaws.cn/sdk-for-cpp/latest/api/aws-cpp-sdk-ec2/html/class_aws_1_1_e_c2_1_1_model_1_1_create_key_pair_request.html) that contains the key’s name.

 **Includes** 

```
#include <aws/ec2/EC2Client.h>
#include <aws/ec2/model/CreateKeyPairRequest.h>
#include <iostream>
#include <fstream>
```

 **Code** 

```
    Aws::EC2::EC2Client ec2Client(clientConfiguration);
    Aws::EC2::Model::CreateKeyPairRequest request;
    request.SetKeyName(keyPairName);

    Aws::EC2::Model::CreateKeyPairOutcome outcome = ec2Client.CreateKeyPair(request);
    if (!outcome.IsSuccess()) {
        std::cerr << "Failed to create key pair - "  << keyPairName << ". " <<
                  outcome.GetError().GetMessage() << std::endl;
    } else {
        std::cout << "Successfully created key pair named " <<
                  keyPairName << std::endl;
        if (!keyFilePath.empty()) {
            std::ofstream keyFile(keyFilePath.c_str());
            keyFile << outcome.GetResult().GetKeyMaterial();
            keyFile.close();
            std::cout << "Keys written to the file " <<
                      keyFilePath << std::endl;
        }

    }
```

See the [complete example](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/cpp/example_code/ec2/create_key_pair.cpp).

## Describe Key Pairs
<a name="describe-key-pairs"></a>

To list your key pairs or to get information about them, call the EC2Client’s `DescribeKeyPairs` function with a [DescribeKeyPairsRequest](https://docs.amazonaws.cn/sdk-for-cpp/latest/api/aws-cpp-sdk-ec2/html/class_aws_1_1_e_c2_1_1_model_1_1_describe_key_pairs_request.html).

You will receive a [DescribeKeyPairsResponse](https://docs.amazonaws.cn/sdk-for-cpp/latest/api/aws-cpp-sdk-ec2/html/class_aws_1_1_e_c2_1_1_model_1_1_describe_key_pairs_response.html) that you can use to access the list of key pairs by calling its `GetKeyPairs` function, which returns a list of [KeyPairInfo](https://docs.amazonaws.cn/sdk-for-cpp/latest/api/aws-cpp-sdk-ec2/html/class_aws_1_1_e_c2_1_1_model_1_1_key_pair_info.html) objects.

 **Includes** 

```
#include <aws/ec2/EC2Client.h>
#include <aws/ec2/model/DescribeKeyPairsRequest.h>
#include <aws/ec2/model/DescribeKeyPairsResponse.h>
#include <iomanip>
#include <iostream>
```

 **Code** 

```
    Aws::EC2::EC2Client ec2Client(clientConfiguration);
    Aws::EC2::Model::DescribeKeyPairsRequest request;

    Aws::EC2::Model::DescribeKeyPairsOutcome outcome = ec2Client.DescribeKeyPairs(request);
    if (outcome.IsSuccess()) {
        std::cout << std::left <<
                  std::setw(32) << "Name" <<
                  std::setw(64) << "Fingerprint" << std::endl;

        const std::vector<Aws::EC2::Model::KeyPairInfo> &key_pairs =
                outcome.GetResult().GetKeyPairs();
        for (const auto &key_pair: key_pairs) {
            std::cout << std::left <<
                      std::setw(32) << key_pair.GetKeyName() <<
                      std::setw(64) << key_pair.GetKeyFingerprint() << std::endl;
        }
    } else {
        std::cerr << "Failed to describe key pairs:" <<
                  outcome.GetError().GetMessage() << std::endl;
    }
```

See the [complete example](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/cpp/example_code/ec2/describe_key_pairs.cpp).

## Delete a Key Pair
<a name="delete-a-key-pair"></a>

To delete a key pair, call the EC2Client’s `DeleteKeyPair` function, passing it a [DeleteKeyPairRequest](https://docs.amazonaws.cn/sdk-for-cpp/latest/api/aws-cpp-sdk-ec2/html/class_aws_1_1_e_c2_1_1_model_1_1_delete_key_pair_request.html) that contains the name of the key pair to delete.

 **Includes** 

```
#include <aws/ec2/EC2Client.h>
#include <aws/ec2/model/DeleteKeyPairRequest.h>
#include <iostream>
```

 **Code** 

```
    Aws::EC2::EC2Client ec2Client(clientConfiguration);
    Aws::EC2::Model::DeleteKeyPairRequest request;

    request.SetKeyName(keyPairName);
    const Aws::EC2::Model::DeleteKeyPairOutcome outcome = ec2Client.DeleteKeyPair(
            request);

    if (!outcome.IsSuccess()) {
        std::cerr << "Failed to delete key pair " << keyPairName <<
                  ":" << outcome.GetError().GetMessage() << std::endl;
    } else {
        std::cout << "Successfully deleted key pair named " << keyPairName <<
                  std::endl;
    }
```

See the [complete example](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/cpp/example_code/ec2/delete_key_pair.cpp).

## More Information
<a name="more-information"></a>
+  [Amazon EC2 Key Pairs](https://docs.amazonaws.cn/AWSEC2/latest/UserGuide/ec2-key-pairs.html) in the Amazon EC2 User Guide
+  [CreateKeyPair](https://docs.amazonaws.cn/AWSEC2/latest/APIReference/API_CreateKeyPair.html) in the Amazon EC2 API Reference
+  [DescribeKeyPairs](https://docs.amazonaws.cn/AWSEC2/latest/APIReference/API_DescribeKeyPairs.html) in the Amazon EC2 API Reference
+  [DeleteKeyPair](https://docs.amazonaws.cn/AWSEC2/latest/APIReference/API_DeleteKeyPair.html) in the Amazon EC2 API Reference

# Working with Security Groups in Amazon EC2
<a name="examples-ec2-security-groups"></a>

## Prerequisites
<a name="codeExamplePrereq"></a>

Before you begin, we recommend you read [Getting started using the Amazon SDK for C\$1\$1](getting-started.md). 

Download the example code and build the solution as described in [Getting started on code examples](getting-started-code-examples.md). 

To run the examples, the user profile your code uses to make the requests must have proper permissions in Amazon (for the service and the action). For more information, see [Providing Amazon credentials](credentials.md).

## Create a Security Group
<a name="create-a-security-group"></a>

To create a security group, call the EC2Client’s `CreateSecurityGroup` function with a [CreateSecurityGroupRequest](https://docs.amazonaws.cn/sdk-for-cpp/latest/api/aws-cpp-sdk-ec2/html/class_aws_1_1_e_c2_1_1_model_1_1_create_security_group_request.html) that contains the key’s name.

 **Includes** 

```
#include <aws/ec2/EC2Client.h>
#include <aws/ec2/model/CreateSecurityGroupRequest.h>
```

 **Code** 

```
    Aws::EC2::EC2Client ec2Client(clientConfiguration);

    Aws::EC2::Model::CreateSecurityGroupRequest request;

    request.SetGroupName(groupName);
    request.SetDescription(description);
    request.SetVpcId(vpcID);

    const Aws::EC2::Model::CreateSecurityGroupOutcome outcome =
            ec2Client.CreateSecurityGroup(request);

    if (!outcome.IsSuccess()) {
        std::cerr << "Failed to create security group:" <<
                  outcome.GetError().GetMessage() << std::endl;
        return false;
    }

    std::cout << "Successfully created security group named " << groupName <<
              std::endl;
```

See the [complete example](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/cpp/example_code/ec2/create_security_group.cpp).

## Configure a Security Group
<a name="configure-a-security-group"></a>

A security group can control both inbound (ingress) and outbound (egress) traffic to your Amazon EC2 instances.

To add ingress rules to your security group, use the EC2Client’s `AuthorizeSecurityGroupIngress` function, providing the name of the security group and the access rules ([IpPermission](https://docs.amazonaws.cn/sdk-for-cpp/latest/api/aws-cpp-sdk-ec2/html/class_aws_1_1_e_c2_1_1_model_1_1_ip_permission.html)) you want to assign to it within an [AuthorizeSecurityGroupIngressRequest](https://docs.amazonaws.cn/sdk-for-cpp/latest/api/aws-cpp-sdk-ec2/html/class_aws_1_1_e_c2_1_1_model_1_1_authorize_security_group_ingress_request.html) object. The following example shows how to add IP permissions to a security group.

 **Includes** 

```
#include <aws/ec2/model/AuthorizeSecurityGroupIngressRequest.h>
```

 **Code** 

```
    Aws::EC2::Model::AuthorizeSecurityGroupIngressRequest authorizeSecurityGroupIngressRequest;
    authorizeSecurityGroupIngressRequest.SetGroupId(groupID);
```

```
    Aws::String ingressIPRange = "203.0.113.0/24";  // Configure this for your allowed IP range.
    Aws::EC2::Model::IpRange ip_range;
    ip_range.SetCidrIp(ingressIPRange);

    Aws::EC2::Model::IpPermission permission1;
    permission1.SetIpProtocol("tcp");
    permission1.SetToPort(80);
    permission1.SetFromPort(80);
    permission1.AddIpRanges(ip_range);

    authorize_request.AddIpPermissions(permission1);

    Aws::EC2::Model::IpPermission permission2;
    permission2.SetIpProtocol("tcp");
    permission2.SetToPort(22);
    permission2.SetFromPort(22);
    permission2.AddIpRanges(ip_range);

    authorize_request.AddIpPermissions(permission2);
```

```
    Aws::EC2::Model::AuthorizeSecurityGroupIngressOutcome authorizeSecurityGroupIngressOutcome =
            ec2Client.AuthorizeSecurityGroupIngress(authorizeSecurityGroupIngressRequest);

    if (authorizeSecurityGroupIngressOutcome.IsSuccess()) {
        std::cout << "Successfully authorized security group ingress." << std::endl;
    } else {
        std::cerr << "Error authorizing security group ingress: "
                  << authorizeSecurityGroupIngressOutcome.GetError().GetMessage() << std::endl;
    }
```

To add an egress rule to the security group, provide similar data in an [AuthorizeSecurityGroupEgressRequest](https://docs.amazonaws.cn/sdk-for-cpp/latest/api/aws-cpp-sdk-ec2/html/class_aws_1_1_e_c2_1_1_model_1_1_authorize_security_group_egress_request.html) to the EC2Client’s `AuthorizeSecurityGroupEgress` function.

See the [complete example](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/cpp/example_code/ec2/create_security_group.cpp).

## Describe Security Groups
<a name="describe-security-groups"></a>

To describe your security groups or get information about them, call the EC2Client’s `DescribeSecurityGroups` function with a [DescribeSecurityGroupsRequest](https://docs.amazonaws.cn/sdk-for-cpp/latest/api/aws-cpp-sdk-ec2/html/class_aws_1_1_e_c2_1_1_model_1_1_describe_security_groups_request.html).

You will receive a [DescribeSecurityGroupsResponse](https://docs.amazonaws.cn/sdk-for-cpp/latest/api/aws-cpp-sdk-ec2/html/class_aws_1_1_e_c2_1_1_model_1_1_describe_security_groups_response.html) in the outcome object that you can use to access the list of security groups by calling its `GetSecurityGroups` function, which returns a list of [SecurityGroup](https://docs.amazonaws.cn/sdk-for-cpp/latest/api/aws-cpp-sdk-ec2/html/class_aws_1_1_e_c2_1_1_model_1_1_security_group.html) objects.

 **Includes** 

```
#include <aws/ec2/EC2Client.h>
#include <aws/ec2/model/DescribeSecurityGroupsRequest.h>
#include <aws/ec2/model/DescribeSecurityGroupsResponse.h>
#include <iomanip>
#include <iostream>
```

 **Code** 

```
    Aws::EC2::EC2Client ec2Client(clientConfiguration);
    Aws::EC2::Model::DescribeSecurityGroupsRequest request;

    if (!groupID.empty()) {
        request.AddGroupIds(groupID);
    }

    Aws::String nextToken;
    do {
        if (!nextToken.empty()) {
            request.SetNextToken(nextToken);
        }

        Aws::EC2::Model::DescribeSecurityGroupsOutcome outcome = ec2Client.DescribeSecurityGroups(request);
        if (outcome.IsSuccess()) {
            std::cout << std::left <<
                      std::setw(32) << "Name" <<
                      std::setw(30) << "GroupId" <<
                      std::setw(30) << "VpcId" <<
                      std::setw(64) << "Description" << std::endl;

            const std::vector<Aws::EC2::Model::SecurityGroup> &securityGroups =
                    outcome.GetResult().GetSecurityGroups();

            for (const auto &securityGroup: securityGroups) {
                std::cout << std::left <<
                          std::setw(32) << securityGroup.GetGroupName() <<
                          std::setw(30) << securityGroup.GetGroupId() <<
                          std::setw(30) << securityGroup.GetVpcId() <<
                          std::setw(64) << securityGroup.GetDescription() <<
                          std::endl;
            }
        } else {
            std::cerr << "Failed to describe security groups:" <<
                      outcome.GetError().GetMessage() << std::endl;
            return false;
        }

        nextToken = outcome.GetResult().GetNextToken();
    } while (!nextToken.empty());
```

See the [complete example](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/cpp/example_code/ec2/describe_security_groups.cpp).

## Delete a Security Group
<a name="delete-a-security-group"></a>

To delete a security group, call the EC2Client’s `DeleteSecurityGroup` function, passing it a [DeleteSecurityGroupRequest](https://docs.amazonaws.cn/sdk-for-cpp/latest/api/aws-cpp-sdk-ec2/html/class_aws_1_1_e_c2_1_1_model_1_1_delete_security_group_request.html) that contains the ID of the security group to delete.

 **Includes** 

```
#include <aws/ec2/EC2Client.h>
#include <aws/ec2/model/DeleteSecurityGroupRequest.h>
#include <iostream>
```

 **Code** 

```
    Aws::EC2::EC2Client ec2Client(clientConfiguration);
    Aws::EC2::Model::DeleteSecurityGroupRequest request;

    request.SetGroupId(securityGroupID);
    Aws::EC2::Model::DeleteSecurityGroupOutcome outcome = ec2Client.DeleteSecurityGroup(request);

    if (!outcome.IsSuccess()) {
        std::cerr << "Failed to delete security group " << securityGroupID <<
                  ":" << outcome.GetError().GetMessage() << std::endl;
    } else {
        std::cout << "Successfully deleted security group " << securityGroupID <<
                  std::endl;
    }
```

See the [complete example](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/cpp/example_code/ec2/delete_security_group.cpp).

## More Information
<a name="more-information"></a>
+  [Amazon EC2 Security Groups](https://docs.amazonaws.cn/AWSEC2/latest/UserGuide/ec2-key-pairs.html) in the Amazon EC2 User Guide
+  [Authorizing Inbound Traffic for Your Linux Instances](https://docs.amazonaws.cn/AWSEC2/latest/UserGuide/authorizing-access-to-an-instance.html) in the Amazon EC2 User Guide
+  [CreateSecurityGroup](https://docs.amazonaws.cn/AWSEC2/latest/APIReference/API_CreateSecurityGroup.html) in the Amazon EC2 API Reference
+  [DescribeSecurityGroups](https://docs.amazonaws.cn/AWSEC2/latest/APIReference/API_DescribeSecurityGroups.html) in the Amazon EC2 API Reference
+  [DeleteSecurityGroup](https://docs.amazonaws.cn/AWSEC2/latest/APIReference/API_DeleteSecurityGroup.html) in the Amazon EC2 API Reference
+  [AuthorizeSecurityGroupIngress](https://docs.amazonaws.cn/AWSEC2/latest/APIReference/API_AuthorizeSecurityGroupIngress.html) in the Amazon EC2 API Reference

# Amazon S3 code examples using the Amazon SDK for C\$1\$1
<a name="examples-s3"></a>

[Amazon S3](http://www.amazonaws.cn/s3) is object storage built to store and retrieve any amount of data from anywhere. There are multiple classes provided by the Amazon SDK for C\$1\$1 to interface with Amazon S3. 

**Note**  
Only the code that is necessary to demonstrate certain techniques is supplied in this Guide, but the [complete example code is available on GitHub](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/cpp). On GitHub you can download a single source file or you can clone the repository locally to get, build, and run all examples.
+ [https://docs.amazonaws.cn/sdk-for-cpp/latest/api/aws-cpp-sdk-s3/html/class_aws_1_1_s3_1_1_s3_client.html](https://docs.amazonaws.cn/sdk-for-cpp/latest/api/aws-cpp-sdk-s3/html/class_aws_1_1_s3_1_1_s3_client.html) class 

  The `S3Client` library is a fully-featured Amazon S3 interface.

  The `list_buckets_disabling_dns_cache.cpp` example in this set is catered specifically to work with CURL on Linux/Mac (though can be modified to work on Windows). If you are on Windows, delete the file `list_buckets_disabling_dns_cache.cpp` before building the project because it relies on the curl HttpClient of Linux.

  The example code utilizing the `S3Client` is in the [`s3` folder](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/cpp/example_code/s3) on Github. See the [Readme](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/cpp/example_code/s3/README.md) on Github for a full list of functions demonstrated by this example set.

  Portions of the `s3` example set are covered in additional detail in this guide:
  + [Creating, listing, and deleting buckets](examples-s3-buckets.md)
  + [Operations on objects](examples-s3-objects.md) – Uploading and downloading data objects
  + [Managing Amazon S3 Access Permissions](examples-s3-access-permissions.md)
  + [Managing Access to Amazon S3 Buckets Using Bucket Policies](examples-s3-bucket-policies.md)
  + [Configuring an Amazon S3 Bucket as a Website](examples-s3-website-configuration.md)
+ [https://docs.amazonaws.cn/sdk-for-cpp/latest/api/aws-cpp-sdk-s3-crt/html/class_aws_1_1_s3_crt_1_1_s3_crt_client.html](https://docs.amazonaws.cn/sdk-for-cpp/latest/api/aws-cpp-sdk-s3-crt/html/class_aws_1_1_s3_crt_1_1_s3_crt_client.html) class 

  The `S3CrtClient` was added in version 1.9 of the SDK. `S3CrtClient` provides high throughput for Amazon S3 GET (download) and PUT (upload) operations. The `S3CrtClient` is implemented on the top of the Amazon Common Runtime (CRT) libraries. 

  The example code utilizing the `S3CrtClient` is in the [`s3-crt` folder](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/cpp/example_code/s3-crt) on Github. See the [Readme](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/cpp/example_code/s3-crt/README.md) on Github for a full list of functions demonstrated by this example set.
  + [Using `S3CrtClient` for Amazon S3 operations](examples-s3-crt.md)
+ [https://docs.amazonaws.cn/sdk-for-cpp/latest/api/aws-cpp-sdk-transfer/html/class_aws_1_1_transfer_1_1_transfer_manager.html](https://docs.amazonaws.cn/sdk-for-cpp/latest/api/aws-cpp-sdk-transfer/html/class_aws_1_1_transfer_1_1_transfer_manager.html) class 

  `TransferManager` is a fully managed service that enables the transfer of files over the File Transfer Protocol (FTP), File Transfer Protocol over SSL (FTPS), or Secure Shell (SSH) File Transfer Protocol (SFTP) directly into and out of Amazon S3.

  The example code utilizing the `TransferManager` is in the [`transfer-manager` folder](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/cpp/example_code/transfer-manager) on Github. See the [Readme](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/cpp/example_code/transfer-manager/README.md) on Github for a full list of functions demonstrated by this example set.
  + [Using TransferManager for Amazon S3 operations](examples-s3-transfermanager.md)

# Creating, listing, and deleting buckets
<a name="examples-s3-buckets"></a>

Every *object* or file in Amazon Simple Storage Service (Amazon S3) is contained in a *bucket*, which represents a folder of objects. Each bucket has a name that is globally unique within Amazon. For more information, see [Working with Amazon S3 Buckets](https://docs.amazonaws.cn/AmazonS3/latest/dev/UsingBucket.html) in the Amazon Simple Storage Service User Guide.

## Prerequisites
<a name="codeExamplePrereq"></a>

Before you begin, we recommend you read [Getting started using the Amazon SDK for C\$1\$1](getting-started.md). 

Download the example code and build the solution as described in [Getting started on code examples](getting-started-code-examples.md). 

To run the examples, the user profile your code uses to make the requests must have proper permissions in Amazon (for the service and the action). For more information, see [Providing Amazon credentials](credentials.md).

## List buckets
<a name="list-buckets"></a>

To run the `list_buckets` example, at a command prompt, navigate to the folder where your build system creates your build executables. Run the executable like `run_list_buckets` (your full executable filename will differ based on your operating system). The output lists your account's buckets if you have any, or it displays an empty list if you don't have any buckets.

In `list_buckets.cpp`, there are two methods.
+ `main()` calls `ListBuckets()`. 
+ `ListBuckets()` uses the SDK to query your buckets.

The `S3Client` object calls the SDK's `ListBuckets()` method. If successful, the method returns a `ListBucketOutcome` object, which contains a `ListBucketResult` object. The `ListBucketResult` object calls the `GetBuckets()` method to get a list of `Bucket` objects that contain information about each Amazon S3 bucket in your account.

 **Code** 

```
bool AwsDoc::S3::listBuckets(const Aws::S3::S3ClientConfiguration &clientConfig) {
    Aws::S3::S3Client client(clientConfig);

    auto outcome = client.ListBuckets();

    bool result = true;
    if (!outcome.IsSuccess()) {
        std::cerr << "Failed with error: " << outcome.GetError() << std::endl;
        result = false;
    } else {
        std::cout << "Found " << outcome.GetResult().GetBuckets().size() << " buckets\n";
        for (auto &&b: outcome.GetResult().GetBuckets()) {
            std::cout << b.GetName() << std::endl;
        }
    }

    return result;
}
```

See the complete [list\$1buckets example](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/cpp/example_code/s3/list_buckets.cpp) on Github.

## Create a bucket
<a name="create-bucket"></a>



To run the `create_bucket` example, at a command prompt, navigate to the folder where your build system creates your build executables. Run the executable like `run_create_bucket` (your full executable filename will differ based on your operating system). The code creates an empty bucket under your account and then displays the success or failure of the request.

In `create_bucket.cpp`, there are two methods. 
+ `main()` calls `CreateBucket()`. In `main()`, you need to change the Amazon Web Services Region to the Region of your account by using the `enum`. You can view the Region of your account by logging into the [Amazon Web Services Management Console](https://console.amazonaws.cn/), and locating the Region in the upper right-hand corner. 
+ `CreateBucket()` uses the SDK to create a bucket. 



The `S3Client` object calls the SDK's `CreateBucket()` method, passing in a `CreateBucketRequest` with the bucket’s name. By default, buckets are created in the *us-east-1* (N. Virginia) Region. If your Region is not *us-east-1* then the code sets up a bucket constraint to ensure the bucket is created in your Region.

 **Code** 

```
bool AwsDoc::S3::createBucket(const Aws::String &bucketName,
                              const Aws::S3::S3ClientConfiguration &clientConfig) {
    Aws::S3::S3Client client(clientConfig);
    Aws::S3::Model::CreateBucketRequest request;
    request.SetBucket(bucketName);

    if (clientConfig.region != "us-east-1") {
        Aws::S3::Model::CreateBucketConfiguration createBucketConfig;
        createBucketConfig.SetLocationConstraint(
                Aws::S3::Model::BucketLocationConstraintMapper::GetBucketLocationConstraintForName(
                        clientConfig.region));
        request.SetCreateBucketConfiguration(createBucketConfig);
    }

    Aws::S3::Model::CreateBucketOutcome outcome = client.CreateBucket(request);
    if (!outcome.IsSuccess()) {
        auto err = outcome.GetError();
        std::cerr << "Error: createBucket: " <<
                  err.GetExceptionName() << ": " << err.GetMessage() << std::endl;
    } else {
        std::cout << "Created bucket " << bucketName <<
                  " in the specified AWS Region." << std::endl;
    }

    return outcome.IsSuccess();
}
```

See the complete [create\$1buckets example](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/cpp/example_code/s3/create_bucket.cpp) on Github.

## Delete a bucket
<a name="delete-bucket"></a>



To run the `delete_bucket` example, at a command prompt, navigate to the folder where your build system creates your build executables. Run the executable like `run_delete_bucket` (your full executable filename will differ based on your operating system). The code deletes the specified bucket in your account and then displays the success or failure of the request.

In `delete_bucket.cpp` there are two methods. 
+ `main()` calls `DeleteBucket()`. In `main()`, you need to change the Amazon Web Services Region to the Region of your account by using the `enum`. You also need to change the `bucket_name` to the name of the bucket to delete. 
+ `DeleteBucket()` uses the SDK to delete the bucket. 



The `S3Client` object uses the SDK's `DeleteBucket()` method, passing in a `DeleteBucketRequest` object with the name of the bucket to delete. The bucket must be empty to be successful.

 **Code**

```
bool AwsDoc::S3::deleteBucket(const Aws::String &bucketName,
                              const Aws::S3::S3ClientConfiguration &clientConfig) {

    Aws::S3::S3Client client(clientConfig);

    Aws::S3::Model::DeleteBucketRequest request;
    request.SetBucket(bucketName);

    Aws::S3::Model::DeleteBucketOutcome outcome =
            client.DeleteBucket(request);

    if (!outcome.IsSuccess()) {
        const Aws::S3::S3Error &err = outcome.GetError();
        std::cerr << "Error: deleteBucket: " <<
                  err.GetExceptionName() << ": " << err.GetMessage() << std::endl;
    } else {
        std::cout << "The bucket was deleted" << std::endl;
    }

    return outcome.IsSuccess();
}
```

See the complete [delete\$1bucket example](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/cpp/example_code/s3/delete_bucket.cpp) on Github.

# Operations on objects
<a name="examples-s3-objects"></a>

An Amazon S3 object represents a *file*, which is a collection of data. Every object must reside within a [bucket](examples-s3-buckets.md).

## Prerequisites
<a name="codeExamplePrereq"></a>

Before you begin, we recommend you read [Getting started using the Amazon SDK for C\$1\$1](getting-started.md). 

Download the example code and build the solution as described in [Getting started on code examples](getting-started-code-examples.md). 

To run the examples, the user profile your code uses to make the requests must have proper permissions in Amazon (for the service and the action). For more information, see [Providing Amazon credentials](credentials.md).

## Upload a file to a bucket
<a name="upload-object"></a>

Use the `S3Client` object `PutObject` function, supplying it with a bucket name, key name, and file to upload. `Aws::FStream` is used to upload the contents of the local file to the bucket. The bucket must exist or an error will result.

For an example on uploading objects asynchronously, see [Asynchronous programming using the Amazon SDK for C\$1\$1](async-methods.md)

 **Code** 

```
bool AwsDoc::S3::putObject(const Aws::String &bucketName,
                           const Aws::String &fileName,
                           const Aws::S3::S3ClientConfiguration &clientConfig) {
    Aws::S3::S3Client s3Client(clientConfig);

    Aws::S3::Model::PutObjectRequest request;
    request.SetBucket(bucketName);
    //We are using the name of the file as the key for the object in the bucket.
    //However, this is just a string and can be set according to your retrieval needs.
    request.SetKey(fileName);

    std::shared_ptr<Aws::IOStream> inputData =
            Aws::MakeShared<Aws::FStream>("SampleAllocationTag",
                                          fileName.c_str(),
                                          std::ios_base::in | std::ios_base::binary);

    if (!*inputData) {
        std::cerr << "Error unable to read file " << fileName << std::endl;
        return false;
    }

    request.SetBody(inputData);

    Aws::S3::Model::PutObjectOutcome outcome =
            s3Client.PutObject(request);

    if (!outcome.IsSuccess()) {
        std::cerr << "Error: putObject: " <<
                  outcome.GetError().GetMessage() << std::endl;
    } else {
        std::cout << "Added object '" << fileName << "' to bucket '"
                  << bucketName << "'.";
    }

    return outcome.IsSuccess();
}
```

See the [complete example](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/cpp/example_code/s3/put_object.cpp) on Github.

## Upload a string to a bucket
<a name="upload-object-string"></a>

Use the `S3Client` object `PutObject` function, supplying it with a bucket name, key name, and file to upload. The bucket must exist or an error will result. This example differs from the previous one by using `Aws::StringStream` to upload an in-memory string data object directly to a bucket.

For an example on uploading objects asynchronously, see [Asynchronous programming using the Amazon SDK for C\$1\$1](async-methods.md)

 **Code** 

```
bool AwsDoc::S3::putObjectBuffer(const Aws::String &bucketName,
                                 const Aws::String &objectName,
                                 const std::string &objectContent,
                                 const Aws::S3::S3ClientConfiguration &clientConfig) {
    Aws::S3::S3Client s3Client(clientConfig);

    Aws::S3::Model::PutObjectRequest request;
    request.SetBucket(bucketName);
    request.SetKey(objectName);

    const std::shared_ptr<Aws::IOStream> inputData =
            Aws::MakeShared<Aws::StringStream>("");
    *inputData << objectContent.c_str();

    request.SetBody(inputData);

    Aws::S3::Model::PutObjectOutcome outcome = s3Client.PutObject(request);

    if (!outcome.IsSuccess()) {
        std::cerr << "Error: putObjectBuffer: " <<
                  outcome.GetError().GetMessage() << std::endl;
    } else {
        std::cout << "Success: Object '" << objectName << "' with content '"
                  << objectContent << "' uploaded to bucket '" << bucketName << "'.";
    }

    return outcome.IsSuccess();
}
```

See the [complete example](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/cpp/example_code/s3/put_object_buffer.cpp) on Github.

## List objects
<a name="list-objects"></a>

To get a list of objects within a bucket, use the `S3Client` object `ListObjects` function. Supply it with a `ListObjectsRequest` that you set with the name of a bucket to list the contents of.

The `ListObjects` function returns a `ListObjectsOutcome` object that you can use to get a list of objects in the form of `Object` instances.

 **Code** 

```
bool AwsDoc::S3::listObjects(const Aws::String &bucketName,
                             Aws::Vector<Aws::String> &keysResult,
                             const Aws::S3::S3ClientConfiguration &clientConfig) {
    Aws::S3::S3Client s3Client(clientConfig);

    Aws::S3::Model::ListObjectsV2Request request;
    request.WithBucket(bucketName);

    Aws::String continuationToken; // Used for pagination.
    Aws::Vector<Aws::S3::Model::Object> allObjects;

    do {
        if (!continuationToken.empty()) {
            request.SetContinuationToken(continuationToken);
        }

        auto outcome = s3Client.ListObjectsV2(request);

        if (!outcome.IsSuccess()) {
            std::cerr << "Error: listObjects: " <<
                      outcome.GetError().GetMessage() << std::endl;
            return false;
        } else {
            Aws::Vector<Aws::S3::Model::Object> objects =
                    outcome.GetResult().GetContents();

            allObjects.insert(allObjects.end(), objects.begin(), objects.end());
            continuationToken = outcome.GetResult().GetNextContinuationToken();
        }
    } while (!continuationToken.empty());

    std::cout << allObjects.size() << " object(s) found:" << std::endl;

    for (const auto &object: allObjects) {
        std::cout << "  " << object.GetKey() << std::endl;
        keysResult.push_back(object.GetKey());
    }

    return true;
}
```

See the [complete example](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/cpp/example_code/s3/list_objects.cpp) on Github.

## Download an object
<a name="download-object"></a>

Use the `S3Client` object `GetObject` function, passing it a `GetObjectRequest` that you set with the name of a bucket and the object key to download. `GetObject` returns a [https://docs.amazonaws.cn/sdk-for-cpp/latest/api/aws-cpp-sdk-s3/html/namespace_aws_1_1_s3_1_1_model.html#a6e16a7b25e8c7547934968a538a15272](https://docs.amazonaws.cn/sdk-for-cpp/latest/api/aws-cpp-sdk-s3/html/namespace_aws_1_1_s3_1_1_model.html#a6e16a7b25e8c7547934968a538a15272) object that consists of a [https://docs.amazonaws.cn/sdk-for-cpp/latest/api/aws-cpp-sdk-s3/html/class_aws_1_1_s3_1_1_model_1_1_get_object_result.html](https://docs.amazonaws.cn/sdk-for-cpp/latest/api/aws-cpp-sdk-s3/html/class_aws_1_1_s3_1_1_model_1_1_get_object_result.html) and a [https://docs.amazonaws.cn/sdk-for-cpp/latest/api/aws-cpp-sdk-s3/html/class_aws_1_1_s3_1_1_s3_error.html](https://docs.amazonaws.cn/sdk-for-cpp/latest/api/aws-cpp-sdk-s3/html/class_aws_1_1_s3_1_1_s3_error.html). `GetObjectResult` can be used to access the S3 object’s data.

The following example downloads an object from Amazon S3. The object contents are stored in a local variable and the first line of the contents is output to the console.

 **Code** 

```
bool AwsDoc::S3::getObject(const Aws::String &objectKey,
                           const Aws::String &fromBucket,
                           const Aws::S3::S3ClientConfiguration &clientConfig) {
    Aws::S3::S3Client client(clientConfig);

    Aws::S3::Model::GetObjectRequest request;
    request.SetBucket(fromBucket);
    request.SetKey(objectKey);

    Aws::S3::Model::GetObjectOutcome outcome =
            client.GetObject(request);

    if (!outcome.IsSuccess()) {
        const Aws::S3::S3Error &err = outcome.GetError();
        std::cerr << "Error: getObject: " <<
                  err.GetExceptionName() << ": " << err.GetMessage() << std::endl;
    } else {
        std::cout << "Successfully retrieved '" << objectKey << "' from '"
                  << fromBucket << "'." << std::endl;
    }

    return outcome.IsSuccess();
}
```

See the [complete example](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/cpp/example_code/s3/get_object.cpp) on Github.

## Delete an object
<a name="delete-object"></a>

Use the `S3Client` object’s `DeleteObject` function, passing it a `DeleteObjectRequest` that you set with the name of a bucket and object to download. *The specified bucket and object key must exist or an error will result*.

 **Code** 

```
bool AwsDoc::S3::deleteObject(const Aws::String &objectKey,
                              const Aws::String &fromBucket,
                              const Aws::S3::S3ClientConfiguration &clientConfig) {
    Aws::S3::S3Client client(clientConfig);
    Aws::S3::Model::DeleteObjectRequest request;

    request.WithKey(objectKey)
            .WithBucket(fromBucket);

    Aws::S3::Model::DeleteObjectOutcome outcome =
            client.DeleteObject(request);

    if (!outcome.IsSuccess()) {
        auto err = outcome.GetError();
        std::cerr << "Error: deleteObject: " <<
                  err.GetExceptionName() << ": " << err.GetMessage() << std::endl;
    } else {
        std::cout << "Successfully deleted the object." << std::endl;
    }

    return outcome.IsSuccess();
}
```

See the [complete example](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/cpp/example_code/s3/delete_object.cpp) on Github.

# Managing Amazon S3 Access Permissions
<a name="examples-s3-access-permissions"></a>

Access permissions for an Amazon S3 bucket or object are defined in an access control list (ACL). The ACL specifies the owner of the bucket/object and a list of grants. Each grant specifies a user (or grantee) and the user’s permissions to access the bucket/object, such as READ or WRITE access.

## Prerequisites
<a name="codeExamplePrereq"></a>

Before you begin, we recommend you read [Getting started using the Amazon SDK for C\$1\$1](getting-started.md). 

Download the example code and build the solution as described in [Getting started on code examples](getting-started-code-examples.md). 

To run the examples, the user profile your code uses to make the requests must have proper permissions in Amazon (for the service and the action). For more information, see [Providing Amazon credentials](credentials.md).

## Manage an Object’s Access Control List
<a name="manage-an-object-s-access-control-list"></a>

The access control list for an object can be retrieved by calling the `S3Client` method `GetObjectAcl`. The method accepts the names of the object and its bucket. The return value includes the ACL’s `Owner` and list of `Grants`.

```
bool AwsDoc::S3::getObjectAcl(const Aws::String &bucketName,
                              const Aws::String &objectKey,
                              const Aws::S3::S3ClientConfiguration &clientConfig) {
    Aws::S3::S3Client s3Client(clientConfig);

    Aws::S3::Model::GetObjectAclRequest request;
    request.SetBucket(bucketName);
    request.SetKey(objectKey);

    Aws::S3::Model::GetObjectAclOutcome outcome =
            s3Client.GetObjectAcl(request);

    if (!outcome.IsSuccess()) {
        const Aws::S3::S3Error &err = outcome.GetError();
        std::cerr << "Error: getObjectAcl: "
                  << err.GetExceptionName() << ": " << err.GetMessage() << std::endl;
    } else {
        Aws::Vector<Aws::S3::Model::Grant> grants =
                outcome.GetResult().GetGrants();

        for (auto it = grants.begin(); it != grants.end(); it++) {
            std::cout << "For object " << objectKey << ": "
                      << std::endl << std::endl;

            Aws::S3::Model::Grant grant = *it;
            Aws::S3::Model::Grantee grantee = grant.GetGrantee();

            if (grantee.TypeHasBeenSet()) {
                std::cout << "Type:          "
                          << getGranteeTypeString(grantee.GetType()) << std::endl;
            }

            if (grantee.DisplayNameHasBeenSet()) {
                std::cout << "Display name:  "
                          << grantee.GetDisplayName() << std::endl;
            }

            if (grantee.EmailAddressHasBeenSet()) {
                std::cout << "Email address: "
                          << grantee.GetEmailAddress() << std::endl;
            }

            if (grantee.IDHasBeenSet()) {
                std::cout << "ID:            "
                          << grantee.GetID() << std::endl;
            }

            if (grantee.URIHasBeenSet()) {
                std::cout << "URI:           "
                          << grantee.GetURI() << std::endl;
            }

            std::cout << "Permission:    " <<
                      getPermissionString(grant.GetPermission()) <<
                      std::endl << std::endl;
        }
    }

    return outcome.IsSuccess();
}

//! Routine which converts a built-in type enumeration to a human-readable string.
/*!
 \param type: Type enumeration.
 \return String: Human-readable string
*/
Aws::String getGranteeTypeString(const Aws::S3::Model::Type &type) {
    switch (type) {
        case Aws::S3::Model::Type::AmazonCustomerByEmail:
            return "Email address of an AWS account";
        case Aws::S3::Model::Type::CanonicalUser:
            return "Canonical user ID of an AWS account";
        case Aws::S3::Model::Type::Group:
            return "Predefined Amazon S3 group";
        case Aws::S3::Model::Type::NOT_SET:
            return "Not set";
        default:
            return "Type unknown";
    }
}

//! Routine which converts a built-in type enumeration to a human-readable string.
/*!
 \param permission: Permission enumeration.
 \return String: Human-readable string
*/
Aws::String getPermissionString(const Aws::S3::Model::Permission &permission) {
    switch (permission) {
        case Aws::S3::Model::Permission::FULL_CONTROL:
            return "Can read this object's data and its metadata, "
                   "and read/write this object's permissions";
        case Aws::S3::Model::Permission::NOT_SET:
            return "Permission not set";
        case Aws::S3::Model::Permission::READ:
            return "Can read this object's data and its metadata";
        case Aws::S3::Model::Permission::READ_ACP:
            return "Can read this object's permissions";
            // case Aws::S3::Model::Permission::WRITE // Not applicable.
        case Aws::S3::Model::Permission::WRITE_ACP:
            return "Can write this object's permissions";
        default:
            return "Permission unknown";
    }
}
```

The ACL can be modified by either creating a new ACL or changing the grants specified in the current ACL. The updated ACL becomes the new current ACL by passing it to the `PutObjectAcl` method.

The following code uses the ACL retrieved by `GetObjectAcl` and adds a new grant to it. The user or grantee is given READ permission for the object. The modified ACL is passed to `PutObjectAcl`, making it the new current ACL. 

```
bool AwsDoc::S3::putObjectAcl(const Aws::String &bucketName, const Aws::String &objectKey, const Aws::String &ownerID,
                              const Aws::String &granteePermission, const Aws::String &granteeType,
                              const Aws::String &granteeID, const Aws::String &granteeEmailAddress,
                              const Aws::String &granteeURI, const Aws::S3::S3ClientConfiguration &clientConfig) {
    Aws::S3::S3Client s3Client(clientConfig);

    Aws::S3::Model::Owner owner;
    owner.SetID(ownerID);

    Aws::S3::Model::Grantee grantee;
    grantee.SetType(setGranteeType(granteeType));

    if (!granteeEmailAddress.empty()) {
        grantee.SetEmailAddress(granteeEmailAddress);
    }

    if (!granteeID.empty()) {
        grantee.SetID(granteeID);
    }

    if (!granteeURI.empty()) {
        grantee.SetURI(granteeURI);
    }

    Aws::S3::Model::Grant grant;
    grant.SetGrantee(grantee);
    grant.SetPermission(setGranteePermission(granteePermission));

    Aws::Vector<Aws::S3::Model::Grant> grants;
    grants.push_back(grant);

    Aws::S3::Model::AccessControlPolicy acp;
    acp.SetOwner(owner);
    acp.SetGrants(grants);

    Aws::S3::Model::PutObjectAclRequest request;
    request.SetAccessControlPolicy(acp);
    request.SetBucket(bucketName);
    request.SetKey(objectKey);

    Aws::S3::Model::PutObjectAclOutcome outcome =
            s3Client.PutObjectAcl(request);

    if (!outcome.IsSuccess()) {
        auto error = outcome.GetError();
        std::cerr << "Error: putObjectAcl: " << error.GetExceptionName()
                  << " - " << error.GetMessage() << std::endl;
    } else {
        std::cout << "Successfully added an ACL to the object '" << objectKey
                  << "' in the bucket '" << bucketName << "'." << std::endl;
    }

    return outcome.IsSuccess();
}

//! Routine which converts a human-readable string to a built-in type enumeration.
/*!
 \param access: Human readable string.
 \return Permission: Permission enumeration.
*/
Aws::S3::Model::Permission setGranteePermission(const Aws::String &access) {
    if (access == "FULL_CONTROL")
        return Aws::S3::Model::Permission::FULL_CONTROL;
    if (access == "WRITE")
        return Aws::S3::Model::Permission::WRITE;
    if (access == "READ")
        return Aws::S3::Model::Permission::READ;
    if (access == "WRITE_ACP")
        return Aws::S3::Model::Permission::WRITE_ACP;
    if (access == "READ_ACP")
        return Aws::S3::Model::Permission::READ_ACP;
    return Aws::S3::Model::Permission::NOT_SET;
}

//! Routine which converts a human-readable string to a built-in type enumeration.
/*!
 \param type: Human readable string.
 \return Type: Type enumeration.
*/
Aws::S3::Model::Type setGranteeType(const Aws::String &type) {
    if (type == "Amazon customer by email")
        return Aws::S3::Model::Type::AmazonCustomerByEmail;
    if (type == "Canonical user")
        return Aws::S3::Model::Type::CanonicalUser;
    if (type == "Group")
        return Aws::S3::Model::Type::Group;
    return Aws::S3::Model::Type::NOT_SET;
}
```

See the [complete example](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/cpp/example_code/s3/get_put_object_acl.cpp) on Github.

## Manage a Bucket’s Access Control List
<a name="manage-a-bucket-s-access-control-list"></a>

In most cases, the preferred method for setting the access permissions of a bucket is to define a bucket policy. However, buckets also support access control lists for users who wish to use them.

Management of an access control list for a bucket is identical to that used for an object. The `GetBucketAcl` method retrieves a bucket’s current ACL and `PutBucketAcl` applies a new ACL to the bucket.

The following code demonstrates getting and setting a bucket ACL.

```
//! Routine which demonstrates setting the ACL for an S3 bucket.
/*!
  \param bucketName: Name of a bucket.
  \param ownerID: The canonical ID of the bucket owner.
   See https://docs.aws.amazon.com/AmazonS3/latest/userguide/finding-canonical-user-id.html for more information.
  \param granteePermission: The access level to enable for the grantee.
  \param granteeType: The type of grantee.
  \param granteeID: The canonical ID of the grantee.
  \param granteeEmailAddress: The email address associated with the grantee's AWS account.
  \param granteeURI: The URI of a built-in access group.
  \param clientConfig: Aws client configuration.
  \return bool: Function succeeded.
*/

bool AwsDoc::S3::getPutBucketAcl(const Aws::String &bucketName,
                                 const Aws::String &ownerID,
                                 const Aws::String &granteePermission,
                                 const Aws::String &granteeType,
                                 const Aws::String &granteeID,
                                 const Aws::String &granteeEmailAddress,
                                 const Aws::String &granteeURI,
                                 const Aws::S3::S3ClientConfiguration &clientConfig) {
    bool result = ::putBucketAcl(bucketName, ownerID, granteePermission, granteeType,
                                 granteeID,
                                 granteeEmailAddress,
                                 granteeURI,
                                 clientConfig);
    if (result) {
        result = ::getBucketAcl(bucketName, clientConfig);
    }

    return result;
}

//! Routine which demonstrates setting the ACL for an S3 bucket.
/*!
  \param bucketName: Name of from bucket.
  \param ownerID: The canonical ID of the bucket owner.
   See https://docs.aws.amazon.com/AmazonS3/latest/userguide/finding-canonical-user-id.html for more information.
  \param granteePermission: The access level to enable for the grantee.
  \param granteeType: The type of grantee.
  \param granteeID: The canonical ID of the grantee.
  \param granteeEmailAddress: The email address associated with the grantee's AWS account.
  \param granteeURI: The URI of a built-in access group.
  \param clientConfig: Aws client configuration.
  \return bool: Function succeeded.
*/

bool putBucketAcl(const Aws::String &bucketName,
                  const Aws::String &ownerID,
                  const Aws::String &granteePermission,
                  const Aws::String &granteeType,
                  const Aws::String &granteeID,
                  const Aws::String &granteeEmailAddress,
                  const Aws::String &granteeURI,
                  const Aws::S3::S3ClientConfiguration &clientConfig) {
    Aws::S3::S3Client s3Client(clientConfig);

    Aws::S3::Model::Owner owner;
    owner.SetID(ownerID);

    Aws::S3::Model::Grantee grantee;
    grantee.SetType(setGranteeType(granteeType));

    if (!granteeEmailAddress.empty()) {
        grantee.SetEmailAddress(granteeEmailAddress);
    }

    if (!granteeID.empty()) {
        grantee.SetID(granteeID);
    }

    if (!granteeURI.empty()) {
        grantee.SetURI(granteeURI);
    }

    Aws::S3::Model::Grant grant;
    grant.SetGrantee(grantee);
    grant.SetPermission(setGranteePermission(granteePermission));

    Aws::Vector<Aws::S3::Model::Grant> grants;
    grants.push_back(grant);

    Aws::S3::Model::AccessControlPolicy acp;
    acp.SetOwner(owner);
    acp.SetGrants(grants);

    Aws::S3::Model::PutBucketAclRequest request;
    request.SetAccessControlPolicy(acp);
    request.SetBucket(bucketName);

    Aws::S3::Model::PutBucketAclOutcome outcome =
            s3Client.PutBucketAcl(request);

    if (!outcome.IsSuccess()) {
        const Aws::S3::S3Error &error = outcome.GetError();

        std::cerr << "Error: putBucketAcl: " << error.GetExceptionName()
                  << " - " << error.GetMessage() << std::endl;
    } else {
        std::cout << "Successfully added an ACL to the bucket '" << bucketName
                  << "'." << std::endl;
    }

    return outcome.IsSuccess();
}

//! Routine which demonstrates getting the ACL for an S3 bucket.
/*!
  \param bucketName: Name of the s3 bucket.
  \param clientConfig: Aws client configuration.
  \return bool: Function succeeded.
*/
bool getBucketAcl(const Aws::String &bucketName,
                  const Aws::S3::S3ClientConfiguration &clientConfig) {
    Aws::S3::S3Client s3Client(clientConfig);

    Aws::S3::Model::GetBucketAclRequest request;
    request.SetBucket(bucketName);

    Aws::S3::Model::GetBucketAclOutcome outcome =
            s3Client.GetBucketAcl(request);

    if (!outcome.IsSuccess()) {
        const Aws::S3::S3Error &err = outcome.GetError();
        std::cerr << "Error: getBucketAcl: "
                  << err.GetExceptionName() << ": " << err.GetMessage() << std::endl;
    } else {
        const Aws::Vector<Aws::S3::Model::Grant> &grants =
                outcome.GetResult().GetGrants();

        for (const Aws::S3::Model::Grant &grant: grants) {
            const Aws::S3::Model::Grantee &grantee = grant.GetGrantee();

            std::cout << "For bucket " << bucketName << ": "
                      << std::endl << std::endl;

            if (grantee.TypeHasBeenSet()) {
                std::cout << "Type:          "
                          << getGranteeTypeString(grantee.GetType()) << std::endl;
            }

            if (grantee.DisplayNameHasBeenSet()) {
                std::cout << "Display name:  "
                          << grantee.GetDisplayName() << std::endl;
            }

            if (grantee.EmailAddressHasBeenSet()) {
                std::cout << "Email address: "
                          << grantee.GetEmailAddress() << std::endl;
            }

            if (grantee.IDHasBeenSet()) {
                std::cout << "ID:            "
                          << grantee.GetID() << std::endl;
            }

            if (grantee.URIHasBeenSet()) {
                std::cout << "URI:           "
                          << grantee.GetURI() << std::endl;
            }

            std::cout << "Permission:    " <<
                      getPermissionString(grant.GetPermission()) <<
                      std::endl << std::endl;
        }
    }

    return outcome.IsSuccess();
}

//! Routine which converts a built-in type enumeration to a human-readable string.
/*!
 \param permission: Permission enumeration.
 \return String: Human-readable string.
*/

Aws::String getPermissionString(const Aws::S3::Model::Permission &permission) {
    switch (permission) {
        case Aws::S3::Model::Permission::FULL_CONTROL:
            return "Can list objects in this bucket, create/overwrite/delete "
                   "objects in this bucket, and read/write this "
                   "bucket's permissions";
        case Aws::S3::Model::Permission::NOT_SET:
            return "Permission not set";
        case Aws::S3::Model::Permission::READ:
            return "Can list objects in this bucket";
        case Aws::S3::Model::Permission::READ_ACP:
            return "Can read this bucket's permissions";
        case Aws::S3::Model::Permission::WRITE:
            return "Can create, overwrite, and delete objects in this bucket";
        case Aws::S3::Model::Permission::WRITE_ACP:
            return "Can write this bucket's permissions";
        default:
            return "Permission unknown";
    }
}

//! Routine which converts a human-readable string to a built-in type enumeration
/*!
 \param access: Human readable string.
 \return Permission: Permission enumeration.
*/
Aws::S3::Model::Permission setGranteePermission(const Aws::String &access) {
    if (access == "FULL_CONTROL")
        return Aws::S3::Model::Permission::FULL_CONTROL;
    if (access == "WRITE")
        return Aws::S3::Model::Permission::WRITE;
    if (access == "READ")
        return Aws::S3::Model::Permission::READ;
    if (access == "WRITE_ACP")
        return Aws::S3::Model::Permission::WRITE_ACP;
    if (access == "READ_ACP")
        return Aws::S3::Model::Permission::READ_ACP;
    return Aws::S3::Model::Permission::NOT_SET;
}

//! Routine which converts a built-in type enumeration to a human-readable string.
/*!
 \param type: Type enumeration.
 \return bool: Human-readable string.
*/
Aws::String getGranteeTypeString(const Aws::S3::Model::Type &type) {
    switch (type) {
        case Aws::S3::Model::Type::AmazonCustomerByEmail:
            return "Email address of an AWS account";
        case Aws::S3::Model::Type::CanonicalUser:
            return "Canonical user ID of an AWS account";
        case Aws::S3::Model::Type::Group:
            return "Predefined Amazon S3 group";
        case Aws::S3::Model::Type::NOT_SET:
            return "Not set";
        default:
            return "Type unknown";
    }
}

Aws::S3::Model::Type setGranteeType(const Aws::String &type) {
    if (type == "Amazon customer by email")
        return Aws::S3::Model::Type::AmazonCustomerByEmail;
    if (type == "Canonical user")
        return Aws::S3::Model::Type::CanonicalUser;
    if (type == "Group")
        return Aws::S3::Model::Type::Group;
    return Aws::S3::Model::Type::NOT_SET;
}
```

See the [complete example](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/cpp/example_code/s3/get_put_bucket_acl.cpp) on Github.

# Managing Access to Amazon S3 Buckets Using Bucket Policies
<a name="examples-s3-bucket-policies"></a>

You can set, get, or delete a *bucket policy* to manage access to your Amazon S3 buckets.

## Prerequisites
<a name="codeExamplePrereq"></a>

Before you begin, we recommend you read [Getting started using the Amazon SDK for C\$1\$1](getting-started.md). 

Download the example code and build the solution as described in [Getting started on code examples](getting-started-code-examples.md). 

To run the examples, the user profile your code uses to make the requests must have proper permissions in Amazon (for the service and the action). For more information, see [Providing Amazon credentials](credentials.md).

## Set a Bucket Policy
<a name="set-s3-bucket-policy"></a>

You can set the bucket policy for a particular S3 bucket by calling the `S3Client`’s `PutBucketPolicy` function and providing it with the bucket name and policy’s JSON representation in a [PutBucketPolicyRequest](https://docs.amazonaws.cn/sdk-for-cpp/latest/api/aws-cpp-sdk-s3/html/class_aws_1_1_s3_1_1_model_1_1_put_bucket_policy_request.html).

 **Code** 

```
//! Build a policy JSON string.
/*!
  \param userArn: Aws user Amazon Resource Name (ARN).
      For more information, see https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_identifiers.html#identifiers-arns.
  \param bucketName: Name of a bucket.
  \return String: Policy as JSON string.
*/

Aws::String getPolicyString(const Aws::String &userArn,
                            const Aws::String &bucketName) {
    return
            "{\n"
            "   \"Version\":\"2012-10-17\",\n"
            "   \"Statement\":[\n"
            "       {\n"
            "           \"Sid\": \"1\",\n"
            "           \"Effect\": \"Allow\",\n"
            "           \"Principal\": {\n"
            "               \"AWS\": \""
            + userArn +
            "\"\n""           },\n"
            "           \"Action\": [ \"s3:getObject\" ],\n"
            "           \"Resource\": [ \"arn:aws:s3:::"
            + bucketName +
            "/*\" ]\n"
            "       }\n"
            "   ]\n"
            "}";
}
```

```
bool AwsDoc::S3::putBucketPolicy(const Aws::String &bucketName,
                                 const Aws::String &policyBody,
                                 const Aws::S3::S3ClientConfiguration &clientConfig) {
    Aws::S3::S3Client s3Client(clientConfig);

    std::shared_ptr<Aws::StringStream> request_body =
            Aws::MakeShared<Aws::StringStream>("");
    *request_body << policyBody;

    Aws::S3::Model::PutBucketPolicyRequest request;
    request.SetBucket(bucketName);
    request.SetBody(request_body);

    Aws::S3::Model::PutBucketPolicyOutcome outcome =
            s3Client.PutBucketPolicy(request);

    if (!outcome.IsSuccess()) {
        std::cerr << "Error: putBucketPolicy: "
                  << outcome.GetError().GetMessage() << std::endl;
    } else {
        std::cout << "Set the following policy body for the bucket '" <<
                  bucketName << "':" << std::endl << std::endl;
        std::cout << policyBody << std::endl;
    }

    return outcome.IsSuccess();
}
```

**Note**  
The [Aws::Utils::Json::JsonValue](https://docs.amazonaws.cn/sdk-for-cpp/latest/api/aws-cpp-sdk-core/html/class_aws_1_1_utils_1_1_json_1_1_json_value.html) utility class can be used to help you construct valid JSON objects to pass to `PutBucketPolicy`.

See the [complete example](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/cpp/example_code/s3/put_bucket_policy.cpp) on Github.

## Get a Bucket Policy
<a name="get-s3-bucket-policy"></a>

To retrieve the policy for an Amazon S3 bucket, call the `S3Client`’s `GetBucketPolicy` function, passing it the name of the bucket in a [GetBucketPolicyRequest](https://docs.amazonaws.cn/sdk-for-cpp/latest/api/aws-cpp-sdk-s3/html/class_aws_1_1_s3_1_1_model_1_1_get_bucket_policy_request.html).

 **Code** 

```
bool AwsDoc::S3::getBucketPolicy(const Aws::String &bucketName,
                                 const Aws::S3::S3ClientConfiguration &clientConfig) {
    Aws::S3::S3Client s3Client(clientConfig);

    Aws::S3::Model::GetBucketPolicyRequest request;
    request.SetBucket(bucketName);

    Aws::S3::Model::GetBucketPolicyOutcome outcome =
            s3Client.GetBucketPolicy(request);

    if (!outcome.IsSuccess()) {
        const Aws::S3::S3Error &err = outcome.GetError();
        std::cerr << "Error: getBucketPolicy: "
                  << err.GetExceptionName() << ": " << err.GetMessage() << std::endl;
    } else {
        Aws::StringStream policy_stream;
        Aws::String line;

        outcome.GetResult().GetPolicy() >> line;
        policy_stream << line;

        std::cout << "Retrieve the policy for bucket '" << bucketName << "':\n\n" <<
                  policy_stream.str() << std::endl;
    }

    return outcome.IsSuccess();
}
```

See the [complete example](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/cpp/example_code/s3/get_bucket_policy.cpp) on Github.

## Delete a Bucket Policy
<a name="delete-s3-bucket-policy"></a>

To delete a bucket policy, call the `S3Client`’s `DeleteBucketPolicy` function, providing it with the bucket name in a [DeleteBucketPolicyRequest](https://docs.amazonaws.cn/sdk-for-cpp/latest/api/aws-cpp-sdk-s3/html/class_aws_1_1_s3_1_1_model_1_1_delete_bucket_policy_request.html).

 **Code** 

```
bool AwsDoc::S3::deleteBucketPolicy(const Aws::String &bucketName,
                                    const Aws::S3::S3ClientConfiguration &clientConfig) {
    Aws::S3::S3Client client(clientConfig);

    Aws::S3::Model::DeleteBucketPolicyRequest request;
    request.SetBucket(bucketName);

    Aws::S3::Model::DeleteBucketPolicyOutcome outcome = client.DeleteBucketPolicy(request);

    if (!outcome.IsSuccess()) {
        const Aws::S3::S3Error &err = outcome.GetError();
        std::cerr << "Error: deleteBucketPolicy: " <<
                  err.GetExceptionName() << ": " << err.GetMessage() << std::endl;
    } else {
        std::cout << "Policy was deleted from the bucket." << std::endl;
    }

    return outcome.IsSuccess();
}
```

This function succeeds even if the bucket doesn’t already have a policy. If you specify a bucket name that doesn’t exist or if you don’t have access to the bucket, an `AmazonServiceException` is thrown.

See the [complete example](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/cpp/example_code/s3/delete_bucket_policy.cpp) on Github.

## More Info
<a name="more-info"></a>
+  [PutBucketPolicy](https://docs.amazonaws.cn/AmazonS3/latest/API/PutBucketPolicy.html) in the Amazon Simple Storage Service API Reference
+  [GetBucketPolicy](https://docs.amazonaws.cn/AmazonS3/latest/API/GetBucketPolicy.html) in the Amazon Simple Storage Service API Reference
+  [DeleteBucketPolicy](https://docs.amazonaws.cn/AmazonS3/latest/API/DeleteBucketPolicy.html) in the Amazon Simple Storage Service API Reference
+  [Access Policy Language Overview](https://docs.amazonaws.cn/AmazonS3/latest/dev/access-policy-language-overview.html) in the Amazon Simple Storage Service User Guide
+  [Bucket Policy Examples](https://docs.amazonaws.cn/AmazonS3/latest/dev/example-bucket-policies.html) in the Amazon Simple Storage Service User Guide

# Configuring an Amazon S3 Bucket as a Website
<a name="examples-s3-website-configuration"></a>

You can configure an Amazon S3 bucket to behave as a website. To do this, you need to set its website configuration.

## Prerequisites
<a name="codeExamplePrereq"></a>

Before you begin, we recommend you read [Getting started using the Amazon SDK for C\$1\$1](getting-started.md). 

Download the example code and build the solution as described in [Getting started on code examples](getting-started-code-examples.md). 

To run the examples, the user profile your code uses to make the requests must have proper permissions in Amazon (for the service and the action). For more information, see [Providing Amazon credentials](credentials.md).

## Set a Bucket’s Website Configuration
<a name="set-a-bucket-s-website-configuration"></a>

To set an Amazon S3 bucket’s website configuration, call the `S3Client`’s `PutBucketWebsite` function with a [PutBucketWebsiteRequest](https://docs.amazonaws.cn/sdk-for-cpp/latest/api/aws-cpp-sdk-s3/html/class_aws_1_1_s3_1_1_model_1_1_put_bucket_website_request.html) object containing the bucket name and its website configuration, provided in a [WebsiteConfiguration](https://docs.amazonaws.cn/sdk-for-cpp/latest/api/aws-cpp-sdk-s3/html/class_aws_1_1_s3_1_1_model_1_1_website_configuration.html) object.

Setting an index document is *required*; all other parameters are optional.

 **Code** 

```
bool AwsDoc::S3::putWebsiteConfig(const Aws::String &bucketName,
                                  const Aws::String &indexPage, const Aws::String &errorPage,
                                  const Aws::S3::S3ClientConfiguration &clientConfig) {
    Aws::S3::S3Client client(clientConfig);

    Aws::S3::Model::IndexDocument indexDocument;
    indexDocument.SetSuffix(indexPage);

    Aws::S3::Model::ErrorDocument errorDocument;
    errorDocument.SetKey(errorPage);

    Aws::S3::Model::WebsiteConfiguration websiteConfiguration;
    websiteConfiguration.SetIndexDocument(indexDocument);
    websiteConfiguration.SetErrorDocument(errorDocument);

    Aws::S3::Model::PutBucketWebsiteRequest request;
    request.SetBucket(bucketName);
    request.SetWebsiteConfiguration(websiteConfiguration);

    Aws::S3::Model::PutBucketWebsiteOutcome outcome =
            client.PutBucketWebsite(request);

    if (!outcome.IsSuccess()) {
        std::cerr << "Error: PutBucketWebsite: "
                  << outcome.GetError().GetMessage() << std::endl;
    } else {
        std::cout << "Success: Set website configuration for bucket '"
                  << bucketName << "'." << std::endl;
    }

    return outcome.IsSuccess();
}
```

**Note**  
Setting a website configuration does not modify the access permissions for your bucket. To make your files visible on the web, you will also need to set a *bucket policy* that allows public read access to the files in the bucket. For more information, see [Managing Access to Amazon S3 Buckets Using Bucket Policies](examples-s3-bucket-policies.md).

See the [complete example](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/cpp/example_code/s3/put_website_config.cpp) on Github.

## Get a Bucket’s Website Configuration
<a name="get-a-bucket-s-website-configuration"></a>

To get an Amazon S3 bucket’s website configuration, call the `S3Client`’s `GetBucketWebsite` function with a [GetBucketWebsiteRequest](https://docs.amazonaws.cn/sdk-for-cpp/latest/api/aws-cpp-sdk-s3/html/class_aws_1_1_s3_1_1_model_1_1_get_bucket_website_request.html) containing the name of the bucket to retrieve the configuration for.

The configuration will be returned as a [GetBucketWebsiteResult](https://docs.amazonaws.cn/sdk-for-cpp/latest/api/aws-cpp-sdk-s3/html/class_aws_1_1_s3_1_1_model_1_1_get_bucket_website_result.html) object within the outcome object. If there is no website configuration for the bucket, then `null` will be returned.

 **Code** 

```
bool AwsDoc::S3::getWebsiteConfig(const Aws::String &bucketName,
                                  const Aws::S3::S3ClientConfiguration &clientConfig) {
    Aws::S3::S3Client s3Client(clientConfig);

    Aws::S3::Model::GetBucketWebsiteRequest request;
    request.SetBucket(bucketName);

    Aws::S3::Model::GetBucketWebsiteOutcome outcome =
            s3Client.GetBucketWebsite(request);

    if (!outcome.IsSuccess()) {
        const Aws::S3::S3Error &err = outcome.GetError();

        std::cerr << "Error: GetBucketWebsite: "
                  << err.GetMessage() << std::endl;
    } else {
        Aws::S3::Model::GetBucketWebsiteResult websiteResult = outcome.GetResult();

        std::cout << "Success: GetBucketWebsite: "
                  << std::endl << std::endl
                  << "For bucket '" << bucketName << "':"
                  << std::endl
                  << "Index page : "
                  << websiteResult.GetIndexDocument().GetSuffix()
                  << std::endl
                  << "Error page: "
                  << websiteResult.GetErrorDocument().GetKey()
                  << std::endl;
    }

    return outcome.IsSuccess();
}
```

See the [complete example](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/cpp/example_code/s3/get_website_config.cpp) on Github.

## Delete a Bucket’s Website Configuration
<a name="delete-a-bucket-s-website-configuration"></a>

To delete an Amazon S3 bucket’s website configuration, call the `S3Client`’s `DeleteBucketWebsite` function with a [DeleteBucketWebsiteRequest](https://docs.amazonaws.cn/sdk-for-cpp/latest/api/aws-cpp-sdk-s3/html/class_aws_1_1_s3_1_1_model_1_1_delete_bucket_website_request.html): containing the name of the bucket to delete the configuration from.

 **Code** 

```
bool AwsDoc::S3::deleteBucketWebsite(const Aws::String &bucketName,
                                     const Aws::S3::S3ClientConfiguration &clientConfig) {
    Aws::S3::S3Client client(clientConfig);
    Aws::S3::Model::DeleteBucketWebsiteRequest request;
    request.SetBucket(bucketName);

    Aws::S3::Model::DeleteBucketWebsiteOutcome outcome =
            client.DeleteBucketWebsite(request);

    if (!outcome.IsSuccess()) {
        auto err = outcome.GetError();
        std::cerr << "Error: deleteBucketWebsite: " <<
                  err.GetExceptionName() << ": " << err.GetMessage() << std::endl;
    } else {
        std::cout << "Website configuration was removed." << std::endl;
    }

    return outcome.IsSuccess();
}
```

See the [complete example](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/cpp/example_code/s3/delete_website_config.cpp) on Github.

## More Information
<a name="more-information"></a>
+  [PUT Bucket website](https://docs.amazonaws.cn/AmazonS3/latest/API/RESTBucketPUTwebsite.html) in the Amazon Simple Storage Service API Reference
+  [GET Bucket website](https://docs.amazonaws.cn/AmazonS3/latest/API/RESTBucketGETwebsite.html) in the Amazon Simple Storage Service API Reference
+  [DELETE Bucket website](https://docs.amazonaws.cn/AmazonS3/latest/API/RESTBucketDELETEwebsite.html) in the Amazon Simple Storage Service API Reference

# Using TransferManager for Amazon S3 operations
<a name="examples-s3-transfermanager"></a>

You can use the Amazon SDK for C\$1\$1 `TransferManager` class to reliably transfer files from the local environment to Amazon S3 and to copy objects from one Amazon S3 location to another. `TransferManager` can get the progress of a transfer and pause or resume uploads and downloads.

**Note**  
To avoid being charged for incomplete or partial uploads, we recommend that you enable the [AbortIncompleteMultipartUpload](https://docs.amazonaws.cn/AmazonS3/latest/userguide/mpu-abort-incomplete-mpu-lifecycle-config.html) lifecycle rule on your Amazon S3 buckets.  
This rule directs Amazon S3 to abort multipart uploads that don’t complete within a specified number of days after being initiated. When the set time limit is exceeded, Amazon S3 aborts the upload and then deletes the incomplete upload data.   
For more information, see [Setting lifecycle configuration on a bucket](https://docs.amazonaws.cn/AmazonS3/latest/userguide/how-to-set-lifecycle-configuration-intro.html) in the Amazon S3 User Guide.

## Prerequisites
<a name="codeExamplePrereq"></a>

Before you begin, we recommend you read [Getting started using the Amazon SDK for C\$1\$1](getting-started.md). 

Download the example code and build the solution as described in [Getting started on code examples](getting-started-code-examples.md). 

To run the examples, the user profile your code uses to make the requests must have proper permissions in Amazon (for the service and the action). For more information, see [Providing Amazon credentials](credentials.md).

## Upload and download of object using `TransferManager`
<a name="stream"></a>

This example demonstrates how [https://docs.amazonaws.cn/sdk-for-cpp/latest/api/aws-cpp-sdk-transfer/html/class_aws_1_1_transfer_1_1_transfer_manager.html](https://docs.amazonaws.cn/sdk-for-cpp/latest/api/aws-cpp-sdk-transfer/html/class_aws_1_1_transfer_1_1_transfer_manager.html) transfers large object in memory. `UploadFile` and `DownloadFile` methods are both called asynchronously and return a `TransferHandle` to manage the status of your request. If the object uploaded is larger than `bufferSize` then a multipart upload will be performed. The `bufferSize` defaults to 5MB, but this can be configured via [https://docs.amazonaws.cn/sdk-for-cpp/latest/api/aws-cpp-sdk-transfer/html/struct_aws_1_1_transfer_1_1_transfer_manager_configuration.html](https://docs.amazonaws.cn/sdk-for-cpp/latest/api/aws-cpp-sdk-transfer/html/struct_aws_1_1_transfer_1_1_transfer_manager_configuration.html). 

```
        auto s3_client = Aws::MakeShared<Aws::S3::S3Client>("S3Client");
        auto executor = Aws::MakeShared<Aws::Utils::Threading::PooledThreadExecutor>("executor", 25);
        Aws::Transfer::TransferManagerConfiguration transfer_config(executor.get());
        transfer_config.s3Client = s3_client;

        // Create buffer to hold data received by the data stream.
        Aws::Utils::Array<unsigned char> buffer(BUFFER_SIZE);

        // The local variable 'streamBuffer' is captured by reference in a lambda.
        // It must persist until all downloading by the 'transfer_manager' is complete.
        Stream::PreallocatedStreamBuf streamBuffer(buffer.GetUnderlyingData(), buffer.GetLength());

        auto transfer_manager = Aws::Transfer::TransferManager::Create(transfer_config);

        auto uploadHandle = transfer_manager->UploadFile(LOCAL_FILE, BUCKET, KEY, "text/plain", Aws::Map<Aws::String, Aws::String>());
        uploadHandle->WaitUntilFinished();
        bool success = uploadHandle->GetStatus() == Transfer::TransferStatus::COMPLETED; 
      
        if (!success)
        {
            auto err = uploadHandle->GetLastError();           
            std::cout << "File upload failed:  "<< err.GetMessage() << std::endl;
        }
        else
        {
            std::cout << "File upload finished." << std::endl;

            auto downloadHandle = transfer_manager->DownloadFile(BUCKET,
                KEY,
                [&]() { //Define a lambda expression for the callback method parameter to stream back the data.
                    return Aws::New<MyUnderlyingStream>("TestTag", &streamBuffer);
                });
            downloadHandle->WaitUntilFinished();// Block calling thread until download is complete.
            auto downStat = downloadHandle->GetStatus();
            if (downStat != Transfer::TransferStatus::COMPLETED)
            {
                auto err = downloadHandle->GetLastError();
                std::cout << "File download failed:  " << err.GetMessage() << std::endl;
            }
            std::cout << "File download to memory finished."  << std::endl;
```

See the [complete example](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/cpp/example_code/transfer-manager/transferOnStream.cpp) on Github.

# Using `S3CrtClient` for Amazon S3 operations
<a name="examples-s3-crt"></a>

The `S3CrtClient` class is available in version 1.9 of the Amazon SDK for C\$1\$1 and improves the throughput of uploading and downloading large data files to and from Amazon S3. For more information on the improvements of this release, see [Improving Amazon S3 Throughput with Amazon SDK for C\$1\$1 v1.9 ](https://github.com/aws/aws-sdk-cpp/wiki/Improving-S3-Throughput-with-AWS-SDK-for-CPP-v1.9)

The `S3CrtClient` is implemented on the top of the [Amazon Common Runtime (CRT) libraries](https://docs.amazonaws.cn/sdkref/latest/guide/common-runtime.html).

**Note**  
To avoid being charged for incomplete or partial uploads, we recommend that you enable the [AbortIncompleteMultipartUpload](https://docs.amazonaws.cn/AmazonS3/latest/userguide/mpu-abort-incomplete-mpu-lifecycle-config.html) lifecycle rule on your Amazon S3 buckets.  
This rule directs Amazon S3 to abort multipart uploads that don’t complete within a specified number of days after being initiated. When the set time limit is exceeded, Amazon S3 aborts the upload and then deletes the incomplete upload data.   
For more information, see [Setting lifecycle configuration on a bucket](https://docs.amazonaws.cn/AmazonS3/latest/userguide/how-to-set-lifecycle-configuration-intro.html) in the Amazon S3 User Guide.

## Prerequisites
<a name="codeExamplePrereq"></a>

Before you begin, we recommend you read [Getting started using the Amazon SDK for C\$1\$1](getting-started.md). 

Download the example code and build the solution as described in [Getting started on code examples](getting-started-code-examples.md). 

To run the examples, the user profile your code uses to make the requests must have proper permissions in Amazon (for the service and the action). For more information, see [Providing Amazon credentials](credentials.md).

## Upload and download of object using `S3CrtClient`
<a name="stream"></a>

This example demonstrates how to use the [https://docs.amazonaws.cn/sdk-for-cpp/latest/api/aws-cpp-sdk-s3-crt/html/class_aws_1_1_s3_crt_1_1_s3_crt_client.html](https://docs.amazonaws.cn/sdk-for-cpp/latest/api/aws-cpp-sdk-s3-crt/html/class_aws_1_1_s3_crt_1_1_s3_crt_client.html). The example creates a bucket, uploads an object, downloads the object, then deletes the file and the bucket. A PUT operation turns into a multipart upload. A GET operation turns into multiple "ranged" GET requests. For more information on multipart uploads, see [Uploading and copying objects using multipart upload](https://docs.amazonaws.cn/AmazonS3/latest/userguide/mpuoverview.html) in the Amazon S3 User Guide. 

The provided data file, `ny.json`, gets uploaded as a multipart upload in this example. This can be confirmed by viewing the debug logs after a successful run of the program.

If the upload fails, an `AbortMultipartUpload` is issued in the underlying CRT library to clean up any already-uploaded parts. However, not all failures can be handled internally (such as a network cable being unplugged). It is recommended to create a lifecycle rule on your Amazon S3 bucket to ensure partially uploaded data does not linger on your account (partially uploaded data is still billable). To find out how to set up a lifecycle rule, see [Discovering and Deleting Incomplete Multipart Uploads to Lower Amazon S3 Costs](https://amazonaws-china.com/blogs/aws-cost-management/discovering-and-deleting-incomplete-multipart-uploads-to-lower-amazon-s3-costs/ ). 

**Using the debug log to explore multipart upload details**

1. In `main()`, note that there are "TODO" comments with instructions for updating the code.

   1. For `file_name`: From the link provided in the code comment download sample data file `ny.json`, or use a large data file of your own.

   1. For `region`: Update the `region` variable, using the enum, to the Amazon Web Services Region of your account. To find your Region of your account, log into the Amazon Web Services Management Console, and locate the Region in the upper right-hand corner.

1. Build the example.

1. Copy the file specified by variable `file_name` to your executable folder and run the `s3-crt-demo` executable.

1. In your executable folder, find the most recent `.log` file.

1. Open the log file, select **search**, and enter **partNumber**.

1. The log contains entries similar to the following, where the `partNumber` and `uploadId` are specified for each portion of the uploaded file:

    `PUT /my-object partNumber=1&uploadId=gsk8vDbmnlA5EseDo._LDEgq22Qmt0SeuszYxMsZ9ABt503VqDIFOP8xzZI1P0zp.ToS.qo5kK16HNWogZF3KpRo.Dc7QnLZIK0BTmzCWwWoPax4T21hvP6nPdz9591F content-length:8388608 host:my-bucketasdfasdf.s3.us-east-2.amazonaws.com x-amz-content-sha256:UNSIGNED-PAYLOAD`

    and 

    `PUT /my-object partNumber=2&uploadId=gsk8vDbmnlA5EseDo._LDEgq22Qmt0SeuszYxMsZ9ABt503VqDIFOP8xzZI1P0zp.ToS.qo5kK16HNWogZF3KpRo.Dc7QnLZIK0BTmzCWwWoPax4T21hvP6nPdz9591F content-length:8388608 host:my-bucketasdfasdf.s3.us-east-2.amazonaws.com x-amz-content-sha256:UNSIGNED-PAYLOAD `

See the [complete example](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/cpp/example_code/s3-crt/s3-crt-demo.cpp) on Github.

# Amazon SQS code examples using the Amazon SDK for C\$1\$1
<a name="examples-sqs"></a>

Amazon Simple Queue Service (Amazon SQS) is a fully managed message queuing service that makes it easy to decouple and scale microservices, distributed systems, and serverless applications. You can use the following examples to program [Amazon SQS](http://www.amazonaws.cn/sqs) using the Amazon SDK for C\$1\$1.

**Note**  
Only the code that is necessary to demonstrate certain techniques is supplied in this Guide, but the [complete example code is available on GitHub](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/cpp). On GitHub you can download a single source file or you can clone the repository locally to get, build, and run all examples.

**Topics**
+ [

# Working with Amazon SQS Message Queues
](examples-sqs-message-queues.md)
+ [

# Sending, Receiving, and Deleting Amazon SQS Messages
](examples-sqs-messages.md)
+ [

# Enabling Long Polling for Amazon SQS Message Queues
](examples-sqs-long-polling.md)
+ [

# Setting Visibility Timeout in Amazon SQS
](examples-sqs-visibility-timeout.md)
+ [

# Using Dead Letter Queues in Amazon SQS
](examples-sqs-dead-letter-queues.md)

# Working with Amazon SQS Message Queues
<a name="examples-sqs-message-queues"></a>

A *message queue* is the logical container you use to send messages reliably in Amazon SQS. There are two types of queues: *standard* and *first-in, first-out* (FIFO). To learn more about queues and the differences between these types, see the [Amazon Simple Queue Service Developer Guide](https://docs.amazonaws.cn/AWSSimpleQueueService/latest/SQSDeveloperGuide/).

These C\$1\$1 examples show you how to use the Amazon SDK for C\$1\$1 to create, list, delete, and get the URL of an Amazon SQS queue.

## Prerequisites
<a name="codeExamplePrereq"></a>

Before you begin, we recommend you read [Getting started using the Amazon SDK for C\$1\$1](getting-started.md). 

Download the example code and build the solution as described in [Getting started on code examples](getting-started-code-examples.md). 

To run the examples, the user profile your code uses to make the requests must have proper permissions in Amazon (for the service and the action). For more information, see [Providing Amazon credentials](credentials.md).

## Create a Queue
<a name="sqs-create-queue"></a>

Use the SQSClient class `CreateQueue` member function, and provide it with a [CreateQueueRequest](https://docs.amazonaws.cn/sdk-for-cpp/latest/api/aws-cpp-sdk-sqs/html/class_aws_1_1_s_q_s_1_1_model_1_1_create_queue_request.html) object that describes the queue parameters.

 **Includes** 

```
#include <aws/core/Aws.h>
#include <aws/sqs/SQSClient.h>
#include <aws/sqs/model/CreateQueueRequest.h>
#include <iostream>
```

 **Code** 

```
    Aws::SQS::SQSClient sqsClient(clientConfiguration);

    Aws::SQS::Model::CreateQueueRequest request;
    request.SetQueueName(queueName);

    const Aws::SQS::Model::CreateQueueOutcome outcome = sqsClient.CreateQueue(request);
    if (outcome.IsSuccess()) {
        std::cout << "Successfully created queue " << queueName << " with a queue URL "
                  << outcome.GetResult().GetQueueUrl() << "." << std::endl;
    }
    else {
        std::cerr << "Error creating queue " << queueName << ": " <<
                  outcome.GetError().GetMessage() << std::endl;
    }
```

See the [complete example](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/cpp/example_code/sqs/create_queue.cpp).

## List Queues
<a name="sqs-list-queues"></a>

To list Amazon SQS queues for your account, call the SQSClient class `ListQueues` member function, and pass it a [ListQueuesRequest](https://docs.amazonaws.cn/sdk-for-cpp/latest/api/aws-cpp-sdk-sqs/html/class_aws_1_1_s_q_s_1_1_model_1_1_list_queues_request.html) object.

 **Includes** 

```
#include <aws/core/Aws.h>
#include <aws/sqs/SQSClient.h>
#include <aws/sqs/model/ListQueuesRequest.h>
#include <iostream>
```

 **Code** 

```
    Aws::SQS::SQSClient sqsClient(clientConfiguration);

    Aws::SQS::Model::ListQueuesRequest listQueuesRequest;

    Aws::String nextToken; // Used for pagination.
    Aws::Vector<Aws::String> allQueueUrls;

    do {
        if (!nextToken.empty()) {
            listQueuesRequest.SetNextToken(nextToken);
        }
        const Aws::SQS::Model::ListQueuesOutcome outcome = sqsClient.ListQueues(
                listQueuesRequest);
        if (outcome.IsSuccess()) {
            const Aws::Vector<Aws::String> &queueUrls = outcome.GetResult().GetQueueUrls();
            allQueueUrls.insert(allQueueUrls.end(),
                                queueUrls.begin(),
                                queueUrls.end());

            nextToken = outcome.GetResult().GetNextToken();
        }
        else {
            std::cerr << "Error listing queues: " <<
                      outcome.GetError().GetMessage() << std::endl;
            return false;
        }

    } while (!nextToken.empty());

    std::cout << allQueueUrls.size() << " Amazon SQS queue(s) found." << std::endl;
    for (const auto &iter: allQueueUrls) {
        std::cout << " " << iter << std::endl;
    }
```

See the [complete example](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/cpp/example_code/sqs/list_queues.cpp).

## Get the Queue’s URL
<a name="sqs-get-queue-url"></a>

To get the URL for an existing Amazon SQS queue, call the SQSClient class `GetQueueUrl` member function.

 **Includes** 

```
#include <aws/core/Aws.h>
#include <aws/sqs/SQSClient.h>
#include <aws/sqs/model/GetQueueUrlRequest.h>
#include <iostream>
```

 **Code** 

```
    Aws::SQS::SQSClient sqsClient(clientConfiguration);

    Aws::SQS::Model::GetQueueUrlRequest request;
    request.SetQueueName(queueName);

    const Aws::SQS::Model::GetQueueUrlOutcome outcome = sqsClient.GetQueueUrl(request);
    if (outcome.IsSuccess()) {
        std::cout << "Queue " << queueName << " has url " <<
                  outcome.GetResult().GetQueueUrl() << std::endl;
    }
    else {
        std::cerr << "Error getting url for queue " << queueName << ": " <<
                  outcome.GetError().GetMessage() << std::endl;
    }
```

See the [complete example](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/cpp/example_code/sqs/get_queue_url.cpp).

## Delete a Queue
<a name="sqs-delete-queue"></a>

Provide the [URL](#sqs-get-queue-url) to the SQSClient class `DeleteQueue` member function.

 **Includes** 

```
#include <aws/core/Aws.h>
#include <aws/core/client/DefaultRetryStrategy.h>
#include <aws/sqs/SQSClient.h>
#include <aws/sqs/model/DeleteQueueRequest.h>
#include <iostream>
```

 **Code** 

```
    Aws::SQS::Model::DeleteQueueRequest request;
    request.SetQueueUrl(queueURL);

    const Aws::SQS::Model::DeleteQueueOutcome outcome = sqsClient.DeleteQueue(request);
    if (outcome.IsSuccess()) {
        std::cout << "Successfully deleted queue with url " << queueURL <<
                  std::endl;
    }
    else {
        std::cerr << "Error deleting queue " << queueURL << ": " <<
                  outcome.GetError().GetMessage() << std::endl;
    }
```

See the [complete example](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/cpp/example_code/sqs/delete_queue.cpp).

## More Info
<a name="more-info"></a>
+  [How Amazon SQS Queues Work](https://docs.amazonaws.cn/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-how-it-works.html) in the Amazon Simple Queue Service Developer Guide
+  [CreateQueue](https://docs.amazonaws.cn/AWSSimpleQueueService/latest/APIReference/API_CreateQueue.html) in the Amazon Simple Queue Service API Reference
+  [GetQueueUrl](https://docs.amazonaws.cn/AWSSimpleQueueService/latest/APIReference/API_GetQueueUrl.html) in the Amazon Simple Queue Service API Reference
+  [ListQueues](https://docs.amazonaws.cn/AWSSimpleQueueService/latest/APIReference/API_ListQueues.html) in the Amazon Simple Queue Service API Reference
+  [DeleteQueues](https://docs.amazonaws.cn/AWSSimpleQueueService/latest/APIReference/API_DeleteQueues.html) in the Amazon Simple Queue Service API Reference

# Sending, Receiving, and Deleting Amazon SQS Messages
<a name="examples-sqs-messages"></a>

Messages are always delivered using an [SQS queue](examples-sqs-message-queues.md). These C\$1\$1 examples show you how to use the Amazon SDK for C\$1\$1 to send, receive, and delete Amazon SQS messages from SQS queues.

## Prerequisites
<a name="codeExamplePrereq"></a>

Before you begin, we recommend you read [Getting started using the Amazon SDK for C\$1\$1](getting-started.md). 

Download the example code and build the solution as described in [Getting started on code examples](getting-started-code-examples.md). 

To run the examples, the user profile your code uses to make the requests must have proper permissions in Amazon (for the service and the action). For more information, see [Providing Amazon credentials](credentials.md).

## Send a Message
<a name="sqs-message-send"></a>

You can add a single message to an Amazon SQS queue by calling the SQSClient class `SendMessage` member function. You provide `SendMessage` with a [SendMessageRequest](https://docs.amazonaws.cn/sdk-for-cpp/latest/api/aws-cpp-sdk-sqs/html/class_aws_1_1_s_q_s_1_1_model_1_1_send_message_request.html) object containing the queue’s [URL](examples-sqs-message-queues.md#sqs-get-queue-url), the message body, and an optional delay value (in seconds).

 **Includes** 

```
#include <aws/core/Aws.h>
#include <aws/sqs/SQSClient.h>
#include <aws/sqs/model/SendMessageRequest.h>
#include <iostream>
```

 **Code** 

```
    Aws::SQS::SQSClient sqsClient(clientConfiguration);

    Aws::SQS::Model::SendMessageRequest request;
    request.SetQueueUrl(queueUrl);
    request.SetMessageBody(messageBody);

    const Aws::SQS::Model::SendMessageOutcome outcome = sqsClient.SendMessage(request);
    if (outcome.IsSuccess()) {
        std::cout << "Successfully sent message to " << queueUrl <<
                  std::endl;
    }
    else {
        std::cerr << "Error sending message to " << queueUrl << ": " <<
                  outcome.GetError().GetMessage() << std::endl;
    }
```

See the [complete example](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/cpp/example_code/sqs/send_message.cpp).

## Receive Messages
<a name="sqs-messages-receive"></a>

Retrieve any messages that are currently in the queue by calling the SQSClient class `ReceiveMessage` member function, passing it the queue’s URL. Messages are returned as a list of [Message](https://docs.amazonaws.cn/sdk-for-cpp/latest/api/aws-cpp-sdk-sqs/html/class_aws_1_1_s_q_s_1_1_model_1_1_message.html) objects.

 **Includes** 

```
#include <aws/core/Aws.h>
#include <aws/sqs/SQSClient.h>
#include <aws/sqs/model/ReceiveMessageRequest.h>
#include <iostream>
```

 **Code** 

```
    Aws::SQS::SQSClient sqsClient(clientConfiguration);

    Aws::SQS::Model::ReceiveMessageRequest request;
    request.SetQueueUrl(queueUrl);
    request.SetMaxNumberOfMessages(1);

    const Aws::SQS::Model::ReceiveMessageOutcome outcome = sqsClient.ReceiveMessage(
            request);
    if (outcome.IsSuccess()) {

        const Aws::Vector<Aws::SQS::Model::Message> &messages =
                outcome.GetResult().GetMessages();
        if (!messages.empty()) {
            const Aws::SQS::Model::Message &message = messages[0];
            std::cout << "Received message:" << std::endl;
            std::cout << "  MessageId: " << message.GetMessageId() << std::endl;
            std::cout << "  ReceiptHandle: " << message.GetReceiptHandle() << std::endl;
            std::cout << "  Body: " << message.GetBody() << std::endl << std::endl;
        }
        else {
            std::cout << "No messages received from queue " << queueUrl <<
                      std::endl;

        }
    }
    else {
        std::cerr << "Error receiving message from queue " << queueUrl << ": "
                  << outcome.GetError().GetMessage() << std::endl;
    }
```

See the [complete example](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/cpp/example_code/sqs/receive_message.cpp).

### Delete Messages after Receipt
<a name="sqs-messages-delete"></a>

After receiving a message and processing its contents, delete the message from the queue by sending the message’s receipt handle and the queue URL to the SQSClient class `DeleteMessage` member function.

 **Includes** 

```
#include <aws/core/Aws.h>
#include <aws/sqs/SQSClient.h>
#include <aws/sqs/model/DeleteMessageRequest.h>
#include <iostream>
```

 **Code** 

```
    Aws::SQS::Model::DeleteMessageRequest request;
    request.SetQueueUrl(queueUrl);
    request.SetReceiptHandle(messageReceiptHandle);

    const Aws::SQS::Model::DeleteMessageOutcome outcome = sqsClient.DeleteMessage(
            request);
    if (outcome.IsSuccess()) {
        std::cout << "Successfully deleted message from queue " << queueUrl
                  << std::endl;
    }
    else {
        std::cerr << "Error deleting message from queue " << queueUrl << ": " <<
                  outcome.GetError().GetMessage() << std::endl;
    }
```

See the [complete example](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/cpp/example_code/sqs/receive_message.cpp).

## More Info
<a name="more-info"></a>
+  [How Amazon SQS Queues Work](https://docs.amazonaws.cn/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-how-it-works.html) in the Amazon Simple Queue Service Developer Guide
+  [SendMessage](https://docs.amazonaws.cn/AWSSimpleQueueService/latest/APIReference/API_SendMessage.html) in the Amazon Simple Queue Service API Reference
+  [SendMessageBatch](https://docs.amazonaws.cn/AWSSimpleQueueService/latest/APIReference/API_SendMessageBatch.html) in the Amazon Simple Queue Service API Reference
+  [ReceiveMessage](https://docs.amazonaws.cn/AWSSimpleQueueService/latest/APIReference/API_ReceiveMessage.html) in the Amazon Simple Queue Service API Reference
+  [DeleteMessage](https://docs.amazonaws.cn/AWSSimpleQueueService/latest/APIReference/API_DeleteMessage.html) in the Amazon Simple Queue Service API Reference

# Enabling Long Polling for Amazon SQS Message Queues
<a name="examples-sqs-long-polling"></a>

Amazon SQS uses *short polling* by default, querying only a subset of the servers—based on a weighted random distribution—to determine whether any messages are available for inclusion in the response.

Long polling helps reduce your cost of using Amazon SQS by reducing the number of empty responses when there are no messages available to return in reply to a ReceiveMessage request sent to an Amazon SQS queue and eliminating false empty responses. You can set a long polling frequency from *1–20 seconds*.

## Prerequisites
<a name="codeExamplePrereq"></a>

Before you begin, we recommend you read [Getting started using the Amazon SDK for C\$1\$1](getting-started.md). 

Download the example code and build the solution as described in [Getting started on code examples](getting-started-code-examples.md). 

To run the examples, the user profile your code uses to make the requests must have proper permissions in Amazon (for the service and the action). For more information, see [Providing Amazon credentials](credentials.md).

## Enable Long Polling when Creating a Queue
<a name="sqs-long-polling-create-queue"></a>

To enable long polling when creating an Amazon SQS queue, set the `ReceiveMessageWaitTimeSeconds` attribute on the [CreateQueueRequest](https://docs.amazonaws.cn/sdk-for-cpp/latest/api/aws-cpp-sdk-sqs/html/class_aws_1_1_s_q_s_1_1_model_1_1_create_queue_request.html) object before calling the SQSClient class’ `CreateQueue` member function.

 **Includes** 

```
#include <aws/core/Aws.h>
#include <aws/sqs/SQSClient.h>
#include <aws/sqs/model/CreateQueueRequest.h>
#include <iostream>
```

 **Code** 

```
    Aws::SQS::SQSClient sqsClient(clientConfiguration);

    Aws::SQS::Model::CreateQueueRequest request;
    request.SetQueueName(queueName);
    request.AddAttributes(
            Aws::SQS::Model::QueueAttributeName::ReceiveMessageWaitTimeSeconds,
            pollTimeSeconds);

    const Aws::SQS::Model::CreateQueueOutcome outcome = sqsClient.CreateQueue(request);
    if (outcome.IsSuccess()) {
        std::cout << "Successfully created queue " << queueName <<
                  std::endl;
    }
    else {
        std::cout << "Error creating queue " << queueName << ": " <<
                  outcome.GetError().GetMessage() << std::endl;
    }
```

See the [complete example](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/cpp/example_code/sqs/long_polling_on_create_queue.cpp).

## Enable Long Polling on an Existing Queue
<a name="sqs-long-polling-existing-queue"></a>

In addition to enabling long polling when creating a queue, you can also enable it on an existing queue by setting `ReceiveMessageWaitTimeSeconds` on the [SetQueueAttributesRequest](https://docs.amazonaws.cn/sdk-for-cpp/latest/api/aws-cpp-sdk-sqs/html/class_aws_1_1_s_q_s_1_1_model_1_1_set_queue_attributes_request.html) before calling the SQSClient class’ `SetQueueAttributes` member function.

 **Includes** 

```
#include <aws/core/Aws.h>
#include <aws/sqs/SQSClient.h>
#include <aws/sqs/model/SetQueueAttributesRequest.h>
#include <iostream>
```

 **Code** 

```
    Aws::SQS::SQSClient sqsClient(clientConfiguration);

    Aws::SQS::Model::SetQueueAttributesRequest request;
    request.SetQueueUrl(queueURL);
    request.AddAttributes(
            Aws::SQS::Model::QueueAttributeName::ReceiveMessageWaitTimeSeconds,
            pollTimeSeconds);

    const Aws::SQS::Model::SetQueueAttributesOutcome outcome = sqsClient.SetQueueAttributes(
            request);
    if (outcome.IsSuccess()) {
        std::cout << "Successfully updated long polling time for queue " <<
                  queueURL << " to " << pollTimeSeconds << std::endl;
    }
    else {
        std::cout << "Error updating long polling time for queue " <<
                  queueURL << ": " << outcome.GetError().GetMessage() <<
                  std::endl;
    }
```

See the [complete example](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/cpp/example_code/sqs/long_polling_on_existing_queue.cpp).

## Enable Long Polling on Message Receipt
<a name="sqs-long-polling-receive-message"></a>

You can enable long polling when receiving a message by setting the wait time in seconds on the [ReceiveMessageRequest](https://docs.amazonaws.cn/sdk-for-cpp/latest/api/aws-cpp-sdk-sqs/html/class_aws_1_1_s_q_s_1_1_model_1_1_receive_message_request.html) that you supply to the SQSClient class’ ReceiveMessage member function.

**Note**  
You should make sure that the Amazon client’s request timeout is larger than the maximum long poll time (20s) so that your `ReceiveMessage` requests don’t time out while waiting for the next poll event\$1

 **Includes** 

```
#include <aws/core/Aws.h>
#include <aws/sqs/SQSClient.h>
#include <aws/sqs/model/ReceiveMessageRequest.h>
```

 **Code** 

```
    Aws::SQS::SQSClient sqsClient(customConfiguration);

    Aws::SQS::Model::ReceiveMessageRequest request;
    request.SetQueueUrl(queueUrl);
    request.SetMaxNumberOfMessages(1);
    request.SetWaitTimeSeconds(waitTimeSeconds);

    auto outcome = sqsClient.ReceiveMessage(request);
    if (outcome.IsSuccess()) {
        const auto &messages = outcome.GetResult().GetMessages();
        if (messages.empty()) {
            std::cout << "No messages received from queue " << queueUrl <<
                      std::endl;
        }
        else {
            const auto &message = messages[0];
            std::cout << "Received message:" << std::endl;
            std::cout << "  MessageId: " << message.GetMessageId() << std::endl;
            std::cout << "  ReceiptHandle: " << message.GetReceiptHandle() << std::endl;
            std::cout << "  Body: " << message.GetBody() << std::endl << std::endl;
        }
    }
    else {
        std::cout << "Error receiving message from queue " << queueUrl << ": "
                  << outcome.GetError().GetMessage() << std::endl;
    }
```

See the [complete example](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/cpp/example_code/sqs/long_polling_on_message_receipt.cpp).

## More Info
<a name="more-info"></a>
+  [Amazon SQS Long Polling](https://docs.amazonaws.cn/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-long-polling.html) in the Amazon Simple Queue Service Developer Guide
+  [CreateQueue](https://docs.amazonaws.cn/AWSSimpleQueueService/latest/APIReference/API_CreateQueue.html) in the Amazon Simple Queue Service API Reference
+  [ReceiveMessage](https://docs.amazonaws.cn/AWSSimpleQueueService/latest/APIReference/API_ReceiveMessage.html) in the Amazon Simple Queue Service API Reference
+  [SetQueueAttributes](https://docs.amazonaws.cn/AWSSimpleQueueService/latest/APIReference/API_SetQueueAttributes.html) in the Amazon Simple Queue Service API Reference

# Setting Visibility Timeout in Amazon SQS
<a name="examples-sqs-visibility-timeout"></a>

When a message is received in Amazon SQS, it remains on the queue until it’s deleted in order to ensure receipt. A message that was received, but not deleted, will be available in subsequent requests after a given *visibility timeout* to help prevent the message from being received more than once before it can be processed and deleted.

When using [standard queues](https://docs.amazonaws.cn/AWSSimpleQueueService/latest/SQSDeveloperGuide/standard-queues.html), visibility timeout isn’t a guarantee against receiving a message twice. If you are using a standard queue, be sure that your code can handle the case where the same message has been delivered more than once.

## Prerequisites
<a name="codeExamplePrereq"></a>

Before you begin, we recommend you read [Getting started using the Amazon SDK for C\$1\$1](getting-started.md). 

Download the example code and build the solution as described in [Getting started on code examples](getting-started-code-examples.md). 

To run the examples, the user profile your code uses to make the requests must have proper permissions in Amazon (for the service and the action). For more information, see [Providing Amazon credentials](credentials.md).

## Set the Message Visibility Timeout upon Message Receipt
<a name="sqs-visibility-timeout-receipt"></a>

When you have received a message, you can modify its visibility timeout by passing its receipt handle in a [ChangeMessageVisibilityRequest](https://docs.amazonaws.cn/sdk-for-cpp/latest/api/aws-cpp-sdk-sqs/html/class_aws_1_1_s_q_s_1_1_model_1_1_change_message_visibility_request.html) that you pass to the SQSClient class’ `ChangeMessageVisibility` member function.

 **Includes** 

```
#include <aws/core/Aws.h>
#include <aws/sqs/SQSClient.h>
#include <aws/sqs/model/ChangeMessageVisibilityRequest.h>
#include <aws/sqs/model/ReceiveMessageRequest.h>
#include <iostream>
```

 **Code** 

```
    Aws::SQS::Model::ChangeMessageVisibilityRequest request;
    request.SetQueueUrl(queue_url);
    request.SetReceiptHandle(messageReceiptHandle);
    request.SetVisibilityTimeout(visibilityTimeoutSeconds);

    auto outcome = sqsClient.ChangeMessageVisibility(request);
    if (outcome.IsSuccess()) {
        std::cout << "Successfully changed visibility of message " <<
                  messageReceiptHandle << " from queue " << queue_url << std::endl;
    }
    else {
        std::cout << "Error changing visibility of message from queue "
                  << queue_url << ": " <<
                  outcome.GetError().GetMessage() << std::endl;
    }
```

See the [complete example](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/cpp/example_code/sqs/change_message_visibility.cpp).

## More Info
<a name="more-info"></a>
+  [Visibility Timeout](https://docs.amazonaws.cn/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-visibility-timeout.html) in the Amazon Simple Queue Service Developer Guide
+  [SetQueueAttributes](https://docs.amazonaws.cn/AWSSimpleQueueService/latest/APIReference/API_SetQueueAttributes.html) in the Amazon Simple Queue Service API Reference
+  [GetQueueAttributes](https://docs.amazonaws.cn/AWSSimpleQueueService/latest/APIReference/API_GetQueueAttributes.html) in the Amazon Simple Queue Service API Reference
+  [ReceiveMessage](https://docs.amazonaws.cn/AWSSimpleQueueService/latest/APIReference/API_ReceiveMessage.html) in the Amazon Simple Queue Service API Reference
+  [ChangeMessageVisibility](https://docs.amazonaws.cn/AWSSimpleQueueService/latest/APIReference/API_ChangeMessageVisibility.html) in the Amazon Simple Queue Service API Reference
+  [ChangeMessageVisibilityBatch](https://docs.amazonaws.cn/AWSSimpleQueueService/latest/APIReference/API_ChangeMessageVisibilityBatch.html) in the Amazon Simple Queue Service API Reference

# Using Dead Letter Queues in Amazon SQS
<a name="examples-sqs-dead-letter-queues"></a>

Amazon SQS provides support for *dead letter queues*. A dead letter queue is a queue that other queues can target for messages that can’t be processed successfully. You can set aside and isolate these messages in the dead letter queue to determine why their processing did not succeed.

To create a dead letter queue, you must first create a *redrive policy*, and then set the policy in the queue’s attributes.

**Important**  
A dead letter queue must be the same type of queue (FIFO or standard) that the source queue is. It must also be created using the same Amazon Web Services account and Amazon Web Services Region as the source queue.

## Prerequisites
<a name="codeExamplePrereq"></a>

Before you begin, we recommend you read [Getting started using the Amazon SDK for C\$1\$1](getting-started.md). 

Download the example code and build the solution as described in [Getting started on code examples](getting-started-code-examples.md). 

To run the examples, the user profile your code uses to make the requests must have proper permissions in Amazon (for the service and the action). For more information, see [Providing Amazon credentials](credentials.md).

## Create a Redrive Policy
<a name="sqs-dead-letter-queue-create-redrive-policy"></a>

A redrive policy is specified in JSON. To create it, you can use the JSON utility class provided with the Amazon SDK for C\$1\$1.

Here is an example function that creates a redrive policy by providing it with the ARN of your dead letter queue and the maximum number of times the message can be received and not processed before it’s sent to the dead letter queue.

 **Includes** 

```
#include <aws/core/Aws.h>
#include <aws/core/utils/json/JsonSerializer.h>
```

 **Code** 

```
Aws::String MakeRedrivePolicy(const Aws::String &queueArn, int maxReceiveCount) {
    Aws::Utils::Json::JsonValue redrive_arn_entry;
    redrive_arn_entry.AsString(queueArn);

    Aws::Utils::Json::JsonValue max_msg_entry;
    max_msg_entry.AsInteger(maxReceiveCount);

    Aws::Utils::Json::JsonValue policy_map;
    policy_map.WithObject("deadLetterTargetArn", redrive_arn_entry);
    policy_map.WithObject("maxReceiveCount", max_msg_entry);

    return policy_map.View().WriteReadable();
}
```

See the [complete example](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/cpp/example_code/sqs/dead_letter_queue.cpp).

## Set the Redrive Policy on your Source Queue
<a name="sqs-dead-letter-queue-set-redrive-policy"></a>

To finish setting up your dead letter queue, call the SQSClient class’ `SetQueueAttributes` member function with a [SetQueueAttributesRequest](https://docs.amazonaws.cn/sdk-for-cpp/latest/api/aws-cpp-sdk-sqs/html/class_aws_1_1_s_q_s_1_1_model_1_1_set_queue_attributes_request.html) object for which you’ve set the `RedrivePolicy` attribute with your JSON redrive policy.

 **Includes** 

```
#include <aws/sqs/SQSClient.h>
#include <aws/sqs/model/SetQueueAttributesRequest.h>
#include <iostream>
```

 **Code** 

```
    Aws::SQS::Model::SetQueueAttributesRequest request;
    request.SetQueueUrl(srcQueueUrl);
    request.AddAttributes(
            Aws::SQS::Model::QueueAttributeName::RedrivePolicy,
            redrivePolicy);

    const Aws::SQS::Model::SetQueueAttributesOutcome outcome =
            sqsClient.SetQueueAttributes(request);
    if (outcome.IsSuccess()) {
        std::cout << "Successfully set dead letter queue for queue  " <<
                  srcQueueUrl << " to " << deadLetterQueueARN << std::endl;
    }
    else {
        std::cerr << "Error setting dead letter queue for queue " <<
                  srcQueueUrl << ": " << outcome.GetError().GetMessage() <<
                  std::endl;
    }
```

See the [complete example](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/cpp/example_code/sqs/dead_letter_queue.cpp).

## More Info
<a name="more-info"></a>
+  [Using Amazon SQS Dead Letter Queues](https://docs.amazonaws.cn/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-dead-letter-queues.html) in the Amazon Simple Queue Service Developer Guide
+  [SetQueueAttributes](https://docs.amazonaws.cn/AWSSimpleQueueService/latest/APIReference/API_SetQueueAttributes.html) in the Amazon Simple Queue Service API Reference