

# AWS IoT rule actions


AWS IoT rule actions specify what to do when a rule is invoked. You can define actions to send data to an Amazon DynamoDB database, send data to Amazon Kinesis Data Streams, invoke an AWS Lambda function, and so on. AWS IoT supports the following actions in AWS Regions where the action's service is available.


| Rule action | Description | Name in API | 
| --- | --- | --- | 
| [Apache Kafka](apache-kafka-rule-action.md) | Sends a message to an Apache Kafka cluster. | kafka | 
| [CloudWatch alarms](cloudwatch-alarms-rule-action.md) | Changes the state of an Amazon CloudWatch alarm. | cloudwatchAlarm | 
| [CloudWatch Logs](cloudwatch-logs-rule-action.md) | Sends a message to Amazon CloudWatch Logs. | cloudwatchLogs | 
| [CloudWatch metrics](cloudwatch-metrics-rule-action.md) | Sends a message to a CloudWatch metric. | cloudwatchMetric | 
| [DynamoDB](dynamodb-rule-action.md) | Sends a message to a DynamoDB table. | dynamoDB | 
| [DynamoDBv2](dynamodb-v2-rule-action.md) | Sends message data to multiple columns in a DynamoDB table. | dynamoDBv2 | 
| [Elasticsearch](elasticsearch-rule-action.md) | Sends a message to an OpenSearch endpoint. | OpenSearch | 
| [HTTP](https-rule-action.md) | Posts a message to an HTTPS endpoint. | http | 
| [AWS IoT Events](iotevents-rule-action.md) | Sends a message to an AWS IoT Events input. | iotEvents | 
| [AWS IoT SiteWise](iotsitewise-rule-action.md) | Sends message data to AWS IoT SiteWise asset properties. | iotSiteWise | 
| [Firehose](kinesis-firehose-rule-action.md) | Sends a message to a Firehose delivery stream. | firehose | 
| [Kinesis Data Streams](kinesis-rule-action.md) | Sends a message to a Kinesis data stream. | kinesis | 
| [Lambda](lambda-rule-action.md) | Invokes a Lambda function with message data as input. | lambda | 
| [Location](location-rule-action.md) | Sends location data to Amazon Location Service. | location | 
| [OpenSearch](opensearch-rule-action.md) | Sends a message to an Amazon OpenSearch Service endpoint. | OpenSearch | 
| [Republish](republish-rule-action.md) | Republishes a message to another MQTT topic. | republish | 
| [S3](s3-rule-action.md) | Stores a message in an Amazon Simple Storage Service (Amazon S3) bucket. | s3 | 
| [Salesforce IoT](salesforce-iot-rule-action.md) | Sends a message to a Salesforce IoT input stream. | salesforce | 
| [SNS](sns-rule-action.md) | Publishes a message as an Amazon Simple Notification Service (Amazon SNS) push notification. | sns | 
| [SQS](sqs-rule-action.md) | Sends a message to an Amazon Simple Queue Service (Amazon SQS) queue. | sqs | 
| [Step Functions](stepfunctions-rule-action.md) | Starts an AWS Step Functions state machine. | stepFunctions | 
| [Timestream](timestream-rule-action.md) | Sends a message to an Amazon Timestream database table. | timestream | 

**Notes**  
Define the rule in the same AWS Region as another service's resource so that the rule action can interact with that resource.
The AWS IoT rules engine might make multiple attempts to perform an action if intermittent errors occur. If all attempts fail, the message is discarded and the error is available in your CloudWatch Logs. You can specify an error action for each rule that is invoked after a failure occurs. For more information, see [Error handling (error action)](rule-error-handling.md).
Some rule actions activate actions in services that integrate with AWS Key Management Service (AWS KMS) to support data encryption at rest. If you use a customer-managed AWS KMS key (KMS key) to encrypt data at rest, the service must have permission to use the KMS key on the caller's behalf. To learn how to manage permissions for your customer managed KMS key, see the data encryption topics in the appropriate service guide. For more information about customer managed KMS keys, see [AWS Key Management Service concepts](https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html) in the *AWS Key Management Service Developer Guide*.  
You can use any [function](iot-sql-functions.md) or [substitution template](https://docs.aws.amazon.com//iot/latest/developerguide/iot-substitution-templates.html) in an error action's SQL statement including the external functions: [https://docs.aws.amazon.com//iot/latest/developerguide/iot-sql-functions.html#iot-func-aws-lambda](https://docs.aws.amazon.com//iot/latest/developerguide/iot-sql-functions.html#iot-func-aws-lambda), [https://docs.aws.amazon.com//iot/latest/developerguide/iot-sql-functions.html#iot-sql-function-get-dynamodb](https://docs.aws.amazon.com//iot/latest/developerguide/iot-sql-functions.html#iot-sql-function-get-dynamodb), [https://docs.aws.amazon.com//iot/latest/developerguide/iot-sql-functions.html#iot-sql-function-get-registry_data](https://docs.aws.amazon.com//iot/latest/developerguide/iot-sql-functions.html#iot-sql-function-get-registry_data), [https://docs.aws.amazon.com//iot/latest/developerguide/iot-sql-functions.html#iot-sql-function-get-thing-shadow](https://docs.aws.amazon.com//iot/latest/developerguide/iot-sql-functions.html#iot-sql-function-get-thing-shadow), [https://docs.aws.amazon.com//iot/latest/developerguide/iot-sql-functions.html#iot-sql-function-get-secret](https://docs.aws.amazon.com//iot/latest/developerguide/iot-sql-functions.html#iot-sql-function-get-secret), [https://docs.aws.amazon.com//iot/latest/developerguide/iot-sql-functions.html#iot-sql-function-machine-learning](https://docs.aws.amazon.com//iot/latest/developerguide/iot-sql-functions.html#iot-sql-function-machine-learning), and [https://docs.aws.amazon.com//iot/latest/developerguide/iot-sql-functions.html#iot-sql-decode-base64](https://docs.aws.amazon.com//iot/latest/developerguide/iot-sql-functions.html#iot-sql-decode-base64). If an error action requires to call an external function, then invoking the error action can result in additional bill for the external function.

# Apache Kafka


The Apache Kafka (Kafka) action sends messages directly to your [Amazon Managed Streaming for Apache Kafka](https://docs.aws.amazon.com//msk/latest/developerguide/what-is-msk.html) (Amazon MSK), Apache Kafka clusters managed by third-party providers such as [Confluent Cloud](https://www.confluent.io/), or self-managed Apache Kafka clusters. With Kafka rule action, you can route your IoT data to Kafka clusters. This enables you to build high-performance data pipelines for various purposes, such as streaming analytics, data integration, visualization, and mission-critical business applications.

**Note**  
This topic assumes familiarity with the Apache Kafka platform and related concepts. For more information about Apache Kafka, see [Apache Kafka](https://kafka.apache.org/). [MSK Serverless](https://docs.aws.amazon.com//msk/latest/developerguide/serverless.html) is not supported. MSK Serverless clusters can only be done via IAM authentication, which Apache Kafka rule action doesn't currently support. For more information about how to configure AWS IoT Core with Confluent, see [Leveraging Confluent and AWS to Solve IoT Device and Data Management Challenges](https://aws.amazon.com/blogs/apn/leveraging-confluent-and-aws-to-solve-iot-device-and-data-management-challenges/).

## Requirements


This rule action has the following requirements:
+ An IAM role that AWS IoT can assume to perform the `ec2:CreateNetworkInterface`, `ec2:DescribeNetworkInterfaces`, `ec2:CreateNetworkInterfacePermission`, `ec2:DeleteNetworkInterface`, `ec2:DescribeSubnets`, `ec2:DescribeVpcs`, `ec2:DescribeVpcAttribute`, and `ec2:DescribeSecurityGroups` operations. This role creates and manages elastic network interfaces to your Amazon Virtual Private Cloud to reach your Kafka broker. For more information, see [Granting an AWS IoT rule the access it requires](iot-create-role.md).

  In the AWS IoT console, you can choose or create a role to allow AWS IoT Core to perform this rule action. 

  For more information about network interfaces, see [Elastic network interfaces](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-eni.html) in the *Amazon EC2 User Guide*.

  The policy attached to the role that you specify should look like the following example.  
****  

  ```
  {
      "Version":"2012-10-17",		 	 	 
      "Statement": [
      {
          "Effect": "Allow",
          "Action": [
              "ec2:CreateNetworkInterface",
              "ec2:DescribeNetworkInterfaces",
              "ec2:CreateNetworkInterfacePermission",
              "ec2:DeleteNetworkInterface",
              "ec2:DescribeSubnets",
              "ec2:DescribeVpcs",
              "ec2:DescribeVpcAttribute",
              "ec2:DescribeSecurityGroups"
              ],
              "Resource": "*"
          }
      ]
  }
  ```
+ If you use AWS Secrets Manager to store the credentials required to connect to your Kafka broker, you must create an IAM role that AWS IoT Core can assume to perform the `secretsmanager:GetSecretValue` and `secretsmanager:DescribeSecret` operations.

  The policy attached to the role that you specify should look like the following example.  
****  

  ```
  {
      "Version":"2012-10-17",		 	 	 
      "Statement": [
          {
              "Effect": "Allow",
              "Action": [
                  "secretsmanager:GetSecretValue",
                  "secretsmanager:DescribeSecret"
              ],
              "Resource": [
                  "arn:aws:secretsmanager:us-east-1:123456789012:secret:kafka_client_truststore-*",
                  "arn:aws:secretsmanager:us-east-1:123456789012:secret:kafka_keytab-*"
              ]
          }
      ]
  }
  ```
+ You can run your Apache Kafka clusters inside Amazon Virtual Private Cloud (Amazon VPC). You must create an Apache Kafka Virtual Private Cloud (VPC) destination and use an NAT gateway in your subnets to forward messages from AWS IoT to a public Kafka cluster. The AWS IoT rules engine creates a network interface in each of the subnets listed in the destination to route traffic directly to the VPC. When you destination, the AWS IoT rules engine automatically creates a VPC rule action. For more information about VPC rule actions, see [Apache Kafka Virtual Private Cloud (VPC) destinations](kafka-vpc-destination.md).
+ If you use a customer managed AWS KMS key (KMS key) to encrypt data at rest, the service must have permission to use the KMS key on the caller's behalf. For more information, see [Amazon MSK encryption](https://docs.aws.amazon.com/msk/latest/developerguide/msk-encryption.html) in the *Amazon Managed Streaming for Apache Kafka Developer Guide*.

## Parameters


When you create an AWS IoT rule with this action, you must specify the following information:

destinationArn  
The Amazon Resource Name (ARN) of the Apache Kafka Virtual Private Cloud (VPC) destination. For information about creating a destination, see [Apache Kafka Virtual Private Cloud (VPC) destinations](kafka-vpc-destination.md).

topic  
The Kafka topic for messages to be sent to the Kafka broker.  
You can substitute this field using a substitution template. For more information, see [Substitution templates](iot-substitution-templates.md). 

key (optional)  
The Kafka message key.  
You can substitute this field using a substitution template. For more information, see [Substitution templates](iot-substitution-templates.md). 

headers (optional)  
The list of Kafka headers that you specify. Each header is a key-value pair that you can specify when you create a Kafka action. You can use these headers to route data from IoT clients to downstream Kafka clusters without modifying your message payload.  
You can substitute this field using a substitution template. To understand how to pass an inline Rule's function as a substitution template in Kafka Action's header, see [Examples](#apache-kafka-rule-action-examples). For more information, see [Substitution templates](iot-substitution-templates.md).  
Headers in binary format are not supported.

partition (optional)  
The Kafka message partition.  
You can substitute this field using a substitution template. For more information, see [Substitution templates](iot-substitution-templates.md).

clientProperties  
An object that defines the properties of the Apache Kafka producer client.    
acks (optional)  
The number of acknowledgments the producer requires the server to have received before considering a request complete.  
If you specify 0 as the value, the producer won't wait for any acknowledgment from the server. If the server doesn't receive the message, the producer won't retry to send the message.  
Valid values: `-1`, `0`, `1`, `all`. The default value is `1`.  
bootstrap.servers  
A list of host and port pairs (for example, `host1:port1`, `host2:port2`) used to establish the initial connection to your Kafka cluster.  
compression.type (optional)  
The compression type for all data generated by the producer.  
Valid values: `none`, `gzip`, `snappy`, `lz4`, `zstd`. The default value is `none`.  
security.protocol  
The security protocol used to attach to your Kafka broker.  
Valid values: `SSL`, `SASL_SSL`. The default value is `SSL`.  
key.serializer  
Specifies how to turn the key objects that you provide with the`ProducerRecord` into bytes.  
Valid value: `StringSerializer`.  
value.serializer  
Specifies how to turn value objects that you provide with the `ProducerRecord` into bytes.  
Valid value: `ByteBufferSerializer`.  
ssl.truststore  
The truststore file in base64 format or the location of the truststore file in [AWS Secrets Manager](https://docs.aws.amazon.com/secretsmanager/latest/userguide/). This value isn't required if your truststore is trusted by Amazon certificate authorities (CA).  
This field supports substitution templates. If you use Secrets Manager to store the credentials required to connect to your Kafka broker, you can use the `get_secret` SQL function to retrieve the value for this field. For more information about substitution templates, see [Substitution templates](iot-substitution-templates.md). For more information about the `get_secret` SQL function, see [get\$1secret(secretId, secretType, key, roleArn)](iot-sql-functions.md#iot-sql-function-get-secret). If the truststore is in the form of a file, use the `SecretBinary` parameter. If the truststore is in the form of a string, use the `SecretString` parameter.  
The maximum size of this value is 65 KB.  
ssl.truststore.password  
The password for the truststore. This value is required only if you've created a password for the truststore.  
ssl.keystore  
The keystore file. This value is required when you specify `SSL` as the value for `security.protocol`.  
This field supports substitution templates. Use Secrets Manager to store the credentials required to connect to your Kafka broker. To retrieve the value for this field, use the `get_secret` SQL function. For more information about substitution templates, see [Substitution templates](iot-substitution-templates.md). For more information about the `get_secret` SQL function, see [get\$1secret(secretId, secretType, key, roleArn)](iot-sql-functions.md#iot-sql-function-get-secret). Use the `SecretBinary` parameter.  
ssl.keystore.password  
The store password for the keystore file. This value is required if you specify a value for `ssl.keystore`.  
The value of this field can be plaintext . This field also supports substitution templates. Use Secrets Manager to store the credentials required to connect to your Kafka broker. To retrieve the value for this field, use the `get_secret` SQL function. For more information about substitution templates, see [Substitution templates](iot-substitution-templates.md). For more information about the `get_secret` SQL function, see [get\$1secret(secretId, secretType, key, roleArn)](iot-sql-functions.md#iot-sql-function-get-secret). Use the `SecretString` parameter.  
ssl.key.password  
The password of the private key in your keystore file.  
This field supports substitution templates. Use Secrets Manager to store the credentials required to connect to your Kafka broker. To retrieve the value for this field, use the `get_secret` SQL function. For more information about substitution templates, see [Substitution templates](iot-substitution-templates.md). For more information about the `get_secret` SQL function, see [get\$1secret(secretId, secretType, key, roleArn)](iot-sql-functions.md#iot-sql-function-get-secret). Use the `SecretString` parameter.  
sasl.mechanism  
The security mechanism used to connect to your Kafka broker. This value is required when you specify `SASL_SSL` for `security.protocol`.  
Valid values: `PLAIN`, `SCRAM-SHA-512`, `GSSAPI`.  
`SCRAM-SHA-512` is the only supported security mechanism in the cn-north-1, cn-northwest-1, us-gov-east-1, and us-gov-west-1 Regions.  
sasl.plain.username  
The username used to retrieve the secret string from Secrets Manager. This value is required when you specify `SASL_SSL` for `security.protocol` and `PLAIN` for `sasl.mechanism`.  
sasl.plain.password  
The password used to retrieve the secret string from Secrets Manager. This value is required when you specify `SASL_SSL` for `security.protocol` and `PLAIN` for `sasl.mechanism`.  
sasl.scram.username  
The username used to retrieve the secret string from Secrets Manager. This value is required when you specify `SASL_SSL` for `security.protocol` and `SCRAM-SHA-512` for `sasl.mechanism`.  
sasl.scram.password  
The password used to retrieve the secret string from Secrets Manager. This value is required when you specify `SASL_SSL` for `security.protocol` and `SCRAM-SHA-512` for `sasl.mechanism`.  
sasl.kerberos.keytab  
The keytab file for Kerberos authentication in Secrets Manager. This value is required when you specify `SASL_SSL` for `security.protocol` and `GSSAPI` for `sasl.mechanism`.  
This field supports substitution templates. Use Secrets Manager to store the credentials required to connect to your Kafka broker. To retrieve the value for this field, use the `get_secret` SQL function. For more information about substitution templates, see [Substitution templates](iot-substitution-templates.md). For more information about the `get_secret` SQL function, see [get\$1secret(secretId, secretType, key, roleArn)](iot-sql-functions.md#iot-sql-function-get-secret). Use the `SecretBinary` parameter.  
sasl.kerberos.service.name  
The Kerberos principal name under which Apache Kafka runs. This value is required when you specify `SASL_SSL` for `security.protocol` and `GSSAPI` for `sasl.mechanism`.  
sasl.kerberos.krb5.kdc  
The hostname of the key distribution center (KDC) to which your Apache Kafka producer client connects. This value is required when you specify `SASL_SSL` for `security.protocol` and `GSSAPI` for `sasl.mechanism`.  
sasl.kerberos.krb5.realm  
The realm to which your Apache Kafka producer client connects. This value is required when you specify `SASL_SSL` for `security.protocol` and `GSSAPI` for `sasl.mechanism`.  
sasl.kerberos.principal  
The unique Kerberos identity to which Kerberos can assign tickets to access Kerberos-aware services. This value is required when you specify `SASL_SSL` for `security.protocol` and `GSSAPI` for `sasl.mechanism`.

## Examples


The following JSON example defines an Apache Kafka action in an AWS IoT rule. The following example passes the [ sourceIp()](iot-sql-functions.md#iot-function-sourceip) inline function as a [substitution template](https://docs.aws.amazon.com//iot/latest/developerguide/iot-substitution-templates.html) in the Kafka Action header.

```
{
	"topicRulePayload": {
		"sql": "SELECT * FROM 'some/topic'",
		"ruleDisabled": false,
		"awsIotSqlVersion": "2016-03-23",
		"actions": [
			{
				"kafka": {
					"destinationArn": "arn:aws:iot:region:123456789012:ruledestination/vpc/VPCDestinationARN",
					"topic": "TopicName",
					"clientProperties": {
						"bootstrap.servers": "kafka.com:9092",
						"security.protocol": "SASL_SSL",
						"ssl.truststore": "${get_secret('kafka_client_truststore', 'SecretBinary','arn:aws:iam::123456789012:role/kafka-get-secret-role-name')}",
						"ssl.truststore.password": "kafka password",
						"sasl.mechanism": "GSSAPI",
						"sasl.kerberos.service.name": "kafka",
						"sasl.kerberos.krb5.kdc": "kerberosdns.com",
						"sasl.kerberos.keytab": "${get_secret('kafka_keytab','SecretBinary', 'arn:aws:iam::123456789012:role/kafka-get-secret-role-name')}",
						"sasl.kerberos.krb5.realm": "KERBEROSREALM",
						"sasl.kerberos.principal": "kafka-keytab/kafka-keytab.com"
					},
					"headers": [
						{
							"key": "static_header_key",
							"value": "static_header_value"
						},
						{
							"key": "substitutable_header_key",
							"value": "${value_from_payload}"
						},
						{
							"key": "source_ip",
							"value": "${sourceIp()}"
						}
					]
				}
			}
		]
	}
}
```

**Important notes about your Kerberos setup**
+ Your key distribution center (KDC) must be resolvable through private Domain Name System (DNS) within your target VPC. One possible approach is to add the KDC DNS entry to a private hosted zone. For more information about this approach, see [Working with private hosted zones](https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/hosted-zones-private.html).
+ Each VPC must have DNS resolution enabled. For more information, see [Using DNS with your VPC](https://docs.aws.amazon.com/vpc/latest/userguide/vpc-dns.html).
+ Network interface security groups and instance-level security groups in the VPC destination must allow traffic from within your VPC on the following ports.
  + TCP traffic on the bootstrap broker listener port (often 9092, but must be within the 9000–9100 range)
  + TCP and UDP traffic on port 88 for the KDC
+ `SCRAM-SHA-512` is the only supported security mechanism in the cn-north-1, cn-northwest-1, us-gov-east-1, and us-gov-west-1 Regions.

# Apache Kafka Virtual Private Cloud (VPC) destinations


The Apache Kafka rule action routes data to an Apache Kafka cluster in an Amazon Virtual Private Cloud (Amazon VPC). The VPC configuration used by the Apache Kafka rule action is automatically enabled when you specify the VPC destination for your rule action.

An Apache Kafka Virtual Private Cloud (VPC) destination contains a list of subnets inside the VPC. The rules engine creates an elastic network interface in each subnet that you specify in this list. For more information about network interfaces, see [Elastic network interfaces](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-eni.html) in the Amazon EC2 User Guide.

## Requirements and considerations

+ If you're using a self-managed Apache Kafka cluster that will be accessed using a public endpoint across the internet:
  + Create a NAT gateway for instances in your subnets. The NAT gateway has a public IP address that can connect to the internet, which allows the rules engine to forward your messages to the public Kafka cluster.
  + Allocate an Elastic IP address with the elastic network interfaces (ENIs) that are created by the Apache Kafka Virtual Private Cloud (VPC) destination. The security groups that you use must be configured to block incoming traffic.
**Note**  
If the Apache Kafka Virtual Private Cloud (VPC) destination is disabled and then re-enabled, you must re-associate the elastic IPs with the new ENIs.
+ If an Apache Kafka Virtual Private Cloud (VPC) destination doesn't receive any traffic for 30 days in a row, it will be disabled.
+ If any resources used by the Apache Kafka Virtual Private Cloud (VPC) destination change, the destination will be disabled and unable to be used.
+ Some changes that can disable a Apache Kafka Virtual Private Cloud (VPC) destination include: 
  + Deleting the VPC, subnets, security groups, or the role used.
  + Modifying the role to no longer have the necessary permissions.
  + Reaching near subnet capacity which makes us unable to apply [ FedRAMP](https://aws.amazon.com/compliance/fedramp/) patching.
  + Disabling the destination.

## Pricing


For pricing purposes, a VPC rule action is metered in addition to the action that sends a message to a resource when the resource is in your VPC. For pricing information, see [AWS IoT Core pricing](https://aws.amazon.com/iot-core/pricing/).

## Creating Apache Kafka Virtual Private Cloud (VPC) destinations


You create a Apache Kafka Virtual Private Cloud (VPC) destination by using the [CreateTopicRuleDestination](https://docs.aws.amazon.com/iot/latest/apireference/API_CreateTopicRuleDestination.html) API or the AWS IoT Core console. 

When you create a destination, you must specify the following information.

vpcId  
The unique ID of the Amazon VPC.

subnetIds  
A list of subnets in which the rules engine creates elastic network interfaces. The rules engine allocates a single network interface for each subnet in the list.

securityGroups (optional)  
A list of security groups to apply to the network interfaces.

roleArn  
The Amazon Resource Name (ARN) of a role that has permission to create network interfaces on your behalf.  
This ARN should have a policy attached to it that looks like the following example.    
****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "ec2:CreateNetworkInterface",
                "ec2:DescribeNetworkInterfaces",
                "ec2:DescribeVpcs",
                "ec2:DeleteNetworkInterface",
                "ec2:DescribeSubnets",
                "ec2:DescribeVpcAttribute",
                "ec2:DescribeSecurityGroups"
            ],
            "Resource": "*"
        },
        {
            "Effect": "Allow",
            "Action": "ec2:CreateNetworkInterfacePermission",
            "Resource": "*",
            "Condition": {
                "StringEquals": {
                    "ec2:ResourceTag/VPCDestinationENI": "true"
            }
        }
        },
        {
            "Effect": "Allow",
            "Action": [
                "ec2:CreateTags"
            ],
            "Resource": "*",
            "Condition": {
                "StringEquals": {
                    "ec2:CreateAction": "CreateNetworkInterface",
                    "aws:RequestTag/VPCDestinationENI": "true"
            }
        }
        }
    ]
}
```

### Creating an Apache Kafka Virtual Private Cloud (VPC) destination by using AWS CLI


The following example shows how to create a destination by using AWS CLI.

```
aws --region regions iot create-topic-rule-destination --destination-configuration 'vpcConfiguration={subnetIds=["subnet-123456789101230456"],securityGroups=[],vpcId="vpc-123456789101230456",roleArn="arn:aws:iam::123456789012:role/role-name"}'
```

After you run this command, the destination status will be `IN_PROGRESS`. After a few minutes, its status will change to either `ERROR` (if the command isn't successful) or `ENABLED`. When the destination status is `ENABLED`, it's ready to use.

You can use the following command to get the status of your Apache Kafka Virtual Private Cloud (VPC) destination.

```
aws --region region iot get-topic-rule-destination --arn "VPCDestinationARN"
```

### Creating a Apache Kafka Virtual Private Cloud (VPC) destination by using the AWS IoT Core console


The following steps describe how to create a destination by using the AWS IoT Core console.

1. Navigate to the AWS IoT Core console. In the left pane, on the **Act** tab, choose **Destinations**.

1. Enter values for the following fields.
   + **VPC ID**
   + **Subnet IDs**
   + **Security Group**

1. Select a role that has the permissions required to create network interfaces. The preceding example policy contains these permissions.

When the Apache Kafka Virtual Private Cloud (VPC) destination status is **ENABLED**, it's ready to use.

# CloudWatch alarms


The CloudWatch alarm (`cloudWatchAlarm`) action changes the state of an Amazon CloudWatch alarm. You can specify the state change reason and value in this call. 

## Requirements


This rule action has the following requirements:
+ An IAM role that AWS IoT can assume to perform the `cloudwatch:SetAlarmState` operation. For more information, see [Granting an AWS IoT rule the access it requires](iot-create-role.md).

  In the AWS IoT console, you can choose or create a role to allow AWS IoT to perform this rule action.

## Parameters


When you create an AWS IoT rule with this action, you must specify the following information:

`alarmName`  
The CloudWatch alarm name.  
Supports [substitution templates](iot-substitution-templates.md): API and AWS CLI only

`stateReason`  
Reason for the alarm change.  
Supports [substitution templates](iot-substitution-templates.md): Yes

`stateValue`  
The value of the alarm state. Valid values: `OK`, `ALARM`, `INSUFFICIENT_DATA`.  
Supports [substitution templates](iot-substitution-templates.md): Yes

`roleArn`  
The IAM role that allows access to the CloudWatch alarm. For more information, see [Requirements](#cloudwatch-alarms-rule-action-requirements).  
Supports [substitution templates](iot-substitution-templates.md): No

## Examples


The following JSON example defines a CloudWatch alarm action in an AWS IoT rule.

```
{
    "topicRulePayload": {
        "sql": "SELECT * FROM 'some/topic'", 
        "ruleDisabled": false, 
        "awsIotSqlVersion": "2016-03-23",
        "actions": [
            {
                "cloudwatchAlarm": {
                    "alarmName": "IotAlarm", 
                    "stateReason": "Temperature stabilized.",
                    "stateValue": "OK",
                    "roleArn": "arn:aws:iam::123456789012:role/aws_iot_cw"
                }
            }
        ]
    }
}
```

## See also

+ [What is Amazon CloudWatch?](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/) in the *Amazon CloudWatch User Guide*
+ [Using Amazon CloudWatch alarms](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/AlarmThatSendsEmail.html) in the *Amazon CloudWatch User Guide*

# CloudWatch Logs


The CloudWatch Logs (`cloudwatchLogs`) action sends data to Amazon CloudWatch Logs. You can use `batchMode` to upload and timestamp multiple device log records in one message. You can also specify the log group where the action sends data.

## Requirements


This rule action has the following requirements:
+ An IAM role that AWS IoT can assume to perform the `logs:CreateLogStream`, `logs:DescribeLogStreams`, and `logs:PutLogEvents` operations. For more information, see [Granting an AWS IoT rule the access it requires](iot-create-role.md).

  In the AWS IoT console, you can choose or create a role to allow AWS IoT to perform this rule action.
+ If you use a customer managed AWS KMS key (KMS key) to encrypt log data in CloudWatch Logs, the service must have permission to use the KMS key on the caller's behalf. For more information, see [Encrypt log data in CloudWatch Logs using AWS KMS](https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/encrypt-log-data-kms.html) in the *Amazon CloudWatch Logs User Guide*.

## MQTT message format requirements for `batchMode`


If you use the CloudWatch Logs rule action with `batchMode` turned off, there are no MQTT message formatting requirements. (Note: the `batchMode` parameter's default value is `false`.) However, if you use the CloudWatch Logs rule action with `batchMode` turned on (the parameter value is `true`), MQTT messages containing device-side logs must be formatted to contain a timestamp and a message payload. **Note:** `timestamp` represents the time that the event occurred and is expressed as a number of milliseconds after January 1, 1970 00:00:00 UTC.

The following is an example of the publish format:

```
[
  {"timestamp": 1673520691093, "message": "Test message 1"}, 
  {"timestamp": 1673520692879, "message": "Test message 2"}, 
  {"timestamp": 1673520693442, "message": "Test message 3"}
]
```

Depending on how the device-side logs are generated, they might need to be filtered and reformatted before they're sent to comply with this requirement. For more information, see [MQTT Message payload](https://docs.aws.amazon.com/iot/latest/developerguide/topicdata.html).

Independent of the `batchMode` parameter, `message` contents must comply with AWS IoT message size limitations. For more information, see [AWS IoT Core endpoints and quotas](https://docs.aws.amazon.com/general/latest/gr/iot-core.html).

## Parameters


When you create an AWS IoT rule with this action, you must specify the following information:

`logGroupName`  
The CloudWatch log group where the action sends data.  
Supports [substitution templates](iot-substitution-templates.md): API and AWS CLI only

`roleArn`  
The IAM role that allows access to the CloudWatch log group. For more information, see [Requirements](#cloudwatch-logs-rule-action-requirements).   
Supports [substitution templates](iot-substitution-templates.md): No

(optional) `batchMode`  
 Indicates whether batches of log records will be extracted and uploaded into CloudWatch. Values include `true` or `false` (default). For more information, see [Requirements](#cloudwatch-logs-rule-action-requirements).   
Supports [substitution templates](iot-substitution-templates.md): No

## Examples


The following JSON example defines a CloudWatch Logs action in an AWS IoT rule.

```
{
    "topicRulePayload": {
        "sql": "SELECT * FROM 'some/topic'", 
        "ruleDisabled": false, 
        "awsIotSqlVersion": "2016-03-23",
        "actions": [
            {
                "cloudwatchLogs": {
                    "logGroupName": "IotLogs",
                    "roleArn": "arn:aws:iam::123456789012:role/aws_iot_cw",
                    "batchMode": false                    
                }
            }
        ]
    }
}
```

## See also

+ [What is Amazon CloudWatch Logs?](https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/) in the *Amazon CloudWatch Logs User Guide*

# CloudWatch metrics


The CloudWatch metric (`cloudwatchMetric`) action captures an Amazon CloudWatch metric. You can specify the metric namespace, name, value, unit, and timestamp. 

## Requirements


This rule action has the following requirements:
+ An IAM role that AWS IoT can assume to perform the `cloudwatch:PutMetricData` operation. For more information, see [Granting an AWS IoT rule the access it requires](iot-create-role.md).

  In the AWS IoT console, you can choose or create a role to allow AWS IoT to perform this rule action.

## Parameters


When you create an AWS IoT rule with this action, you must specify the following information:

`metricName`  
The CloudWatch metric name.  
Supports [substitution templates](iot-substitution-templates.md): Yes

`metricNamespace`  
The CloudWatch metric namespace name.  
Supports [substitution templates](iot-substitution-templates.md): Yes

`metricUnit`  
The metric unit supported by CloudWatch.  
Supports [substitution templates](iot-substitution-templates.md): Yes

`metricValue`  
A string that contains the CloudWatch metric value.  
Supports [substitution templates](iot-substitution-templates.md): Yes

`metricTimestamp`  
(Optional) A string that contains the timestamp, expressed in seconds in Unix epoch time. Defaults to the current Unix epoch time.  
Supports [substitution templates](iot-substitution-templates.md): Yes

`roleArn`  
The IAM role that allows access to the CloudWatch metric. For more information, see [Requirements](#cloudwatch-metrics-rule-action-requirements).  
Supports [substitution templates](iot-substitution-templates.md): No

## Examples


The following JSON example defines a CloudWatch metric action in an AWS IoT rule.

```
{
    "topicRulePayload": {
        "sql": "SELECT * FROM 'some/topic'", 
        "ruleDisabled": false, 
        "awsIotSqlVersion": "2016-03-23",
        "actions": [
            {
                "cloudwatchMetric": {
                    "metricName": "IotMetric",
                    "metricNamespace": "IotNamespace", 
                    "metricUnit": "Count",
                    "metricValue": "1",
                    "metricTimestamp": "1456821314",
                    "roleArn": "arn:aws:iam::123456789012:role/aws_iot_cw"
                }
            }
        ]
    }
}
```

The following JSON example defines a CloudWatch metric action with substitution templates in an AWS IoT rule.

```
{
    "topicRulePayload": {
        "sql": "SELECT * FROM 'some/topic'",
        "ruleDisabled": false,
        "awsIotSqlVersion": "2016-03-23",
        "actions": [
            {
                "cloudwatchMetric": {
                    "metricName": "${topic()}",
                    "metricNamespace": "${namespace}",
                    "metricUnit": "${unit}",
                    "metricValue": "${value}",
                    "roleArn": "arn:aws:iam::123456789012:role/aws_iot_cw"
                }
            }
        ]
    }
}
```

## See also

+ [What is Amazon CloudWatch?](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/) in the *Amazon CloudWatch User Guide*
+ [Using Amazon CloudWatch metrics](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/working_with_metrics.html) in the *Amazon CloudWatch User Guide*

# DynamoDB


The DynamoDB (`dynamoDB`) action writes all or part of an MQTT message to an Amazon DynamoDB table. 

You can follow a tutorial that shows you how to create and test a rule with a DynamoDB action. For more information, see [Tutorial: Storing device data in a DynamoDB table](iot-ddb-rule.md).

**Note**  
This rule writes non-JSON data to DynamoDB as binary data. The DynamoDB console displays the data as base64-encoded text.

## Requirements


This rule action has the following requirements:
+ An IAM role that AWS IoT can assume to perform the `dynamodb:PutItem` operation. For more information, see [Granting an AWS IoT rule the access it requires](iot-create-role.md).

  In the AWS IoT console, you can choose or create a role to allow AWS IoT to perform this rule action.
+  If you use a customer managed AWS KMS key (KMS key) to encrypt data at rest in DynamoDB, the service must have permission to use the KMS key on the caller's behalf. For more information, see [Customer Managed KMS key](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/encryption.howitworks.html#managed-cmk-customer-managed) in the *Amazon DynamoDB Getting Started Guide*.

## Parameters


When you create an AWS IoT rule with this action, you must specify the following information:

`tableName`  
The name of the DynamoDB table.  
Supports [substitution templates](iot-substitution-templates.md): API and AWS CLI only

`hashKeyField`  
The name of the hash key (also called the partition key).  
Supports [substitution templates](iot-substitution-templates.md): API and AWS CLI only

`hashKeyType`  
(Optional) The data type of the hash key (also called the partition key). Valid values: `STRING`, `NUMBER`.  
Supports [substitution templates](iot-substitution-templates.md): API and AWS CLI only

`hashKeyValue`  
The value of the hash key. Consider using a substitution template such as `${topic()}` or `${timestamp()}`.  
Supports [substitution templates](iot-substitution-templates.md): Yes

`rangeKeyField`  
(Optional) The name of the range key (also called the sort key).  
Supports [substitution templates](iot-substitution-templates.md): API and AWS CLI only

`rangeKeyType`  
(Optional) The data type of the range key (also called the sort key). Valid values: `STRING`, `NUMBER`.  
Supports [substitution templates](iot-substitution-templates.md): API and AWS CLI only

`rangeKeyValue`  
(Optional) The value of the range key. Consider using a substitution template such as `${topic()}` or `${timestamp()}`.  
Supports [substitution templates](iot-substitution-templates.md): Yes

`payloadField`  
(Optional) The name of the column where the payload is written. If you omit this value, the payload is written to the column named `payload`.  
Supports [substitution templates](iot-substitution-templates.md): Yes

`operation`  
(Optional) The type of operation to be performed. Valid values: `INSERT`, `UPDATE`, `DELETE`.  
Supports [substitution templates](iot-substitution-templates.md): Yes

`roleARN`  
The IAM role that allows access to the DynamoDB table. For more information, see [Requirements](#dynamodb-rule-action-requirements).  
Supports [substitution templates](iot-substitution-templates.md): No

The data written to the DynamoDB table is the result from the SQL statement of the rule.

## Examples


The following JSON example defines a DynamoDB action in an AWS IoT rule.

```
{
    "topicRulePayload": {
        "sql": "SELECT * AS message FROM 'some/topic'", 
        "ruleDisabled": false,
        "awsIotSqlVersion": "2016-03-23",
        "actions": [
            {
                "dynamoDB": {
                    "tableName": "my_ddb_table",
                    "hashKeyField": "key",
                    "hashKeyValue": "${topic()}",
                    "rangeKeyField": "timestamp",
                    "rangeKeyValue": "${timestamp()}",
                    "roleArn": "arn:aws:iam::123456789012:role/aws_iot_dynamoDB"
                }
            }
        ]
    }
}
```

## See also

+ [What is Amazon DynamoDB?](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/) in the *Amazon DynamoDB Developer Guide*
+ [Getting started with DynamoDB](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/GettingStartedDynamoDB.html) in the *Amazon DynamoDB Developer Guide*
+ [Tutorial: Storing device data in a DynamoDB table](iot-ddb-rule.md)

# DynamoDBv2


The DynamoDBv2 (`dynamoDBv2`) action writes all or part of an MQTT message to an Amazon DynamoDB table. Each attribute in the payload is written to a separate column in the DynamoDB database.

## Requirements


This rule action has the following requirements:
+ An IAM role that AWS IoT can assume to perform the `dynamodb:PutItem` operation. For more information, see [Granting an AWS IoT rule the access it requires](iot-create-role.md).

  In the AWS IoT console, you can choose or create a role to allow AWS IoT to perform this rule action.
+ The MQTT message payload must contain a root-level key that matches the table's primary partition key and a root-level key that matches the table's primary sort key, if one is defined.
+ If you use a customer managed AWS KMS key (KMS key) to encrypt data at rest in DynamoDB, the service must have permission to use the KMS key on the caller's behalf. For more information, see [Customer Managed KMS key](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/encryption.howitworks.html#managed-cmk-customer-managed) in the *Amazon DynamoDB Getting Started Guide*.

## Parameters


When you create an AWS IoT rule with this action, you must specify the following information:

`putItem`  
An object that specifies the DynamoDB table to which the message data will be written. This object must contain the following information:    
`tableName`  
The name of the DynamoDB table.  
Supports [substitution templates](iot-substitution-templates.md): API and AWS CLI only

`roleARN`  
The IAM role that allows access to the DynamoDB table. For more information, see [Requirements](#dynamodb-v2-rule-action-requirements).  
Supports [substitution templates](iot-substitution-templates.md): No

The data written to the DynamoDB table is the result from the SQL statement of the rule.

## Examples


The following JSON example defines a DynamoDBv2 action in an AWS IoT rule.

```
{
    "topicRulePayload": {
        "sql": "SELECT * AS message FROM 'some/topic'", 
        "ruleDisabled": false,
        "awsIotSqlVersion": "2016-03-23",
        "actions": [
            {
                "dynamoDBv2": {
                    "putItem": {
                        "tableName": "my_ddb_table"
                    },
                    "roleArn": "arn:aws:iam::123456789012:role/aws_iot_dynamoDBv2", 
                }
            }
        ]
    }
}
```

The following JSON example defines a DynamoDB action with substitution templates in an AWS IoT rule.

```
{
    "topicRulePayload": {
        "sql": "SELECT * FROM 'some/topic'",
        "ruleDisabled": false,
        "awsIotSqlVersion": "2015-10-08",
        "actions": [
            {
                "dynamoDBv2": {
                    "putItem": {
                        "tableName": "${topic()}"
                    },
                    "roleArn": "arn:aws:iam::123456789012:role/aws_iot_dynamoDBv2"
                }
            }
        ]
    }
}
```

## See also

+ [What is Amazon DynamoDB?](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/) in the *Amazon DynamoDB Developer Guide*
+ [Getting started with DynamoDB](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/GettingStartedDynamoDB.html) in the *Amazon DynamoDB Developer Guide*

# Elasticsearch


The Elasticsearch (`elasticsearch`) action writes data from MQTT messages to an Amazon OpenSearch Service domain. You can then use tools like OpenSearch Dashboards to query and visualize data in OpenSearch Service.

**Warning**  
The `Elasticsearch` action can only be used by existing rule actions. To create a new rule action or to update an existing rule action, use the `OpenSearch` rule action instead. For more information, see [OpenSearch](opensearch-rule-action.md). 

## Requirements


This rule action has the following requirements:
+ An IAM role that AWS IoT can assume to perform the `es:ESHttpPut` operation. For more information, see [Granting an AWS IoT rule the access it requires](iot-create-role.md).

  In the AWS IoT console, you can choose or create a role to allow AWS IoT to perform this rule action.
+ If you use a customer managed AWS KMS key (KMS key) to encrypt data at rest in OpenSearch, the service must have permission to use the KMS key on the caller's behalf. For more information, see [Encryption of data at rest for Amazon OpenSearch Service](https://docs.aws.amazon.com/opensearch-service/latest/developerguide/encryption-at-rest.html) in the *Amazon OpenSearch Service Developer Guide*.

## Parameters


When you create an AWS IoT rule with this action, you must specify the following information:

`endpoint`  
The endpoint of your service domain.  
Supports [substitution templates](iot-substitution-templates.md): API and AWS CLI only

`index`  
The index where you want to store your data.  
Supports [substitution templates](iot-substitution-templates.md): Yes

`type`  
The type of document you are storing.  
Supports [substitution templates](iot-substitution-templates.md): Yes

`id`  
The unique identifier for each document.  
Supports [substitution templates](iot-substitution-templates.md): Yes

`roleARN`  
The IAM role that allows access to the OpenSearch Service domain. For more information, see [Requirements](#elasticsearch-rule-action-requirements).  
Supports [substitution templates](iot-substitution-templates.md): No

## Examples


The following JSON example defines an Elasticsearch action in an AWS IoT rule and how you can specify the fields for the `elasticsearch` action. For more information, see [ElasticsearchAction](https://docs.aws.amazon.com/iot/latest/apireference/API_ElasticsearchAction.html).

```
{
    "topicRulePayload": {
        "sql": "SELECT *, timestamp() as timestamp FROM 'iot/test'",
        "ruleDisabled": false,
        "awsIotSqlVersion": "2016-03-23",
        "actions": [
            {
                "elasticsearch": {
                    "endpoint": "https://my-endpoint",
                    "index": "my-index",
                    "type": "my-type",
                    "id": "${newuuid()}",
                    "roleArn": "arn:aws:iam::123456789012:role/aws_iot_es"
                }
            }
        ]
    }
}
```

The following JSON example defines an Elasticsearch action with substitution templates in an AWS IoT rule.

```
{
    "topicRulePayload": {
        "sql": "SELECT * FROM 'some/topic'",
        "ruleDisabled": false,
        "awsIotSqlVersion": "2016-03-23",
        "actions": [
            {
                "elasticsearch": {
                    "endpoint": "https://my-endpoint",
                    "index": "${topic()}",
                    "type": "${type}",
                    "id": "${newuuid()}",
                    "roleArn": "arn:aws:iam::123456789012:role/aws_iot_es"
                }
            }
        ]
    }
}
```

## See also

+ [OpenSearch](opensearch-rule-action.md)
+ [What is Amazon OpenSearch Service?](https://docs.aws.amazon.com/opensearch-service/latest/developerguide/)

# HTTP


The HTTPS (`http`) action sends data from an MQTT message to an HTTPS endpoint, which can point to a web application or service.

## Requirements


This rule action has the following requirements:
+ You must confirm and enable HTTPS endpoints before the rules engine can use them. For more information, see [HTTP action destinations](http-action-destination.md).

## Parameters


When you create an AWS IoT rule with this action, you must specify the following information:

`url`  
The HTTPS endpoint where the message is sent using the HTTP POST method. If you use an IP address in place of a hostname, it must be an IPv4 address. IPv6 addresses are not supported.  
Supports [substitution templates](iot-substitution-templates.md): Yes

`confirmationUrl`  
(Optional) If specified, AWS IoT uses the confirmation URL to create a matching topic rule destination. You must enable the HTTP action destination before using it in an HTTP action. For more information, see [HTTP action destinations](http-action-destination.md). If you use substitution templates, you must manually create an HTTP action destination before the `http` action can be used. `confirmationUrl` must be a prefix of `url`.  
The relationship between `url` and `confirmationUrl` is described by the following:  
+ If `url` is hardcoded and `confirmationUrl` is not provided, we implicitly treat the `url` field as the `confirmationUrl`. AWS IoT creates a topic rule destination for `url`.
+ If `url` and `confirmationUrl` are hardcoded, `url` must begin with `confirmationUrl`. AWS IoT creates a topic rule destination for `confirmationUrl`.
+ If `url` contains a substitution template, you must specify `confirmationUrl` and `url` must begin with `confirmationUrl`. If `confirmationUrl` contains substitution templates, you must manually create an HTTP action destination before the `http` action can be used. If `confirmationUrl` does not contain substitution templates, AWS IoT creates a topic rule destination for `confirmationUrl`.
Supports [substitution templates](iot-substitution-templates.md): Yes

`headers`  
(Optional) The list of headers to include in HTTP requests to the endpoint. Each header must contain the following information:    
`key`  
The key of the header.  
Supports [substitution templates](iot-substitution-templates.md): No  
`value`  
The value of the header.  
Supports [substitution templates](iot-substitution-templates.md): Yes
The default content type is application/json when the payload is in JSON format. Otherwise, it is application/octet-stream. You can overwrite it by specifying the exact content type in the header with the key content-type (case insensitive). 

`auth`  
(Optional) The authentication used by the rules engine to connect to the endpoint URL specified in the `url` argument. Currently, Signature Version 4 is the only supported authentication type. For more information, see [HTTP Authorization](https://docs.aws.amazon.com/iot/latest/apireference/API_HttpAuthorization.html).  
Supports [substitution templates](iot-substitution-templates.md): No

`enableBatching`  
(Optional) Whether to process the HTTP action messages into a single request for a given url. Value can be true or false. For more information on batching, see [Batching HTTP action messages](http_batching.md).  
Boolean value  
Supports [substitution templates](iot-substitution-templates.md): No

`batchConfig`  
(Optional) Configuration settings for batching. Once enabled, `batchConfig` parameters must be specified. If `batchConfig` parameters are not specified, the default values will be used.    
`maxBatchOpenMs`  
The maximum amount of time (in milliseconds) an outgoing message waits for other messages to create the batch. The higher the setting, the longer the latency of the batched HTTP action.  
Minimum Value: 5 ms. Maximum Value: 200 ms.  
Default Value: 20 ms  
Supports [substitution templates](iot-substitution-templates.md): No  
`maxBatchSize`  
The maximum number of messages that are batched together in a single action execution.  
Supports [substitution templates](iot-substitution-templates.md): No  
Minimum Value: 2 messages. Maximum Value: 10 messages  
Default Value: 10 messages  
`maxBatchSizeBytes`  
Maximum size of a message batch, in bytes.  
Minimum Value: 100 bytes. Maximum Value: 131,072 bytes  
Default Value: 5,120 bytes  
Supports [substitution templates](iot-substitution-templates.md): No
The default content type is application/json when the payload is in JSON format. Otherwise, it is application/octet-stream. You can overwrite it by specifying the exact content type in the header with the key content-type (case insensitive). 

## Examples


The following JSON example defines an AWS IoT rule with an HTTP action.

```
{
    "topicRulePayload": {
        "sql": "SELECT * FROM 'some/topic'", 
        "ruleDisabled": false,
        "awsIotSqlVersion": "2016-03-23", 
        "actions": [
            { 
                "http": { 
                    "url": "https://www.example.com/subpath",
                    "confirmationUrl": "https://www.example.com", 
                    "headers": [
                        { 
                            "key": "static_header_key", 
                            "value": "static_header_value" 
                        },
                        { 
                            "key": "substitutable_header_key", 
                            "value": "${value_from_payload}" 
                        }
                    ] 
                } 
            }
        ]
    }
}
```

```
"http": { 
    "url": "https://www.example.com/subpath",
    "confirmationUrl": "https://www.example.com", 
    "headers": [
        { 
            "key": "Content-Type",
            "value": "application/json"
          }
    ],
    "enableBatching": true, 
    "batchConfig": {     
      "maxBatchOpenMs": 123, 
      "maxBatchSize": 5, 
      "maxBatchSizeBytes": 131072,
     }
 },
 "errorAction": { 
        "http": { 
            "url": "https://www.example.com/subpath",
            "confirmationUrl": "https://www.example.com"
            // batchConfig is not allowed here
        }
}
```

## HTTP action retry logic


The AWS IoT rules engine retries the HTTP action according to these rules:
+ The rules engine tries to send a message at least once.
+ The rules engine retries at most twice. The maximum number of tries is three.
+ The rules engine does not attempt a retry if:
  + The previous try provided a response larger than 16,384 bytes.
  + The downstream web service or application closes the TCP connection after the try.
  + The total time to complete a request with retries exceeded the request timeout limit.
  + The request returns an HTTP status code other than 429, 500-599.

**Note**  
[Standard data transfer costs](https://aws.amazon.com/ec2/pricing/on-demand/) apply to retries.

## See also

+ [Batching HTTP action messages](http_batching.md)
+ [HTTP action destinations](http-action-destination.md)
+ [Route data directly from AWS IoT Core to your web services](https://aws.amazon.com/blogs/iot/route-data-directly-from-iot-core-to-your-web-services/) in the *Internet of Things on AWS* blog

# Batching HTTP action messages


You can use batching to send multiple HTTP action messages in a single request.

## Overview


Batching enables you to send messages from AWS IoT Core Rules Engine to your HTTP endpoints in batches. This functionality can help reduce your costs by lowering the number of HTTP action executions as well as improve efficiency by reducing the overhead associated with establishing new connections.

**Note**  
The batched HTTP action is metered as a single action. You are metered in increments of 5 kiB, based on the size of outbound batched payload emitted by the AWS IoT Core Rules Engine to the downstream service. For more information, see the [AWS IoT Core pricing page](https://aws.amazon.com/iot-core/pricing/).

When you enable batching in the definition of your IoT Rule Action, the following parameters will be available for configuration:

`maxBatchOpenMs`  
The maximum amount of time (in milliseconds) an outgoing message waits for other messages to create the batch. The higher the setting, the longer the latency of the batched HTTP action.  
Minimum Value: 5 ms. Maximum Value: 200 ms.  
Default Value: 20 ms  
Supports [substitution templates](iot-substitution-templates.md): No

`maxBatchSize`  
The maximum number of messages that are batched together in a single IoT rule action execution.  
Minimum Value: 2 messages. Maximum Value: 10 messages  
Default Value: 10 messages  
Supports [substitution templates](iot-substitution-templates.md): No

`maxBatchSizeBytes`  
Maximum size of a message batch, in bytes.  
Minimum Value: 100 bytes. Maximum Value: 131,072 bytes  
Default Value: 5120 bytes  
Supports [substitution templates](iot-substitution-templates.md): No

**Important**  
When you specify multiple batch parameters, batching completes when the first limit is reached. For example, if you specify 100 ms as the Maximum Batch Open Time and 5 kiB as the Maximum Batch Size, and Rules Engine batches only 2 kiB within 100 ms, then a 2 kiB batch will be created and sent.

## Using HTTP headers in a batch


When you use headers in your HTTP action, the batched request uses the header value from the last message that was added to the batch (not necessarily the last message you published). We recommend using header values that are either:
+ Identical across all messages in the batch
+ Applicable to all messages (for example, authentication credentials)

The headers are sent with the HTTP request and are not part of the message body.

**Note**  
When batching is enabled:  
The batched request automatically includes the `Content-Type: application/json` header, as the batch is sent as a JSON array.
We can't guarantee that the last message in the batch is the last message that you published. It is the last message that made it into the batch.

## Payload Example


The following example shows the structure of a batched message payload sent to your HTTP endpoint:

```
[
  {
    "user_id": "user1",
    "steps_today": 1000
  },
  {
    "user_id": "user2",
    "steps_today": 21000
  },
  {
    "user_id": "user8",
    "steps_today": 1500
  },
  ...
]
```

## Limitations


The following are limitations on batching:
+ AWS IoT Core does not guarantee overall message ordering. Batching is performed locally on each host, which may result in messages within a batch being processed in a different order than they were received.
+ AWS IoT Core does not provide message processing support on the receiver side. You are responsible for ensuring that your downstream service is configured to accept and process data in batches.
+ Cross-account batching is not supported, even if messages are destined for the same resource identifier (HTTP URL or resource ARN).
+ AWS IoT Core does not guarantee that the batch size will meet the configuration you specified. Batches may be smaller than your configured limits based on timing and message flow.
+ When batching is enabled, binary payloads (non-UTF-8 data) are not supported. Only UTF-8 text payloads (such as JSON) are accepted. To send binary data, base64 encode it before sending it to the HTTP action, and then decode it at your receiving endpoint. For example, you can use the [encode function](iot-sql-functions.html#iot-function-encode) in IoT rules to encode the binary payload. Alternatively, you can encode the binary payload in your IoT device and publish it to AWS IoT Core.

## Error Actions for Batching


You will not be able to define a separate batching logic in your Error Action definition. However, your Error Action will support batching if you have defined batching logic in your primary Action.

When a batch request fails, AWS IoT Core Rules engine will follow the [HTTP action retry logic](https-rule-action.md#https-rule-action-retry-logic). After the final retry attempt, an error action will be invoked for the entire failed batch.

The following is an example of an error action message with batching enabled:

```
{
    "ruleName": "FailedTopicRule",
    "topic": "topic/rulesengine",
    "payloadsWithMetadata": [
        {
            "id": 1,
            "cloudwatchTraceId": "bebd6d93-6d4a-899e-9e40-56e82252d2be",
            "clientId": "Test",
            "sourceIp": "10.0.0.0",
            "base64OriginalPayload": "eyJ1c2VyX2lkIjogInVzZXI1NjQ3IiwgInN0ZXBzX3RvZGF5IjogMTMzNjUsICJ0aW1lc3RhbXAiOiAiMjAyNS0xMC0wOVQwNzoyMjo1OC45ODQ3OTAxNzZaIn0="
        },
        {
            "id": 2,
            "cloudwatchTraceId": "af94d3b8-0b18-1dbf-2c7d-513f5cb9e2e1",
            "clientId": "Test",
            "sourceIp": "10.0.0.0",
            "base64OriginalPayload": "eyJ1c2VyX2lkIjogInVzZXI1NjQ3IiwgInN0ZXBzX3RvZGF5IjogMTMzNjUsICJ0aW1lc3RhbXAiOiAiMjAyNS0xMC0wOVQwNzoyMjo1OC45ODQ3OTAxNzZaIn0="
        },
        {
            "id": 3,
            "cloudwatchTraceId": "ca441266-c2ce-c916-6aee-b9e5c7831675",
            "clientId": "Test",
            "sourceIp": "10.0.0.0",
            "base64OriginalPayload": "eyJ1c2VyX2lkIjogInVzZXI1NjQ3IiwgInN0ZXBzX3RvZGF5IjogMTMzNjUsICJ0aW1lc3RhbXAiOiAiMjAyNS0xMC0wOVQwNzoyMjo1OC45ODQ3OTAxNzZaIn0="
        }
    ],
    "failures": [
        {
            "affectedIds": [
                1,
                2,
                3
            ],
            "failedAction": "HttpAction",
            "failedResource": "https://example.foobar.com/HttpAction",
            "errorMessage": "HttpAction failed to make a request to the specified endpoint. StatusCode: 500. Reason: Internal Server Error."
        },
        {
            "affectedIds": [
                3
            ],
            "failedAction": "S3Action",
            "failedResource": "amzn-s3-demo-bucket",
            "errorMessage": "Failed to put S3 object. The error received was The specified bucket does not exist"
        },
        {
            "affectedIds": [
                3
            ],
            "failedAction": "LambdaAction",
            "failedResource": "arn:aws:lambda:us-west-2:123456789012:function:dummy",
            "errorMessage": "Failed to invoke lambda function. Received Server error from Lambda. The error code is 403"
        }
    ]
}
```

**Note**  
Batched action failures also generate larger error action payloads which can increase the probability of error action failures due to size. You can monitor error action failures using the `ErrorActionFailure` metric. See [Rule action metrics](metrics_dimensions.md#rule-action-metrics) for more information.

## Batching HTTP action messages with the AWS CLI


### Creating or updating a rule action with batching


1. Use the appropriate AWS CLI command to create or update a rule:
   + To create a new rule, use the [create-topic-rule](https://docs.aws.amazon.com/cli/latest/reference/iot/create-topic-rule.html) command:

     ```
     aws iot create-topic-rule --rule-name myrule --topic-rule-payload file://myrule.json
     ```
   + To update an existing rule, use the [replace-topic-rule](https://docs.aws.amazon.com/cli/latest/reference/iot/replace-topic-rule.html) command:

     ```
     aws iot replace-topic-rule --rule-name myrule --topic-rule-payload file://myrule.json
     ```

1. Enable batching capabilities by setting the enableBatching parameter to true in your topic rule payload:

   ```
   {
           "topicRulePayload": {
           "sql": "SELECT * FROM 'some/topic'", 
           "ruleDisabled": false,
           "awsIotSqlVersion": "2016-03-23", 
           "actions": [
               { 
                   "http": { 
                       "url": "https://www.example.com/subpath",
                       "confirmationUrl": "https://www.example.com", 
                       "headers": [
                           { 
                               "key": "static_header_key", 
                               "value": "static_header_value" 
                           },
                           { 
                               "key": "substitutable_header_key", 
                               "value": "${value_from_payload}" 
                            }
                       ],
                       "enableBatching": true,
                       "batchConfig": {
                          "maxBatchOpenMs": 100,
                          "maxBatchSize": 5,
                          "maxBatchSizeBytes": 1024
                       }
                   }
               }
         ]
   }
   ```

1. Configure the batching parameters. You do not need to specify all batch parameters. You can choose to specify 1, 2, or all 3 batch parameters. If you do not specify a batch parameter, Rules Engine will update that parameter with the default values. For more information on batching parameters and their default values, see [HTTP parameters](https-rule-action.md#https-rule-action-parameters).

# HTTP action destinations


An HTTP action destination is a web service to which the rules engine can route data from a topic rule. An AWS IoT Core resource describes the web service for AWS IoT. Destination resources can be shared by different rules.

Before AWS IoT Core can send data to another web service, it must confirm that it can access the service's endpoint.

## Overview


An HTTP action destination refers to a web service that supports a confirmation URL and one or more data collection URLs. The destination resource contains the confirmation URL of your web service. When you configure an HTTP action, you specify the actual URL of the endpoint that should receive the data along with the web service's confirmation URL. After your destination is confirmed, the topic rule sends the result of the SQL statement to the HTTPS endpoint (and not to the confirmation URL).

An HTTP action destination can be in one of the following states:

ENABLED  
The destination has been confirmed and can be used by a rule action. A destination must be in the `ENABLED` state for it to be used in a rule. You can only enable a destination that's in DISABLED status.

DISABLED  
The destination has been confirmed but it can't be used by a rule action. This is useful if you want to temporarily prevent traffic to your endpoint without having to go through the confirmation process again. You can only disable a destination that's in ENABLED status.

IN\$1PROGRESS  
Confirmation of the destination is in progress.

ERROR  
Destination confirmation timed out.

After an HTTP action destination has been confirmed and enabled, it can be used with any rule in your account.

## Managing HTTP action destinations


You can use the following operations to manage your HTTP action destinations.

### Creating HTTP action destinations


You create an HTTP action destination by calling the `CreateTopicRuleDestination` operation or by using the AWS IoT console.

After you create a destination, AWS IoT sends a confirmation request to the confirmation URL. The confirmation request has the following format:

```
HTTP POST {confirmationUrl}/?confirmationToken={confirmationToken}
Headers:
x-amz-rules-engine-message-type: DestinationConfirmation
x-amz-rules-engine-destination-arn:"arn:aws:iot:us-east-1:123456789012:ruledestination/http/7a280e37-b9c6-47a2-a751-0703693f46e4"
Content-Type: application/json
Body:
{
    "arn":"arn:aws:iot:us-east-1:123456789012:ruledestination/http/7a280e37-b9c6-47a2-a751-0703693f46e4",  
    "confirmationToken": "AYADeMXLrPrNY2wqJAKsFNn-…NBJndA",
    "enableUrl": "https://iot.us-east-1.amazonaws.com/confirmdestination/AYADeMXLrPrNY2wqJAKsFNn-…NBJndA",
    "messageType": "DestinationConfirmation"
}
```

The content of the confirmation request includes the following information:

arn  
The Amazon Resource Name (ARN) for the HTTP action destination to confirm.

confirmationToken  
The confirmation token sent by AWS IoT Core. The token in the example is truncated. Your token will be longer. You'll need this token to confirm your destination with AWS IoT Core.

enableUrl  
The URL to which you browse to confirm a topic rule destination.

messageType  
The type of message.

### Confirming HTTP action destinations


To complete the endpoint confirmation process, if you're using the AWS CLI, you must perform the following steps after your confirmation URL receives the confirmation request.

1. 

**Confirm that the destination is ready to receive messages**  
To confirm that the HTTP action destination is ready to receive IoT messages, either call the `enableUrl` in the confirmation request, or perform the `ConfirmTopicRuleDestination` API operation and pass the `confirmationToken` from the confirmation request.

1. 

**Set topic rule status to enabled**  
After you've confirmed that the destination can receive messages, you must perform the `UpdateTopicRuleDestination` API operation to set the status of the topic rule to `ENABLED`.

If you're using the AWS IoT console, copy the `confirmationToken` and paste it into the destination's confirmation dialog in the AWS IoT console. You can then enable the topic rule.

### Sending a new confirmation request


To activate a new confirmation message for a destination, call `UpdateTopicRuleDestination` and set the topic rule destination's status to `IN_PROGRESS`. 

Repeat the confirmation process after you send a new confirmation request.

### Disabling and deleting an HTTP action destination


To disable a destination, call `UpdateTopicRuleDestination` and set the topic rule destination's status to `DISABLED`. A topic rule in the DISABLED state can be enabled again without the need to send a new confirmation request.

To delete an HTTP action destination, call `DeleteTopicRuleDestination`.

## Certificate Authority Support


**Note**  
Self-signed certificates are not supported. 

 HTTPS Endpoints in an HTTP action destination support certificates issued by both [AWS Private Certificate Authority ](https://www.amazontrust.com/repository/) and [Lets Encrypt](https://letsencrypt.org/certificates/). 

# AWS IoT Events


The AWS IoT Events (`iotEvents`) action sends data from an MQTT message to an AWS IoT Events input. 

**Important**  
If the payload is sent to AWS IoT Core without the `Input attribute Key`, or if the key isn't in the same JSON path specified in the key, it will cause the IoT rule to fail with the error `Failed to send message to Iot Events`.

## Requirements


This rule action has the following requirements:
+ An IAM role that AWS IoT can assume to perform the `iotevents:BatchPutMessage` operation. For more information, see [Granting an AWS IoT rule the access it requires](iot-create-role.md).

  In the AWS IoT console, you can choose or create a role to allow AWS IoT to perform this rule action.

## Parameters


When you create an AWS IoT rule with this action, you must specify the following information:

`batchMode`  
(Optional) Whether to process the event actions as a batch. The default value is `false`.  
When `batchMode` is `true` and the rule SQL statement evaluates to an Array, each Array element is treated as a separate message when it's sent to AWS IoT Events by calling [https://docs.aws.amazon.com/iotevents/latest/apireference/API_iotevents-data_BatchPutMessage.html](https://docs.aws.amazon.com/iotevents/latest/apireference/API_iotevents-data_BatchPutMessage.html). The resulting array can't have more than 10 messages.  
When `batchMode` is `true`, you can't specify a `messageId`.   
Supports [substitution templates](iot-substitution-templates.md): No

`inputName`  
The name of the AWS IoT Events input.  
Supports [substitution templates](iot-substitution-templates.md): API and AWS CLI only

`messageId`  
(Optional) Use this to verify that only one input (message) with a given `messageId` is processed by an AWS IoT Events detector. You can use the `${newuuid()}` substitution template to generate a unique ID for each request.  
When `batchMode` is `true`, you can't specify a `messageId`--a new UUID value will be assigned.  
Supports [substitution templates](iot-substitution-templates.md): Yes

`roleArn`  
The IAM role that allows AWS IoT to send an input to an AWS IoT Events detector. For more information, see [Requirements](#iotevents-rule-action-requirements).  
Supports [substitution templates](iot-substitution-templates.md): No

## Examples


The following JSON example defines an IoT Events action in an AWS IoT rule.

```
{
    "topicRulePayload": {
        "sql": "SELECT * FROM 'some/topic",
        "ruleDisabled": false,
        "awsIotSqlVersion": "2016-03-23",
        "actions": [
            {
                "iotEvents": {
                    "inputName": "MyIoTEventsInput",
                    "messageId": "${newuuid()}",
                    "roleArn": "arn:aws:iam::123456789012:role/aws_iot_events"
                }
            }
        ]
    }
}
```

## See also

+ [What is AWS IoT Events?](https://docs.aws.amazon.com/iotevents/latest/developerguide/) in the *AWS IoT Events Developer Guide*

# AWS IoT SiteWise


The AWS IoT SiteWise (`iotSiteWise`) action sends data from an MQTT message to asset properties in AWS IoT SiteWise.

You can follow a tutorial that shows you how to ingest data from AWS IoT things. For more information, see the [Ingesting data to AWS IoT SiteWise from AWS IoT things](https://docs.aws.amazon.com/iot-sitewise/latest/userguide/ingest-data-from-iot-things.html) tutorial or the [Ingesting data using AWS IoT Core rules](https://docs.aws.amazon.com/iot-sitewise/latest/userguide/iot-rules.html) section in the *AWS IoT SiteWise User Guide*.

## Requirements


This rule action has the following requirements:
+ An IAM role that AWS IoT can assume to perform the `iotsitewise:BatchPutAssetPropertyValue` operation. For more information, see [Granting an AWS IoT rule the access it requires](iot-create-role.md).

  You can attach the following example trust policy to the role.  
****  

  ```
  {
      "Version":"2012-10-17",		 	 	 
      "Statement": [
          {
              "Effect": "Allow",
              "Action": "iotsitewise:BatchPutAssetPropertyValue",
              "Resource": "*"
          }
      ]
  }
  ```

  To improve security, you can specify an AWS IoT SiteWise asset hierarchy path in the `Condition` property. The following example is a trust policy that specifies an asset hierarchy path.  
****  

  ```
  {
      "Version":"2012-10-17",		 	 	 
      "Statement": [
          {
              "Effect": "Allow",
              "Action": "iotsitewise:BatchPutAssetPropertyValue",
              "Resource": "*",
              "Condition": {
                  "StringLike": {
                      "iotsitewise:assetHierarchyPath": [
                          "/root node asset ID",
                          "/root node asset ID/*"
                      ]
              }
          }
          }
      ]
  }
  ```
+ When you send data to AWS IoT SiteWise with this action, your data must meet the requirements of the `BatchPutAssetPropertyValue` operation. For more information, see [BatchPutAssetPropertyValue](https://docs.aws.amazon.com/iot-sitewise/latest/APIReference/API_BatchPutAssetPropertyValue.html) in the *AWS IoT SiteWise API Reference*.

## Parameters


When you create an AWS IoT rule with this action, you must specify the following information:

`putAssetPropertyValueEntries`  
A list of asset property value entries that each contain the following information:    
`propertyAlias`  
(Optional) The property alias associated with your asset property. Specify either a `propertyAlias` or both an `assetId` and a `propertyId`. For more information about property aliases, see [Mapping industrial data streams to asset properties](https://docs.aws.amazon.com/iot-sitewise/latest/userguide/connect-data-streams.html) in the *AWS IoT SiteWise User Guide*.  
Supports [substitution templates](iot-substitution-templates.md): Yes  
`assetId`  
(Optional) The ID of the AWS IoT SiteWise asset. Specify either a `propertyAlias` or both an `assetId` and a `propertyId`.  
Supports [substitution templates](iot-substitution-templates.md): Yes  
`propertyId`  
(Optional) The ID of the asset's property. Specify either a `propertyAlias` or both an `assetId` and a `propertyId`.  
Supports [substitution templates](iot-substitution-templates.md): Yes  
`entryId`  
(Optional) A unique identifier for this entry. Define the `entryId` to better track which message caused an error if failure occurs. Defaults to a new UUID.  
Supports [substitution templates](iot-substitution-templates.md): Yes  
`propertyValues`  
A list of property values to insert that each contain timestamp, quality, and value (TQV) in the following format:    
`timestamp`  
A timestamp structure that contains the following information:    
`timeInSeconds`  
A string that contains the time in seconds in Unix epoch time. If your message payload doesn't have a timestamp, you can use [timestamp()](iot-sql-functions.md#iot-function-timestamp), which returns the current time in milliseconds. To convert that time to seconds, you can use the following substitution template: **\$1\$1floor(timestamp() / 1E3)\$1**.  
Supports [substitution templates](iot-substitution-templates.md): Yes  
`offsetInNanos`  
(Optional) A string that contains the nanosecond time offset from the time in seconds. If your message payload doesn't have a timestamp, you can use [timestamp()](iot-sql-functions.md#iot-function-timestamp), which returns the current time in milliseconds. To calculate the nanosecond offset from that time, you can use the following substitution template: **\$1\$1(timestamp() % 1E3) \$1 1E6\$1**.  
Supports [substitution templates](iot-substitution-templates.md): Yes
Regarding Unix epoch time, AWS IoT SiteWise accepts only entries that have a timestamp of up to 7 days in the past up to 5 minutes in the future.  
`quality`  
(Optional) A string that describes the quality of the value. Valid values: `GOOD`, `BAD`, `UNCERTAIN`.  
Supports [substitution templates](iot-substitution-templates.md): Yes  
`value`  
A value structure that contains one of the following value fields, depending on the asset property's data type:    
`booleanValue`  
(Optional) A string that contains the Boolean value of the value entry.  
Supports [substitution templates](iot-substitution-templates.md): Yes  
`doubleValue`  
(Optional) A string that contains the double value of the value entry.  
Supports [substitution templates](iot-substitution-templates.md): Yes  
`integerValue`  
(Optional) A string that contains the integer value of the value entry.  
Supports [substitution templates](iot-substitution-templates.md): Yes  
`stringValue`  
(Optional) The string value of the value entry.  
Supports [substitution templates](iot-substitution-templates.md): Yes

`roleArn`  
The ARN of the IAM role that grants AWS IoT permission to send an asset property value to AWS IoT SiteWise. For more information, see [Requirements](#iotsitewise-rule-action-requirements).  
Supports [substitution templates](iot-substitution-templates.md): No

## Examples


The following JSON example defines a basic IoT SiteWise action in an AWS IoT rule.

```
{
    "topicRulePayload": {
        "sql": "SELECT * FROM 'some/topic'",
        "ruleDisabled": false,
        "awsIotSqlVersion": "2016-03-23",
        "actions": [
            {
                "iotSiteWise": {
                    "putAssetPropertyValueEntries": [
                        {
                            "propertyAlias": "/some/property/alias",
                            "propertyValues": [
                                {
                                    "timestamp": {
                                        "timeInSeconds": "${my.payload.timeInSeconds}"
                                    },
                                    "value": {
                                        "integerValue": "${my.payload.value}"
                                    }
                                }
                            ]
                        }
                    ],
                    "roleArn": "arn:aws:iam::123456789012:role/aws_iot_sitewise"
                }
            }
        ]
    }
}
```

The following JSON example defines an IoT SiteWise action in an AWS IoT rule. This example uses the topic as the property alias and the `timestamp()` function. For example, if you publish data to `/company/windfarm/3/turbine/7/rpm`, this action sends the data to the asset property with a property alias that's the same as the topic that you specified.

```
{
    "topicRulePayload": {
        "sql": "SELECT * FROM '/company/windfarm/+/turbine/+/+'",
        "ruleDisabled": false,
        "awsIotSqlVersion": "2016-03-23",
        "actions": [
            {
                "iotSiteWise": {
                    "putAssetPropertyValueEntries": [
                        {
                            "propertyAlias": "${topic()}",
                            "propertyValues": [
                                {
                                    "timestamp": {
                                        "timeInSeconds": "${floor(timestamp() / 1E3)}",
                                        "offsetInNanos": "${(timestamp() % 1E3) * 1E6}"
                                    },
                                    "value": {
                                        "doubleValue": "${my.payload.value}"
                                    }
                                }
                            ]
                        }
                    ],
                    "roleArn": "arn:aws:iam::123456789012:role/aws_iot_sitewise"
                }
            }
        ]
    }
}
```

## See also

+ [What is AWS IoT SiteWise?](https://docs.aws.amazon.com/iot-sitewise/latest/userguide/what-is-sitewise.html) in the *AWS IoT SiteWise User Guide*
+ [Ingesting data using AWS IoT Core rules](https://docs.aws.amazon.com/iot-sitewise/latest/userguide/iot-rules.html) in the *AWS IoT SiteWise User Guide*
+ [Ingesting data to AWS IoT SiteWise from AWS IoT things](https://docs.aws.amazon.com/iot-sitewise/latest/userguide/ingest-data-from-iot-things.html) in the *AWS IoT SiteWise User Guide*
+ [Troubleshooting an AWS IoT SiteWise rule action](https://docs.aws.amazon.com/iot-sitewise/latest/userguide/troubleshoot-rule.html) in the *AWS IoT SiteWise User Guide*

# Firehose


The Firehose(`firehose`) action sends data from an MQTT message to an Amazon Data Firehose stream. 

## Requirements


This rule action has the following requirements:
+ An IAM role that AWS IoT can assume to perform the `firehose:PutRecord` operation. For more information, see [Granting an AWS IoT rule the access it requires](iot-create-role.md).

  In the AWS IoT console, you can choose or create a role to allow AWS IoT to perform this rule action.
+ If you use Firehose to send data to an Amazon S3 bucket, and you use an AWS KMS customer managed AWS KMS key to encrypt data at rest in Amazon S3, Firehose must have access to your bucket and permission to use the AWS KMS key on the caller's behalf. For more information, see [Grant Firehose access to an Amazon S3 destination](https://docs.aws.amazon.com/firehose/latest/dev/controlling-access.html#using-iam-s3) in the *Amazon Data Firehose Developer Guide*.

## Parameters


When you create an AWS IoT rule with this action, you must specify the following information:

`batchMode`  
(Optional) Whether to deliver the Firehose stream as a batch by using [https://docs.aws.amazon.com/firehose/latest/APIReference/API_PutRecordBatch.html](https://docs.aws.amazon.com/firehose/latest/APIReference/API_PutRecordBatch.html) . The default value is `false`.  
When `batchMode` is `true` and the rule's SQL statement evaluates to an Array, each Array element forms one record in the `PutRecordBatch` request. The resulting array can't have more than 500 records.   
Supports [substitution templates](iot-substitution-templates.md): No

`deliveryStreamName`  
The Firehose stream to which to write the message data.  
Supports [substitution templates](iot-substitution-templates.md): API and AWS CLI only

`separator`  
(Optional) A character separator that is used to separate records written to the Firehose stream. If you omit this parameter, the stream uses no separator. Valid values: `,` (comma), `\t` (tab), `\n` (newline), `\r\n` (Windows newline).  
Supports [substitution templates](iot-substitution-templates.md): No

`roleArn`  
The IAM role that allows access to the Firehose stream. For more information, see [Requirements](#kinesis-firehose-rule-action-requirements).  
Supports [substitution templates](iot-substitution-templates.md): No

## Examples


The following JSON example defines a Firehose action in an AWS IoT rule.

```
{
    "topicRulePayload": {
        "sql": "SELECT * FROM 'some/topic'", 
        "ruleDisabled": false, 
        "awsIotSqlVersion": "2016-03-23",
        "actions": [
            {
                "firehose": {
                    "deliveryStreamName": "my_firehose_stream",
                    "roleArn": "arn:aws:iam::123456789012:role/aws_iot_firehose"
                }
            }
        ] 
    }
}
```

The following JSON example defines a Firehose action with substitution templates in an AWS IoT rule.

```
{
    "topicRulePayload": {
        "sql": "SELECT * FROM 'some/topic'",
        "ruleDisabled": false,
        "awsIotSqlVersion": "2016-03-23",
        "actions": [
            {
                "firehose": {
                    "deliveryStreamName": "${topic()}",
                    "roleArn": "arn:aws:iam::123456789012:role/aws_iot_firehose"
                }
            }
        ]
    }
}
```

## See also

+ [What is Amazon Data Firehose?](https://docs.aws.amazon.com/firehose/latest/dev/) in the *Amazon Data Firehose Developer Guide*

# Kinesis Data Streams


The Kinesis Data Streams (`kinesis`) action writes data from an MQTT message to Amazon Kinesis Data Streams. 

## Requirements


This rule action has the following requirements:
+ An IAM role that AWS IoT can assume to perform the `kinesis:PutRecord` operation. For more information, see [Granting an AWS IoT rule the access it requires](iot-create-role.md).

  In the AWS IoT console, you can choose or create a role to allow AWS IoT to perform this rule action.
+ If you use an AWS KMS customer-managed AWS KMS key (KMS key) to encrypt data at rest in Kinesis Data Streams, the service must have permission to use the AWS KMS key on the caller's behalf. For more information, see [Permissions to use user-generated AWS KMS keys](https://docs.aws.amazon.com/streams/latest/dev/permissions-user-key-KMS.html) in the *Amazon Kinesis Data Streams Developer Guide*.

## Parameters


When you create an AWS IoT rule with this action, you must specify the following information:

`stream`  
The Kinesis data stream to which to write data.  
Supports [substitution templates](iot-substitution-templates.md): API and AWS CLI only

`partitionKey`  
The partition key used to determine to which shard the data is written. The partition key is usually composed of an expression (for example, `${topic()}` or `${timestamp()}`).  
Supports [substitution templates](iot-substitution-templates.md): Yes

`roleArn`  
The ARN of the IAM role that grants AWS IoT permission to access the Kinesis data stream. For more information, see [Requirements](#kinesis-rule-action-requirements).  
Supports [substitution templates](iot-substitution-templates.md): No

## Examples


The following JSON example defines a Kinesis Data Streams action in an AWS IoT rule.

```
{
    "topicRulePayload": {
        "sql": "SELECT * FROM 'some/topic'", 
        "ruleDisabled": false, 
        "awsIotSqlVersion": "2016-03-23",
        "actions": [
            {
                "kinesis": {
                    "streamName": "my_kinesis_stream", 
                    "partitionKey": "${topic()}",
                    "roleArn": "arn:aws:iam::123456789012:role/aws_iot_kinesis"
                }
            }
        ] 
    }
}
```

The following JSON example defines a Kinesis action with substitution templates in an AWS IoT rule.

```
{
    "topicRulePayload": {
        "sql": "SELECT * FROM 'some/topic'",
        "ruleDisabled": false,
        "awsIotSqlVersion": "2016-03-23",
        "actions": [
            {
                "kinesis": {
                    "streamName": "${topic()}",
                    "partitionKey": "${timestamp()}",
                    "roleArn": "arn:aws:iam::123456789012:role/aws_iot_kinesis"
                }
            }
        ]
    }
}
```

## See also

+ [What is Amazon Kinesis Data Streams?](https://docs.aws.amazon.com/streams/latest/dev/) in the *Amazon Kinesis Data Streams Developer Guide*

# Lambda


A Lambda (`lambda`) action invokes an AWS Lambda function, passing in an MQTT message. AWS IoT invokes Lambda functions asynchronously.

You can follow a tutorial that shows you how to create and test a rule with a Lambda action. For more information, see [Tutorial: Formatting a notification by using an AWS Lambda function](iot-lambda-rule.md).

## Requirements


This rule action has the following requirements:
+ For AWS IoT to invoke a Lambda function, you must configure a policy that grants the `lambda:InvokeFunction` permission to AWS IoT. You can only invoke a Lambda function defined in the same AWS Region where your Lambda policy exists. Lambda functions use resource-based policies, so you must attach the policy to the Lambda function itself. 

  Use the following AWS CLI command to attach a policy that grants the `lambda:InvokeFunction` permission. In this command, replace:
  + *function\$1name* with the name of the Lambda function. You add a new permission to update the function's resource policy.
  + *region* with the AWS Region of the function.
  + *account-id* with the AWS account number where the rule is defined.
  + *rule-name* with the name of the AWS IoT rule for which you are defining the Lambda action.
  + *unique\$1id* with a unique statement identifier.
**Important**  
If you add a permission for an AWS IoT principal without providing the `source-arn` or `source-account`, any AWS account that creates a rule with your Lambda action can activate rules to invoke your Lambda function from AWS IoT.

  For more information, see [AWS Lambda permissions](https://docs.aws.amazon.com/lambda/latest/dg/intro-permission-model.html).

  ```
  aws lambda add-permission \ 
      --function-name function_name \ 
      --region region \ 
      --principal iot.amazonaws.com \
      --source-arn arn:aws:iot:region:account-id:rule/rule_name \
      --source-account account-id 
      --statement-id unique_id 
      --action "lambda:InvokeFunction"
  ```
+ If you use the AWS IoT console to create a rule for the Lambda rule action, the Lambda function is triggered automatically. If you use AWS CloudFormation instead with the [https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-iot-topicrule-lambdaaction.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-iot-topicrule-lambdaaction.html), you must add an [https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-lambda-permission.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-lambda-permission.html) resource. The resource then grants you permission to trigger the Lambda function.

  The following code shows an example of how to add this resource. In this example, replace:
  + *function\$1name* with the name of the Lambda function.
  + *region* with the AWS Region of the function.
  + *account-id* with the AWS account number where the rule is defined.
  + *rule-name* with the name of the AWS IoT rule for which you are defining the Lambda action.

  ```
  Type: AWS::Lambda::Permission
  Properties:
    Action: lambda:InvokeFunction
    FunctionName: !Ref function_name
    Principal: "iot.amazonaws.com"
    SourceAccount: account-id
    SourceArn: arn:aws:iot:region:account-id:rule/rule_name
  ```
+ If you use an AWS KMS customer managed AWS KMS key to encrypt data at rest in Lambda, the service must have permission to use the AWS KMS key on the caller's behalf. For more information, see [Encryption at rest](https://docs.aws.amazon.com/lambda/latest/dg/security-dataprotection.html#security-privacy-atrest) in the *AWS Lambda Developer Guide*.

## Parameters


When you create an AWS IoT rule with this action, you must specify the following information:

`functionArn`  
The ARN of the Lambda function to invoke. AWS IoT must have permission to invoke the function. For more information, see [Requirements](#lambda-rule-action-requirements).  
If you don't specify a version or alias for your Lambda function, the most recent version of the function is shut down. You can specify a version or alias if you want to shut down a specific version of your Lambda function. To specify a version or alias, append the version or alias to the ARN of the Lambda function.  

```
arn:aws:lambda:us-east-2:123456789012:function:myLambdaFunction:someAlias
```
For more information about versioning and aliases, and see [AWS Lambda function versioning and aliases](https://docs.aws.amazon.com/lambda/latest/dg/versioning-aliases.html).  
Supports [substitution templates](iot-substitution-templates.md): API and AWS CLI only

## Examples


The following JSON example defines a Lambda action in an AWS IoT rule.

```
{
    "topicRulePayload": {
        "sql": "SELECT * FROM 'some/topic'", 
        "ruleDisabled": false, 
        "awsIotSqlVersion": "2016-03-23",
        "actions": [
            {
                "lambda": {
                    "functionArn": "arn:aws:lambda:us-east-2:123456789012:function:myLambdaFunction"
                 }
            }
        ]
    }
}
```

The following JSON example defines a Lambda action with substitution templates in an AWS IoT rule.

```
{
    "topicRulePayload": {
        "sql": "SELECT * FROM 'some/topic'",
        "ruleDisabled": false,
        "awsIotSqlVersion": "2016-03-23",
        "actions": [
            {
                "lambda": {
                    "functionArn": "arn:aws:lambda:us-east-1:123456789012:function:${topic()}"
                }
            }
        ]
    }
}
```

## See also

+ [What is AWS Lambda?](https://docs.aws.amazon.com/lambda/latest/dg/) in the *AWS Lambda Developer Guide*
+ [Tutorial: Formatting a notification by using an AWS Lambda function](iot-lambda-rule.md)

# Location


The Location (`location`) action sends your geographical location data to [Amazon Location Service](https://docs.aws.amazon.com//location/latest/developerguide/welcome.html).

## Requirements


This rule action has the following requirements:
+ An IAM role that AWS IoT can assume to perform the `geo:BatchUpdateDevicePosition` operation. For more information, see [Granting an AWS IoT rule the access it requires](iot-create-role.md).

  In the AWS IoT console, you can choose or create a role to allow AWS IoT to perform this rule action.

## Parameters


When you create an AWS IoT rule with this action, you must specify the following information:

`deviceId`  
The unique ID of the device providing the location data. For more information, see [https://docs.aws.amazon.com//location/latest/APIReference/API_DevicePositionUpdate.html](https://docs.aws.amazon.com//location/latest/APIReference/API_DevicePositionUpdate.html) from the *Amazon Location Service API Reference*.  
Supports [substitution templates](iot-substitution-templates.md): Yes

`latitude`  
A string that evaluates to a double value that represents the latitude of the device's location.  
Supports [substitution templates](iot-substitution-templates.md): Yes

`longitude`  
A string that evaluates to a double value that represents the longitude of the device's location.  
Supports [substitution templates](iot-substitution-templates.md): Yes

`roleArn`  
The IAM role that allows access to the Amazon Location Service domain. For more information, see [Requirements](#location-rule-action-requirements). 

`timestamp`  
The time that the location data was sampled. The default value is the time that the MQTT message was processed.  
The `timestamp` value consists of the following two values:  
+ `value`: An expression that returns a long epoch time value. You can use the [time\$1to\$1epoch(String, String)](iot-sql-functions.md#iot-sql-function-time-to-epoch) function to create a valid timestamp from a date or time value passed in the message payload. Supports [substitution templates](iot-substitution-templates.md): Yes.
+ `unit`: (Optional) The precision of the timestamp value that results from the expression described in `value`. Valid values: `SECONDS` \$1 `MILLISECONDS` \$1 `MICROSECONDS` \$1 `NANOSECONDS`. The default is `MILLISECONDS`. Supports [substitution templates](iot-substitution-templates.md): API and AWS CLI only.

`trackerName`  
The name of the tracker resource in Amazon Location in which the location is updated. For more information, see [Tracker](https://docs.aws.amazon.com//location/latest/developerguide/geofence-tracker-concepts.html#tracking-overview) from the *Amazon Location Service Developer Guide*.  
Supports [substitution templates](iot-substitution-templates.md): API and AWS CLI only

## Examples


The following JSON example defines a Location action in an AWS IoT rule.

```
{
	"topicRulePayload": {
		"sql": "SELECT * FROM 'some/topic'",
		"ruleDisabled": false,
		"awsIotSqlVersion": "2016-03-23",
		"actions": [
			{
				"location": {
					"roleArn": "arn:aws:iam::123454962127:role/service-role/ExampleRole",
					"trackerName": "MyTracker",
					"deviceId": "001",
					"sampleTime": {
						"value": "${timestamp()}",
						"unit": "MILLISECONDS"
					},
					"latitude": "-12.3456",
					"longitude": "65.4321"
				}
			}
		]
	}
}
```

The following JSON example defines a Location action with substitution templates in an AWS IoT rule.

```
{
	"topicRulePayload": {
		"sql": "SELECT * FROM 'some/topic'",
		"ruleDisabled": false,
		"awsIotSqlVersion": "2016-03-23",
		"actions": [
			{
				"location": {
					"roleArn": "arn:aws:iam::123456789012:role/service-role/ExampleRole",
					"trackerName": "${TrackerName}",
					"deviceId": "${DeviceID}",
					"timestamp": {
						"value": "${timestamp()}",
						"unit": "MILLISECONDS"
					},
					"latitude": "${get(position, 0)}",
					"longitude": "${get(position, 1)}"
				}
			}
		]
	}
}
```

The following MQTT payload example shows how substitution templates in the preceding example accesses data. You can use the [https://docs.aws.amazon.com/cli/latest/reference/location/get-device-position-history.html](https://docs.aws.amazon.com/cli/latest/reference/location/get-device-position-history.html) CLI command to verify that the MQTT payload data is delivered in your location tracker.

```
{
	"TrackerName": "mytracker",
	"DeviceID": "001",
	"position": [
		"-12.3456",
		"65.4321"
	]
}
```

```
aws location get-device-position-history --device-id 001 --tracker-name mytracker
```

```
{
	"DevicePositions": [
		{
			"DeviceId": "001",
			"Position": [
				-12.3456,
				65.4321
			],
			"ReceivedTime": "2022-11-11T01:31:54.464000+00:00",
			"SampleTime": "2022-11-11T01:31:54.308000+00:00"
		}
	]
}
```

## See also

+ [What is Amazon Location Service?](https://docs.aws.amazon.com//location/latest/developerguide/welcome.html) in the *Amazon Location Service Developer Guide*.

# OpenSearch


The OpenSearch (`openSearch`) action writes data from MQTT messages to an Amazon OpenSearch Service domain. You can then use tools like OpenSearch Dashboards to query and visualize data in OpenSearch Service.

## Requirements


This rule action has the following requirements:
+ An IAM role that AWS IoT can assume to perform the `es:ESHttpPut` operation. For more information, see [Granting an AWS IoT rule the access it requires](iot-create-role.md).

  In the AWS IoT console, you can choose or create a role to allow AWS IoT to perform this rule action.
+ If you use a customer managed AWS KMS key to encrypt data at rest in OpenSearch Service, the service must have permission to use the KMS key on the caller's behalf. For more information, see [Encryption of data at rest for Amazon OpenSearch Service](https://docs.aws.amazon.com/opensearch-service/latest/developerguide/encryption-at-rest.html) in the *Amazon OpenSearch Service Developer Guide*.

## Parameters


When you create an AWS IoT rule with this action, you must specify the following information:

`endpoint`  
The endpoint of your Amazon OpenSearch Service domain.  
Supports [substitution templates](iot-substitution-templates.md): API and AWS CLI only

`index`  
The OpenSearch index where you want to store your data.  
Supports [substitution templates](iot-substitution-templates.md): Yes

`type`  
The type of document you are storing.   
For OpenSearch versions later than 1.0, the value of the `type` parameter must be `_doc`. For more information, see the [OpenSearch documentation](https://opensearch.org/docs/1.0/opensearch/rest-api/document-apis/index-document/#response-body-fields).
Supports [substitution templates](iot-substitution-templates.md): Yes

`id`  
The unique identifier for each document.  
Supports [substitution templates](iot-substitution-templates.md): Yes

`roleARN`  
The IAM role that allows access to the OpenSearch Service domain. For more information, see [Requirements](#opensearch-rule-action-requirements).  
Supports [substitution templates](iot-substitution-templates.md): No

## Limitations


The OpenSearch (`openSearch`) action cannot be used to deliver data to VPC Elasticsearch clusters.

## Examples


The following JSON example defines an OpenSearch action in an AWS IoT rule and how you can specify the fields for the `OpenSearch` action. For more information, see [OpenSearchAction](https://docs.aws.amazon.com/iot/latest/apireference/API_OpenSearchAction.html).

```
{
    "topicRulePayload": {
        "sql": "SELECT *, timestamp() as timestamp FROM 'iot/test'",
        "ruleDisabled": false,
        "awsIotSqlVersion": "2016-03-23",
        "actions": [
            {
                "openSearch": {
                    "endpoint": "https://my-endpoint",
                    "index": "my-index",
                    "type": "_doc",
                    "id": "${newuuid()}",
                    "roleArn": "arn:aws:iam::123456789012:role/aws_iot_os"
                }
            }
        ]
    }
}
```

The following JSON example defines an OpenSearch action with substitution templates in an AWS IoT rule.

```
{
    "topicRulePayload": {
        "sql": "SELECT * FROM 'some/topic'",
        "ruleDisabled": false,
        "awsIotSqlVersion": "2016-03-23",
        "actions": [
            {
                "openSearch": {
                    "endpoint": "https://my-endpoint",
                    "index": "${topic()}",
                    "type": "${type}",
                    "id": "${newuuid()}",
                    "roleArn": "arn:aws:iam::123456789012:role/aws_iot_os"
                }
            }
        ]
    }
}
```

**Note**  
The the substituted `type` field works for OpenSearch version 1.0. For any versions later than 1.0, the value of `type` must be `_doc`.

## See also


[What is Amazon OpenSearch Service?](https://docs.aws.amazon.com/opensearch-service/latest/developerguide/) in the *Amazon OpenSearch Service Developer Guide*

# Republish


The republish (`republish`) action republishes an MQTT message to another MQTT topic.

## Requirements


This rule action has the following requirements:
+ An IAM role that AWS IoT can assume to perform the `iot:Publish` operation. For more information, see [Granting an AWS IoT rule the access it requires](iot-create-role.md).

  In the AWS IoT console, you can choose or create a role to allow AWS IoT to perform this rule action.

## Parameters


When you create an AWS IoT rule with this action, you must specify the following information:

`headers`  
MQTT Version 5.0 headers information.  
For more information, see [RepublishAction](https://docs.aws.amazon.com//iot/latest/apireference/API_RepublishAction.html) and [MqttHeaders](https://docs.aws.amazon.com//iot/latest/apireference/API_MqttHeaders.html) in the *AWS API Reference*.

`topic`  
The MQTT topic to which to republish the message.  
To republish to a reserved topic, which begins with `$`, use `$$` instead. For example, to republish to the device shadow topic `$aws/things/MyThing/shadow/update`, specify the topic as `$$aws/things/MyThing/shadow/update`.  
Republishing to [reserved job topics](reserved-topics.md#reserved-topics-job) is not supported.   
AWS IoT Device Defender reserve topics don't support HTTP publish.
Supports [substitution templates](iot-substitution-templates.md): Yes

`qos`  
(Optional) The Quality of Service (QoS) level to use when republishing messages. Valid values: `0`, `1`. The default value is `0`. For more information about MQTT QoS, see [MQTT](mqtt.md).  
Supports [substitution templates](iot-substitution-templates.md): No

`roleArn`  
The IAM role that allows AWS IoT to publish to the MQTT topic. For more information, see [Requirements](#republish-rule-action-requirements).  
Supports [substitution templates](iot-substitution-templates.md): No

## Examples


The following JSON example defines a republish action in an AWS IoT rule.

```
{
    "topicRulePayload": {
        "sql": "SELECT * FROM 'some/topic'", 
        "ruleDisabled": false, 
        "awsIotSqlVersion": "2016-03-23",
        "actions": [
            {
                "republish": {
                    "topic": "another/topic",
                    "qos": 1,
                    "roleArn": "arn:aws:iam::123456789012:role/aws_iot_republish"
                }
            }
        ]
    }
}
```

The following JSON example defines a republish action with substitution templates in an AWS IoT rule.

```
{
    "topicRulePayload": {
        "sql": "SELECT * FROM 'some/topic'",
        "ruleDisabled": false,
        "awsIotSqlVersion": "2016-03-23",
        "actions": [
            {
                "republish": {
                    "topic": "${topic()}/republish",
                    "roleArn": "arn:aws:iam::123456789012:role/aws_iot_republish"
                }
            }
        ]
    }
}
```

The following JSON example defines a republish action with `headers` in an AWS IoT rule.

```
{
    "topicRulePayload": {
        "sql": "SELECT * FROM 'some/topic'",
        "ruleDisabled": false,
        "awsIotSqlVersion": "2016-03-23",
        "actions": [
            {
                "republish": {
                    "topic": "${topic()}/republish",
                    "roleArn": "arn:aws:iam::123456789012:role/aws_iot_republish",
                    "headers": {
                        "payloadFormatIndicator": "UTF8_DATA",
                        "contentType": "rule/contentType",
                        "correlationData": "cnVsZSBjb3JyZWxhdGlvbiBkYXRh",
                        "userProperties": [
                            {
                                "key": "ruleKey1",
                                "value": "ruleValue1"
                            },
                            {
                                "key": "ruleKey2",
                                "value": "ruleValue2"
                            }
                        ]
                    }
                }
            }
        ]
    }
}
```

**Note**  
The original source IP won't be passed though [Republish action](#republish-rule-action).

# S3


The S3 (`s3`) action writes the data from an MQTT message to an Amazon Simple Storage Service (Amazon S3) bucket. 

## Requirements


This rule action has the following requirements:
+ An IAM role that AWS IoT can assume to perform the `s3:PutObject` operation. For more information, see [Granting an AWS IoT rule the access it requires](iot-create-role.md).

  In the AWS IoT console, you can choose or create a role to allow AWS IoT to perform this rule action.
+ If you use an AWS KMS customermanaged AWS KMS key to encrypt data at rest in Amazon S3, the service must have permission to use the AWS KMS key on the caller's behalf. For more information, see [AWS managed AWS KMS keys and customer managed AWS KMS keys](https://docs.aws.amazon.com/AmazonS3/latest/userguide/UsingKMSEncryption.html#aws-managed-customer-managed-cmks) in the *Amazon Simple Storage Service Developer Guide*.

## Parameters


When you create an AWS IoT rule with this action, you must specify the following information:

`bucket`  
The Amazon S3 bucket to which to write data.  
Supports [substitution templates](iot-substitution-templates.md): API and AWS CLI only

`cannedacl`  
(Optional) The Amazon S3 canned ACL that controls access to the object identified by the object key. For more information, including allowed values, see [Canned ACL](https://docs.aws.amazon.com/AmazonS3/latest/userguide/acl-overview.html#canned-acl).   
Supports [substitution templates](iot-substitution-templates.md): No

`key`  
The path to the file where the data is written.  
Consider an example where this parameter is `${topic()}/${timestamp()}` and the rule receives a message where the topic is `some/topic`. If the current timestamp is `1460685389`, then this action writes the data to a file called `1460685389` in the `some/topic` folder of the S3 bucket.  
If you use a static key, AWS IoT overwrites a single file each time the rule invokes. We recommend that you use the message timestamp or another unique message identifier so that a new file is saved in Amazon S3 for each message received.
Supports [substitution templates](iot-substitution-templates.md): Yes

`roleArn`  
The IAM role that allows access to the Amazon S3 bucket. For more information, see [Requirements](#s3-rule-action-requirements).  
Supports [substitution templates](iot-substitution-templates.md): No

## Examples


The following JSON example defines an S3 action in an AWS IoT rule.

```
{
    "topicRulePayload": {
        "sql": "SELECT * FROM 'some/topic'", 
        "ruleDisabled": false, 
        "awsIotSqlVersion": "2016-03-23",
        "actions": [
            {
                "s3": {
                    "bucketName": "amzn-s3-demo-bucket", 
                    "cannedacl": "public-read",
                    "key": "${topic()}/${timestamp()}",
                    "roleArn": "arn:aws:iam::123456789012:role/aws_iot_s3"
                }
            }
        ]
    }
}
```

## See also

+ [What is Amazon S3?](https://docs.aws.amazon.com/AmazonS3/latest/userguide/) in the *Amazon Simple Storage Service User Guide*

# Salesforce IoT


The Salesforce IoT (`salesforce`) action sends data from the MQTT message that triggered the rule to a Salesforce IoT input stream. 

## Parameters


When you create an AWS IoT rule with this action, you must specify the following information:

`url`  
The URL exposed by the Salesforce IoT input stream. The URL is available from the Salesforce IoT platform when you create an input stream. For more information, see the Salesforce IoT documentation.  
Supports [substitution templates](iot-substitution-templates.md): No

`token`  
The token used to authenticate access to the specified Salesforce IoT input stream. The token is available from the Salesforce IoT platform when you create an input stream. For more information, see the Salesforce IoT documentation.  
Supports [substitution templates](iot-substitution-templates.md): No

## Examples


The following JSON example defines a Salesforce IoT action in an AWS IoT rule.

```
{
    "topicRulePayload": {
        "sql": "SELECT * FROM 'some/topic'",
        "ruleDisabled": false,
        "awsIotSqlVersion": "2016-03-23",
        "actions": [
            {
                "salesforce": {
                    "token": "ABCDEFGHI123456789abcdefghi123456789",
                    "url": "https://ingestion-cluster-id.my-env.sfdcnow.com/streams/stream-id/connection-id/my-event"
                }
            }
        ]
    }
}
```

# SNS


The SNS (`sns`) action sends the data from an MQTT message as an Amazon Simple Notification Service (Amazon SNS) push notification.

You can follow a tutorial that shows you how to create and test a rule with an SNS action. For more information, see [Tutorial: Sending an Amazon SNS notification](iot-sns-rule.md).

**Note**  
The SNS action doesn't support [Amazon SNS FIFO (First-In-First-Out) topics](https://docs.aws.amazon.com/sns/latest/dg/sns-fifo-topics.html). Because the rules engine is a fully distributed service, there is no guarantee of message order when the SNS action is invoked.

## Requirements


This rule action has the following requirements:
+ An IAM role that AWS IoT can assume to perform the `sns:Publish` operation. For more information, see [Granting an AWS IoT rule the access it requires](iot-create-role.md).

  In the AWS IoT console, you can choose or create a role to allow AWS IoT to perform this rule action.
+ If you use an AWS KMS customer managed-managed AWS KMS key to encrypt data at rest in Amazon SNS, the service must have permission to use the AWS KMS key on the caller's behalf. For more information, see [Key management](https://docs.aws.amazon.com/sns/latest/dg/sns-key-management.html) in the *Amazon Simple Notification Service Developer Guide*.

## Parameters


When you create an AWS IoT rule with this action, you must specify the following information:

`targetArn`  
The SNS topic or individual device to which the push notification is sent.  
Supports [substitution templates](iot-substitution-templates.md): API and AWS CLI only

`messageFormat`  
(Optional) The message format. Amazon SNS uses this setting to determine if the payload should be parsed and if relevant platform-specific parts of the payload should be extracted. Valid values: `JSON`, `RAW`. Defaults to `RAW`.  
Supports [substitution templates](iot-substitution-templates.md): No

`roleArn`  
The IAM role that allows access to SNS. For more information, see [Requirements](#sns-rule-action-requirements).  
Supports [substitution templates](iot-substitution-templates.md): No

## Examples


The following JSON example defines an SNS action in an AWS IoT rule.

```
{
    "topicRulePayload": {
        "sql": "SELECT * FROM 'some/topic'", 
        "ruleDisabled": false, 
        "awsIotSqlVersion": "2016-03-23",
        "actions": [
            {
                "sns": {
                    "targetArn": "arn:aws:sns:us-east-2:123456789012:my_sns_topic", 
                    "roleArn": "arn:aws:iam::123456789012:role/aws_iot_sns"
                }
            }
        ]
    }
}
```

The following JSON example defines an SNS action with substitution templates in an AWS IoT rule.

```
{
    "topicRulePayload": {
        "sql": "SELECT * FROM 'some/topic'",
        "ruleDisabled": false,
        "awsIotSqlVersion": "2016-03-23",
        "actions": [
            {
                "sns": {
                    "targetArn": "arn:aws:sns:us-east-1:123456789012:${topic()}",
                    "messageFormat": "JSON",
                    "roleArn": "arn:aws:iam::123456789012:role/aws_iot_sns"
                }
            }
        ]
    }
}
```

## See also

+ [What is Amazon Simple Notification Service?](https://docs.aws.amazon.com/sns/latest/dg/) in the *Amazon Simple Notification Service Developer Guide*
+ [Tutorial: Sending an Amazon SNS notification](iot-sns-rule.md)

# SQS


The SQS (`sqs`) action sends data from an MQTT message to an Amazon Simple Queue Service (Amazon SQS) queue.

**Note**  
The SQS action doesn't support [Amazon SQS FIFO (First-In-First-Out) queues](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/FIFO-queues.html). Because the rules engine is a fully distributed service, there is no guarantee of message order when the SQS action is triggered.

## Requirements


This rule action has the following requirements:
+ An IAM role that AWS IoT can assume to perform the `sqs:SendMessage` operation. For more information, see [Granting an AWS IoT rule the access it requires](iot-create-role.md).

  In the AWS IoT console, you can choose or create a role to allow AWS IoT to perform this rule action.
+ If you use an AWS KMS customer managed AWS KMS key to encrypt data at rest in Amazon SQS, the service must have permission to use the AWS KMS key on the caller's behalf. For more information, see [Key management](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-key-management.html) in the *Amazon Simple Queue Service Developer Guide*.

## Parameters


When you create an AWS IoT rule with this action, you must specify the following information:

`queueUrl`  
The URL of the Amazon SQS queue to which to write the data. The region in this URL doesn't need to be the same AWS Region as your [AWS IoT rule](https://docs.aws.amazon.com/iot/latest/developerguide/iot-rules.html).  
There can be additional charges for data transfer cross AWS Regions using the SQS rule action. For more information, see [Amazon SQS pricing](https://aws.amazon.com/sqs/pricing/).
Supports [substitution templates](iot-substitution-templates.md): API and AWS CLI only

`useBase64`  
Set this parameter to `true` to configure the rule action to base64-encode the message data before it writes the data to the Amazon SQS queue. Defaults to `false`.  
Supports [substitution templates](iot-substitution-templates.md): No

`roleArn`  
The IAM role that allows access to the Amazon SQS queue. For more information, see [Requirements](#sqs-rule-action-requirements).  
Supports [substitution templates](iot-substitution-templates.md): No

## Examples


The following JSON example defines an SQS action in an AWS IoT rule.

```
{
    "topicRulePayload": {
        "sql": "SELECT * FROM 'some/topic'", 
        "ruleDisabled": false, 
        "awsIotSqlVersion": "2016-03-23",
        "actions": [
            {
                "sqs": {
                    "queueUrl": "https://sqs.us-east-2.amazonaws.com/123456789012/my_sqs_queue", 
                    "roleArn": "arn:aws:iam::123456789012:role/aws_iot_sqs"
                }
            }
        ]
    }
}
```

The following JSON example defines an SQS action with substitution templates in an AWS IoT rule.

```
{
    "topicRulePayload": {
        "sql": "SELECT * FROM 'some/topic'",
        "ruleDisabled": false,
        "awsIotSqlVersion": "2016-03-23",
        "actions": [
            {
                "sqs": {
                    "queueUrl": "https://sqs.us-east-2.amazonaws.com/123456789012/${topic()}",
                    "useBase64": true,
                    "roleArn": "arn:aws:iam::123456789012:role/aws_iot_sqs"
                }
            }
        ]
    }
}
```

## See also

+ [What is Amazon Simple Queue Service?](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/) in the *Amazon Simple Queue Service Developer Guide*

# Step Functions


The Step Functions (`stepFunctions`) action starts an AWS Step Functions state machine.

## Requirements


This rule action has the following requirements:
+ An IAM role that AWS IoT can assume to perform the `states:StartExecution` operation. For more information, see [Granting an AWS IoT rule the access it requires](iot-create-role.md).

  In the AWS IoT console, you can choose or create a role to allow AWS IoT to perform this rule action.

## Parameters


When you create an AWS IoT rule with this action, you must specify the following information:

`stateMachineName`  
The name of the Step Functions state machine to start.  
Supports [substitution templates](iot-substitution-templates.md): API and AWS CLI only

`executionNamePrefix`  
(Optional) The name given to the state machine execution consists of this prefix followed by a UUID. Step Functions creates a unique name for each state machine execution if one is not provided.  
Supports [substitution templates](iot-substitution-templates.md): Yes

`roleArn`  
The ARN of the role that grants AWS IoT permission to start the state machine. For more information, see [Requirements](#stepfunctions-rule-action-requirements).  
Supports [substitution templates](iot-substitution-templates.md): No

## Examples


The following JSON example defines a Step Functions action in an AWS IoT rule.

```
{
    "topicRulePayload": {
        "sql": "SELECT * FROM 'some/topic'",
        "ruleDisabled": false,
        "awsIotSqlVersion": "2016-03-23",
        "actions": [
            {
                "stepFunctions": {
                    "stateMachineName": "myStateMachine",
                    "executionNamePrefix": "myExecution",
                    "roleArn": "arn:aws:iam::123456789012:role/aws_iot_step_functions"
                }
            }
        ]
    }
}
```

## See also

+ [What is AWS Step Functions?](https://docs.aws.amazon.com/step-functions/latest/dg/) in the *AWS Step Functions Developer Guide*

# Timestream


The Timestream rule action writes attributes (measures) from an MQTT message into an Amazon Timestream table. For more information about Amazon Timestream, see [What Is Amazon Timestream?](https://docs.aws.amazon.com/timestream/latest/developerguide/what-is-timestream.html).

**Note**  
Amazon Timestream is not available in all AWS Regions. If Amazon Timestream is not available in your Region, it won't appear in the list of rule actions.

The attributes that this rule stores in the Timestream database are those that result from the rule's query statement. The value of each attribute in the query statement's result is parsed to infer its data type (as in a [DynamoDBv2](dynamodb-v2-rule-action.md) action). Each attribute's value is written to its own record in the Timestream table. To specify or change an attribute's data type, use the [`cast()`](iot-sql-functions.md#iot-sql-function-cast) function in the query statement. For more information about the contents of each Timestream record, see [Timestream record content](#timestream-rule-action-data).

**Note**  
With SQL V2 (2016-03-23), numeric values that are whole numbers, such as `10.0`, are converted their Integer representation (`10`). Explicitly casting them to a `Decimal` value, such as by using the [cast()](iot-sql-functions.md#iot-sql-function-cast) function, does not prevent this behavior—the result is still an `Integer` value. This can cause type mismatch errors that prevent data from being recorded in the Timestream database. To process whole number numeric values as `Decimal` values, use SQL V1 (2015-10-08) for the rule query statement.

**Note**  
The maximum number of values that a Timestream rule action can write into an Amazon Timestream table is 100. For more information, see [Amazon Timestream Quota's Reference](https://docs.aws.amazon.com//timestream/latest/developerguide/ts-limits.html#limits.default). 

## Requirements


This rule action has the following requirements:
+ An IAM role that AWS IoT can assume to perform the `timestream:DescribeEndpoints` and `timestream:WriteRecords` operations. For more information, see [Granting an AWS IoT rule the access it requires](iot-create-role.md).

  In the AWS IoT console, you can choose, update, or create a role to allow AWS IoT to perform this rule action.
+ If you use a customer- AWS KMS to encrypt data at rest in Timestream, the service must have permission to use the AWS KMS key on the caller's behalf. For more information, see [How AWS services use AWS KMS](https://docs.aws.amazon.com/kms/latest/developerguide/service-integration.html).

## Parameters


When you create an AWS IoT rule with this action, you must specify the following information:

`databaseName`  
The name of an Amazon Timestream database that has the table to receive the records this action creates. See also `tableName`.  
Supports [substitution templates](iot-substitution-templates.md): API and AWS CLI only

`dimensions`  
Metadata attributes of the time series that are written in each measure record. For example, the name and Availability Zone of an EC2 instance or the name of the manufacturer of a wind turbine are dimensions.    
`name`  
The metadata dimension name. This is the name of the column in the database table record.  
Dimensions can't be named: `measure_name`, `measure_value`, or `time`. These names are reserved. Dimension names can't start with `ts_` or `measure_value` and they can't contain the colon (`:`) character.  
Supports [substitution templates](iot-substitution-templates.md): No  
`value`  
The value to write in this column of the database record.  
Supports [substitution templates](iot-substitution-templates.md): Yes

`roleArn`  
The Amazon Resource Name (ARN) of the role that grants AWS IoT permission to write to the Timestream database table. For more information, see [Requirements](#timestream-rule-action-requirements).  
Supports [substitution templates](iot-substitution-templates.md): No

`tableName`  
The name of the database table into which to write the measure records. See also `databaseName`.  
Supports [substitution templates](iot-substitution-templates.md): API and AWS CLI only

`timestamp`  
 The value to use for the entry's timestamp. If blank, the time that the entry was processed is used.     
`unit`  
The precision of the timestamp value that results from the expression described in `value`.  
Valid values: `SECONDS` \$1 `MILLISECONDS` \$1 `MICROSECONDS` \$1 `NANOSECONDS`. The default is `MILLISECONDS`.  
`value`  
An expression that returns a long epoch time value.  
You can use the [time\$1to\$1epoch(String, String)](iot-sql-functions.md#iot-sql-function-time-to-epoch) function to create a valid timestamp from a date or time value passed in the message payload. 

## Timestream record content


The data written to the Amazon Timestream table by this action include a timestamp, metadata from the Timestream rule action, and the result of the rule's query statement.

For each attribute (measure) in the result of the query statement, this rule action writes a record to the specified Timestream table with these columns.


|  Column name  |  Attribute type  |  Value  |  Comments  | 
| --- | --- | --- | --- | 
|  *dimension-name*  |  DIMENSION  |  The value specified in the Timestream rule action entry.  |  Each **Dimension** specified in the rule action entry creates a column in the Timestream database with the dimension's name.  | 
|  measure\$1name  |  MEASURE\$1NAME  |  The attribute's name  |  The name of the attribute in the result of the query statement whose value is specified in the `measure_value::data-type` column.  | 
|  measure\$1value::*data-type*  |  MEASURE\$1VALUE  |  The value of the attribute in the result of the query statement. The attribute's name is in the `measure_name` column.  |  The value is interpreted\$1 and cast as the most suitable match of: `bigint`, `boolean`, `double`, or `varchar`. Amazon Timestream creates a separate column for each data type. The value in the message can be cast to another data type by using the [`cast()`](iot-sql-functions.md#iot-sql-function-cast) function in the rule's query statement.  | 
|  time  |  TIMESTAMP  |  The date and time of the record in the database.  |  This value is assigned by rules engine or the `timestamp` property, if it is defined.  | 

\$1 The attribute value read from the message payload is interpreted as follows. See the [Examples](#timestream-rule-action-examples) for an illustration of each of these cases.
+ An unquoted value of `true` or `false` is interpreted as a `boolean` type.
+ A decimal numeric is interpreted as a `double` type.
+ A numeric value without a decimal point is interpreted as a `bigint` type.
+ A quoted string is interpreted as a `varchar` type.
+ Objects and array values are converted to JSON strings and stored as a `varchar` type.

## Examples


The following JSON example defines a Timestream rule action with a substitution template in an AWS IoT rule.

```
{
  "topicRulePayload": {
    "sql": "SELECT * FROM 'iot/topic'",
    "ruleDisabled": false,
    "awsIotSqlVersion": "2016-03-23",
    "actions": [
      {
        "timestream": {
          "roleArn": "arn:aws:iam::123456789012:role/aws_iot_timestream",
          "tableName": "devices_metrics",
          "dimensions": [
            {
              "name": "device_id",
              "value": "${clientId()}"
            },
            {
              "name": "device_firmware_sku",
              "value": "My Static Metadata"
            }
          ],
          "databaseName": "record_devices"
        }
      }
    ]
  }
}
```

Using the Timestream topic rule action defined in the previous example with the following message payload results in the Amazon Timestream records written in the table that follows.

```
{
  "boolean_value": true,
  "integer_value": 123456789012,
  "double_value": 123.456789012,
  "string_value": "String value",
  "boolean_value_as_string": "true",
  "integer_value_as_string": "123456789012",
  "double_value_as_string": "123.456789012",
  "array_of_integers": [23,36,56,72],
  "array of strings": ["red", "green","blue"],
  "complex_value": {
    "simple_element": 42,
    "array_of_integers": [23,36,56,72],
    "array of strings": ["red", "green","blue"]
  }
}
```

The following table displays the database columns and records that using the specified topic rule action to process the previous message payload creates. The `device_firmware_sku` and `device_id` columns are the DIMENSIONS defined in the topic rule action. The Timestream topic rule action creates the `time` column and the `measure_name` and `measure_value::*` columns, which it fills with the values from the result of the topic rule action's query statement. 


| device\$1firmware\$1sku | device\$1id | measure\$1name | measure\$1value::bigint | measure\$1value::varchar | measure\$1value::double | measure\$1value::boolean | time | 
| --- | --- | --- | --- | --- | --- | --- | --- | 
| My Static Metadata | iotconsole-159EXAMPLE738-0 | complex\$1value | - | \$1"simple\$1element":42,"array\$1of\$1integers":[23,36,56,72],"array of strings":["red","green","blue"]\$1 | - | - | 2020-08-26 22:42:16.423000000 | 
| My Static Metadata | iotconsole-159EXAMPLE738-0 | integer\$1value\$1as\$1string | - | 123456789012 | - | - | 2020-08-26 22:42:16.423000000 | 
| My Static Metadata | iotconsole-159EXAMPLE738-0 | boolean\$1value | - | - | - | TRUE | 2020-08-26 22:42:16.423000000 | 
| My Static Metadata | iotconsole-159EXAMPLE738-0 | integer\$1value | 123456789012 | - | - | - | 2020-08-26 22:42:16.423000000 | 
| My Static Metadata | iotconsole-159EXAMPLE738-0 | string\$1value | - | String value | - | - | 2020-08-26 22:42:16.423000000 | 
| My Static Metadata | iotconsole-159EXAMPLE738-0 | array\$1of\$1integers | - | [23,36,56,72] | - | - | 2020-08-26 22:42:16.423000000 | 
| My Static Metadata | iotconsole-159EXAMPLE738-0 | array of strings | - | ["red","green","blue"] | - | - | 2020-08-26 22:42:16.423000000 | 
| My Static Metadata | iotconsole-159EXAMPLE738-0 | boolean\$1value\$1as\$1string | - | TRUE | - | - | 2020-08-26 22:42:16.423000000 | 
| My Static Metadata | iotconsole-159EXAMPLE738-0 | double\$1value | - | - | 123.456789012 | - | 2020-08-26 22:42:16.423000000 | 
| My Static Metadata | iotconsole-159EXAMPLE738-0 | double\$1value\$1as\$1string | - | 123.45679 | - | - | 2020-08-26 22:42:16.423000000 | 