

• The AWS Systems Manager CloudWatch Dashboard will no longer be available after April 30, 2026. Customers can continue to use Amazon CloudWatch console to view, create, and manage their Amazon CloudWatch dashboards, just as they do today. For more information, see [Amazon CloudWatch Dashboard documentation](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch_Dashboards.html). 

# AWS Systems Manager change management tools
<a name="systems-manager-actions-and-change"></a>

AWS Systems Manager provides the following tools for making changes to your AWS resources.

**Topics**
+ [AWS Systems Manager Automation](systems-manager-automation.md)
+ [AWS Systems Manager Change Calendar](systems-manager-change-calendar.md)
+ [AWS Systems Manager Change Manager](change-manager.md)
+ [AWS Systems Manager Documents](documents.md)
+ [AWS Systems Manager Maintenance Windows](maintenance-windows.md)
+ [AWS Systems Manager Quick Setup](systems-manager-quick-setup.md)

# AWS Systems Manager Automation
<a name="systems-manager-automation"></a>

Automation, a tool in AWS Systems Manager, simplifies common maintenance, deployment, and remediation tasks for AWS services like Amazon Elastic Compute Cloud (Amazon EC2), Amazon Relational Database Service (Amazon RDS), Amazon Redshift, Amazon Simple Storage Service (Amazon S3), and many more. To get started with Automation, open the [Systems Manager console](https://console.aws.amazon.com/systems-manager/automation). In the navigation pane, choose **Automation**. 

Automation helps you to build automated solutions to deploy, configure, and manage AWS resources at scale. With Automation, you have granular control over the concurrency of your automations. This means you can specify how many resources to target concurrently, and how many errors can occur before an automation is stopped. 

To help you get started with Automation, AWS develops and maintains several pre-defined runbooks. Depending on your use case, you can use these pre-defined runbooks that perform a variety of tasks, or create your own custom runbooks that might better suit your needs. To monitor the progress and status of your automations, you can use the Systems Manager Automation console, or your preferred command line tool. Automation also integrates with Amazon EventBridge to help you build event-driven architecture at scale.

**Note**  
For customers who are new to Systems Manager Automation as of August 14, 2025, the Automation free tier is not available. For customers already using Automation, the free tier of service ends on December 31, 2025. For information about current service costs, see [AWS Systems Manager pricing](https://aws.amazon.com/systems-manager/pricing/).

## How can Automation benefit my organization?
<a name="automation-benefits"></a>

Automation offers these benefits:
+ **Scripting support in runbook content**

  Using the `aws:executeScript` action, you can run custom Python and PowerShell functions directly from your runbooks. This provides you greater flexibility in creating your custom runbooks because you can complete various tasks that other Automation actions don't support. You also have greater control over the logic of the runbook. For an example of how this action can be used and how it can help to improve an existing automated solution, see [Authoring Automation runbooks](automation-authoring-runbooks.md).
+  **Run automations across multiple AWS accounts and AWS Regions from a centralized location** 

  Administrators can run automations on resources across multiple accounts and Regions from the Systems Manager console.
+  **Enhanced operations security** 

  Administrators have a centralized place to grant and revoke access to runbooks. Using only AWS Identity and Access Management (IAM) policies, you can control which individual users or groups in your organization can use Automation and which runbooks they can access.
+  **Automate common IT tasks** 

  Automating common tasks can help improve operational efficiency, enforce organizational standards, and reduce operator errors. For example, you can use the `AWS-UpdateCloudFormationStackWithApproval` runbook to update resources that were deployed by using an AWS CloudFormation template. The update applies a new template. You can configure the Automation to request approval by one or more users before the update begins.
+  **Safely perform disruptive tasks in bulk** 

  Automation includes features, like rate controls, that allow you to control the deployment of an automation across your fleet by specifying a concurrency value and an error threshold. For more information about working with rate controls, see [Run automated operations at scale](running-automations-scale.md).
+ **Streamline complex tasks**

  Automation provides pre-defined runbooks that streamline complex and time-consuming tasks such as creating golden Amazon Machine Images (AMIs). For example, you can use the `AWS-UpdateLinuxAmi` and `AWS-UpdateWindowsAmi` runbooks to create golden AMIs from a source AMI. Using these runbooks, you can run custom scripts before and after updates are applied. You can also include or exclude specific software packages from being installed. For examples of how to use these runbooks, see [Tutorials](automation-tutorials.md).
+ **Define constraints for inputs**

  You can define constraints in custom runbooks to limit the values that Automation will accept for a particular input parameter. For example, `allowedPattern` will only accept values for an input parameter that match the regular expression you define. If you specify `allowedValues` for an input parameter, only the values you've specified in the runbook are accepted.
+  **Log automation action output to Amazon CloudWatch Logs** 

  To meet operational or security requirements in your organization, you might need to provide a record of the scripts run during a runbook. With CloudWatch Logs, you can monitor, store, and access log files from various AWS services. You can send output from the `aws:executeScript` action to a CloudWatch Logs log group for debugging and troubleshooting purposes. Log data can be sent to your log group with or without AWS KMS encryption using your KMS key. For more information, see [Logging Automation action output with CloudWatch Logs](automation-action-logging.md).
+  **Amazon EventBridge integration** 

  Automation is supported as a *target* type in Amazon EventBridge rules. This means you can trigger runbooks by using events. For more information, see [Monitoring Systems Manager events with Amazon EventBridge](monitoring-eventbridge-events.md) and [Reference: Amazon EventBridge event patterns and types for Systems Manager](reference-eventbridge-events.md).
+ **Share organizational best practices**

  You can define best practices for resource management, operations tasks, and more in runbooks that you share across accounts and Regions.

## Who should use Automation?
<a name="automation-who"></a>
+ Any AWS customer who wants to improve their operational efficiency at scale, reduce errors associated with manual intervention, and reduce time to resolution of common issues.
+ Infrastructure experts who want to automate deployment and configuration tasks.
+ Administrators who want to reliably resolve common issues, improve troubleshooting efficiency, and reduce repetitive operations.
+ Users who want to automate a task they normally perform manually.

## What is an automation?
<a name="what-is-an-automation"></a>

An *automation* consists of all of the tasks that are defined in a runbook, and are performed by the Automation service. Automation uses the following components to run automations.


****  

| Concept | Details | 
| --- | --- | 
|  Automation runbook  |  A Systems Manager Automation runbook defines the automation (the actions that Systems Manager performs on your managed nodes and AWS resources). Automation includes several pre-defined runbooks that you can use to perform common tasks like restarting one or more Amazon EC2 instances or creating an Amazon Machine Image (AMI). You can create your own runbooks as well. Runbooks use YAML or JSON, and they include steps and parameters that you specify. Steps run in sequential order. For more information, see [Creating your own runbooks](automation-documents.md). Runbooks are Systems Manager documents of type `Automation`, as opposed to `Command`, `Policy`, `Session` documents. Runbooks support schema version 0.3. Command documents use schema version 1.2, 2.0, or 2.2. Policy documents use schema version 2.0 or later.  | 
|  Automation action  |  The automation defined in a runbook includes one or more steps. Each step is associated with a particular action. The action determines the inputs, behavior, and outputs of the step. Steps are defined in the `mainSteps` section of your runbook. Automation supports 20 distinct action types. For more information, see the [Systems Manager Automation actions reference](automation-actions.md).  | 
|  Automation quota  |  Each AWS account can run 100 automations simultaneously. This includes child automations (automations that are started by another automation), and rate control automations. If you attempt to run more automations than this, Systems Manager adds the additional automations to a queue and displays a status of Pending. This quota can be adjusted using adaptive concurrency. For more information, see [Allowing Automation to adapt to your concurrency needs](adaptive-concurrency.md).For more information about running automations, see [Run an automated operation powered by Systems Manager Automation](running-simple-automations.md).  | 
|  Automation queue quota  |  If you attempt to run more automations than the concurrent automation limit, subsequent automations are added to a queue. Each AWS account can queue 5,000 automations. When an automation is complete (or reaches a terminal state), the first automation in the queue is started.  | 
|  Rate control automation quota  |  Each AWS account can run 25 rate control automations simultaneously. If you attempt to run more rate control automations than the concurrent rate control automation limit, Systems Manager adds the subsequent rate control automations to a queue and displays a status of Pending. For more information about running rate control automations, see [Run automated operations at scale](running-automations-scale.md).  | 
|  Rate control automation queue quota  |  If you attempt to run more automations than the concurrent rate control automation limit, subsequent automations are added to a queue. Each AWS account can queue 1,000 rate control automations. When an automation is complete (or reaches a terminal state), the first automation in the queue is started.  | 

**Topics**
+ [How can Automation benefit my organization?](#automation-benefits)
+ [Who should use Automation?](#automation-who)
+ [What is an automation?](#what-is-an-automation)
+ [Setting up Automation](automation-setup.md)
+ [Run an automated operation powered by Systems Manager Automation](running-simple-automations.md)
+ [Rerunning automation executions](automation-rerun-executions.md)
+ [Run an automation that requires approvals](running-automations-require-approvals.md)
+ [Run automated operations at scale](running-automations-scale.md)
+ [Running automations in multiple AWS Regions and accounts](running-automations-multiple-accounts-regions.md)
+ [Run automations based on EventBridge events](running-automations-event-bridge.md)
+ [Run an automation step by step](automation-working-executing-manually.md)
+ [Scheduling automations with State Manager associations](scheduling-automations-state-manager-associations.md)
+ [Schedule automations with maintenance windows](scheduling-automations-maintenance-windows.md)
+ [Systems Manager Automation actions reference](automation-actions.md)
+ [Creating your own runbooks](automation-documents.md)
+ [Systems Manager Automation Runbook Reference](automation-documents-reference.md)
+ [Tutorials](automation-tutorials.md)
+ [Learn about statuses returned by Systems Manager Automation](automation-statuses.md)
+ [Troubleshooting Systems Manager Automation](automation-troubleshooting.md)

# Setting up Automation
<a name="automation-setup"></a>

To set up Automation, a tool in AWS Systems Manager, you must verify user access to the Automation service and situationally configure roles so that the service can perform actions on your resources. We also recommend that you opt in to the adaptive concurrency mode in your Automation preferences. Adaptive concurrency automatically scales your automation quota to meet your needs. For more information, see [Allowing Automation to adapt to your concurrency needs](adaptive-concurrency.md).

To ensure proper access to AWS Systems Manager Automation, review the following user and service role requirements.

## Verifying user access for runbooks
<a name="automation-setup-user-access"></a>

Verify that you have permission to use runbooks. If your user, group, or role is assigned administrator permissions, then you have access to Systems Manager Automation. If you don't have administrator permissions, then an administrator must give you permission by assigning the `AmazonSSMFullAccess` managed policy, or a policy that provides comparable permissions, to your user, group, or role.

**Important**  
The IAM policy `AmazonSSMFullAccess` grants permissions to Systems Manager actions. However, some runbooks require permissions to other services, such as the runbook `AWS-ReleaseElasticIP`, which requires IAM permissions for `ec2:ReleaseAddress`. Therefore, you must review the actions taken in a runbook to ensure your user, group, or role is assigned the necessary permissions to perform the actions included in the runbook.

## Configuring a service role (assume role) access for automations
<a name="automation-setup-configure-role"></a>

Automations can be initiated under the context of a service role (or *assume role*). This allows the service to perform actions on your behalf. If you don't specify an assume role, Automation uses the context of the user who invoked the automation.

However, the following situations require that you specify a service role for Automation:
+ When you want to restrict a user's permissions on a resource, but you want the user to run an automation that requires elevated permissions. In this scenario, you can create a service role with elevated permissions and allow the user to run the automation.
+ When you create a Systems Manager State Manager association that runs a runbook.
+ When you have operations that you expect to run longer than 12 hours.
+ When you're running a runbook not owned by Amazon that uses the `aws:executeScript` action to call an AWS API operation or to act on an AWS resource. For information, see [Permissions for using runbooks](automation-document-script-considerations.md#script-permissions).

If you need to create a service role for Automation, you can use one of the following methods.

**Topics**
+ [Verifying user access for runbooks](#automation-setup-user-access)
+ [Configuring a service role (assume role) access for automations](#automation-setup-configure-role)
+ [Create service roles for Automation by using CloudFormation](automation-setup-cloudformation.md)
+ [Create the service roles for Automation using the console](automation-setup-iam.md)
+ [Setting up identity based policies examples](automation-setup-identity-based-policies.md)
+ [Allowing Automation to adapt to your concurrency needs](adaptive-concurrency.md)
+ [Configuring automatic retry for throttled operations](automation-throttling-retry.md)
+ [Implement change controls for Automation](automation-change-calendar-integration.md)

# Create service roles for Automation by using CloudFormation
<a name="automation-setup-cloudformation"></a>

You can create a service role for Automation, a tool in AWS Systems Manager, from an AWS CloudFormation template. After you create the service role, you can specify the service role in runbooks using the parameter `AutomationAssumeRole`.

## Create the service role using CloudFormation
<a name="create-iam-service-role"></a>

Use the following procedure to create the required AWS Identity and Access Management (IAM) role for Systems Manager Automation by using CloudFormation.

**To create the required IAM role**

1. Download and unzip the [https://docs.aws.amazon.com/systems-manager/latest/userguide/samples/AWS-SystemsManager-AutomationServiceRole.zip](https://docs.aws.amazon.com/systems-manager/latest/userguide/samples/AWS-SystemsManager-AutomationServiceRole.zip) file. This file includes the `AWS-SystemsManager-AutomationServiceRole.yaml` CloudFormation template file.

1. Open the CloudFormation console at [https://console.aws.amazon.com/cloudformation](https://console.aws.amazon.com/cloudformation/).

1. Choose **Create Stack**.

1. In the **Specify template** section, choose **Upload a template file**.

1. Choose **Browse**, and then choose the `AWS-SystemsManager-AutomationServiceRole.yaml` CloudFormation template file.

1. Choose **Next**.

1. On the **Specify stack details** page, in the **Stack name** field, enter a name. 

1. On the **Configure stack options** page, you don’t need to make any selections. Choose **Next**.

1. On the **Review** page, scroll down and choose the **I acknowledge that CloudFormation might create IAM resources** option.

1. Choose **Create**.

CloudFormation shows the **CREATE\$1IN\$1PROGRESS** status for approximately three minutes. The status changes to **CREATE\$1COMPLETE** after the stack is created and your roles are ready to use.

**Important**  
If you run an automation workflow that invokes other services by using an AWS Identity and Access Management (IAM) service role, be aware that the service role must be configured with permission to invoke those services. This requirement applies to all AWS Automation runbooks (`AWS-*` runbooks) such as the `AWS-ConfigureS3BucketLogging`, `AWS-CreateDynamoDBBackup`, and `AWS-RestartEC2Instance` runbooks, to name a few. This requirement also applies to any custom Automation runbooks you create that invoke other AWS services by using actions that call other services. For example, if you use the `aws:executeAwsApi`, `aws:createStack`, or `aws:copyImage` actions, configure the service role with permission to invoke those services. You can give permissions to other AWS services by adding an IAM inline policy to the role. For more information, see [(Optional) Add an Automation inline policy or customer managed policy to invoke other AWS services](automation-setup-iam.md#add-inline-policy).

## Copy role information for Automation
<a name="copy-iam-role-info"></a>

Use the following procedure to copy information about the Automation service role from the CloudFormation console. You must specify these roles when you use a runbook.

**Note**  
You don't need to copy role information using this procedure if you run the `AWS-UpdateLinuxAmi` or `AWS-UpdateWindowsAmi` runbooks. These runbooks already have the required roles specified as default values. The roles specified in these runbooks use IAM managed policies. 

**To copy the role names**

1. Open the CloudFormation console at [https://console.aws.amazon.com/cloudformation](https://console.aws.amazon.com/cloudformation/).

1. Select the Automation **Stack name** you created in the previous procedure.

1. Choose the **Resources** tab.

1. Choose the **Physical ID** link for **AutomationServiceRole**. The IAM console opens to a summary of the Automation service role.

1. Copy the Amazon Resource Name (ARN) next to **Role ARN**. The ARN is similar to the following: `arn:aws:iam::12345678:role/AutomationServiceRole`

1. Paste the ARN into a text file to use later.

You have finished configuring the service role for Automation. You can now use the Automation service role ARN in your runbooks.

# Create the service roles for Automation using the console
<a name="automation-setup-iam"></a>

If you need to create a service role for Automation, a tool in AWS Systems Manager, complete the following tasks. For more information about when a service role is required for Automation, see [Setting up Automation](automation-setup.md).

**Topics**
+ [Task 1: Create a service role for Automation](#create-service-role)
+ [Task 2: Attach the iam:PassRole policy to your Automation role](#attach-passrole-policy)

## Task 1: Create a service role for Automation
<a name="create-service-role"></a>

Use the following procedure to create a service role (or *assume role*) for Systems Manager Automation.

**Note**  
You can also use this role in runbooks, such as the `AWS-CreateManagedLinuxInstance` runbook. Using this role, or the Amazon Resource Name (ARN) of an AWS Identity and Access Management (IAM) role, in runbooks allows Automation to perform actions in your environment, such as launch new instances and perform actions on your behalf.

**To create an IAM role and allow Automation to assume it**

1. Open the IAM console at [https://console.aws.amazon.com/iam/](https://console.aws.amazon.com/iam/).

1. In the navigation pane, choose **Roles**, and then choose **Create role**.

1. Under **Select type of trusted entity**, choose **AWS service**.

1. In the **Choose a use case** section, choose **Systems Manager**, and then choose **Next: Permissions**.

1. On the **Attached permissions policy** page, search for the **AmazonSSMAutomationRole** policy, choose it, and then choose **Next: Review**. 

1. On the **Review** page, enter a name in the **Role name** box, and then enter a description.

1. Choose **Create role**. The system returns you to the **Roles** page.

1. On the **Roles** page, choose the role you just created to open the **Summary** page. Note the **Role Name** and **Role ARN**. You will specify the role ARN when you attach the **iam:PassRole** policy to your IAM account in the next procedure. You can also specify the role name and the ARN in runbooks.

**Note**  
The `AmazonSSMAutomationRole` policy assigns the Automation role permission to a subset of AWS Lambda functions within your account. These functions begin with "Automation". If you plan to use Automation with Lambda functions, the Lambda ARN must use the following format:  
`"arn:aws:lambda:*:*:function:Automation*"`  
If you have existing Lambda functions whose ARNs don't use this format, then you must also attach an additional Lambda policy to your automation role, such as the **AWSLambdaRole** policy. The additional policy or role must provide broader access to Lambda functions within the AWS account.

After creating your service role, we recommend editing the trust policy to help prevent the cross-service confused deputy problem. The *confused deputy problem* is a security issue where an entity that doesn't have permission to perform an action can coerce a more-privileged entity to perform the action. In AWS, cross-service impersonation can result in the confused deputy problem. Cross-service impersonation can occur when one service (the *calling service*) calls another service (the *called service*). The calling service can be manipulated to use its permissions to act on another customer's resources in a way it should not otherwise have permission to access. To prevent this, AWS provides tools that help you protect your data for all services with service principals that have been given access to resources in your account. 

We recommend using the [https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_condition-keys.html#condition-keys-sourcearn](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_condition-keys.html#condition-keys-sourcearn) and [https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_condition-keys.html#condition-keys-sourceaccount](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_condition-keys.html#condition-keys-sourceaccount) global condition context keys in resource policies to limit the permissions that Automation gives another service to the resource. If the `aws:SourceArn` value doesn't contain the account ID, such as an Amazon S3 bucket ARN, you must use both global condition context keys to limit permissions. If you use both global condition context keys and the `aws:SourceArn` value contains the account ID, the `aws:SourceAccount` value and the account in the `aws:SourceArn` value must use the same account ID when used in the same policy statement. Use `aws:SourceArn` if you want only one resource to be associated with the cross-service access. Use `aws:SourceAccount` if you want to allow any resource in that account to be associated with the cross-service use. The value of `aws:SourceArn` must be the ARN for automation executions. If you don't know the full ARN of the resource or if you're specifying multiple resources, use the `aws:SourceArn` global context condition key with wildcards (`*`) for the unknown portions of the ARN. For example, `arn:aws:ssm:*:123456789012:automation-execution/*`. 

The following example shows how you can use the `aws:SourceArn` and `aws:SourceAccount` global condition context keys for Automation to prevent the confused deputy problem.

------
#### [ JSON ]

****  

```
{
  "Version":"2012-10-17",		 	 	 
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Service": [
          "ssm.amazonaws.com"
        ]
      },
      "Action": "sts:AssumeRole",
      "Condition": {
        "StringEquals": {
          "aws:SourceAccount": "123456789012"
        },
        "ArnLike": {
          "aws:SourceArn": "arn:aws:ssm:*:123456789012:automation-execution/*"
        }
      }
    }
  ]
}
```

------

**To modify the role's trust policy**

1. Open the IAM console at [https://console.aws.amazon.com/iam/](https://console.aws.amazon.com/iam/).

1. In the navigation pane, choose **Roles**.

1. In the list of roles in your account, choose the name of your Automation service role.

1. Choose the **Trust relationships** tab, and then choose **Edit trust relationship**.

1. Edit the trust policy using the `aws:SourceArn` and `aws:SourceAccount` global condition context keys for Automation to prevent the confused deputy problem.

1. Choose **Update Trust Policy** to save your changes.

### (Optional) Add an Automation inline policy or customer managed policy to invoke other AWS services
<a name="add-inline-policy"></a>

If you run an automation that invokes other AWS services by using an IAM service role, the service role must be configured with permission to invoke those services. This requirement applies to all AWS Automation runbooks (`AWS-*` runbooks) such as the `AWS-ConfigureS3BucketLogging`, `AWS-CreateDynamoDBBackup`, and `AWS-RestartEC2Instance` runbooks, to name a few. This requirement also applies to any custom runbooks you create that invoke other AWS services by using actions that call other services. For example, if you use the `aws:executeAwsApi`, `aws:CreateStack`, or `aws:copyImage` actions, to name a few, then you must configure the service role with permission to invoke those services. You can give permissions to other AWS services by adding an IAM inline policy or customer managed policy to the role. 

**To embed an inline policy for a service role (IAM console)**

1. Sign in to the AWS Management Console and open the IAM console at [https://console.aws.amazon.com/iam/](https://console.aws.amazon.com/iam/).

1. In the navigation pane, choose **Roles**.

1. In the list, choose the name of the role that you want to edit.

1. Choose the **Permissions** tab.

1. In the **Add permissions** dropdown, choose **Attach policies** or **Create inline policy**.

1. If you choose **Attach policies**, select the check box next to the policy you want to add and choose **Add permissions**.

1. If you choose **Create inline policy**, choose the **JSON** tab.

1. Enter a JSON Policy document for the AWS services you want to invoke. Here are two example JSON Policy documents.

   **Amazon S3 PutObject and GetObject Example**

------
#### [ JSON ]

****  

   ```
   {
       "Version":"2012-10-17",		 	 	 
       "Statement": [
           {
               "Effect": "Allow",
               "Action": [
                   "s3:PutObject",
                   "s3:GetObject"
               ],
               "Resource": "arn:aws:s3:::amzn-s3-demo-bucket/*"
           }
       ]
   }
   ```

------

   **Amazon EC2 CreateSnapshot and DescribeSnapShots Example**

------
#### [ JSON ]

****  

   ```
   {
      "Version":"2012-10-17",		 	 	 
      "Statement":[
         {
            "Effect":"Allow",
            "Action":"ec2:CreateSnapshot",
            "Resource":"*"
         },
         {
            "Effect":"Allow",
            "Action":"ec2:DescribeSnapshots",
            "Resource":"*"
         }
      ]
   }
   ```

------

   For details about the IAM policy language, see [IAM JSON Policy Reference](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies.html) in the *IAM User Guide*.

1. When you're finished, choose **Review policy**. The [Policy Validator](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_policy-validator.html) reports any syntax errors.

1. On the **Review policy** page, enter a **Name** for the policy that you're creating. Review the policy **Summary** to see the permissions that are granted by your policy. Then choose **Create policy** to save your work.

1. After you create an inline policy, it's automatically embedded in your role.

## Task 2: Attach the iam:PassRole policy to your Automation role
<a name="attach-passrole-policy"></a>

Use the following procedure to attach the `iam:PassRole` policy to your Automation service role. This allows the Automation service to pass the role to other services or Systems Manager tools when running automations.

**To attach the iam:PassRole policy to your Automation role**

1. In the **Summary** page for the role you just created, choose the **Permissions** tab.

1. Choose **Add inline policy**.

1. On the **Create policy** page, choose the **Visual editor** tab.

1. Choose **Service**, and then choose **IAM**.

1. Choose **Select actions**.

1. In the **Filter actions** text box, type **PassRole**, and then choose the **PassRole** option.

1. Choose **Resources**. Verify that **Specific** is selected, and then choose **Add ARN**.

1. In the **Specify ARN for role** field, paste the Automation role ARN that you copied at the end of Task 1. The system populates the **Account** and **Role name with path** fields.
**Note**  
If you want the Automation service role to attach an IAM instance profile role to an EC2 instance, then you must add the ARN of the IAM instance profile role. This allows the Automation service role to pass the IAM instance profile role to the target EC2 instance.

1. Choose **Add**.

1. Choose **Review policy**.

1. On the **Review Policy** page, enter a name and then choose **Create Policy**.

# Setting up identity based policies examples
<a name="automation-setup-identity-based-policies"></a>

The following sections provide example IAM identity-based policies for AWS Systems Manager Automation service. For more information about how to create an IAM identity-based policy using these example JSON Policy documents, see [Creating IAM policies](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_create.html#access_policies_create-json-editor) in the *IAM User Guide*.

**Note**  
All examples contain fictitious account IDs. The account ID shouldn't be specified in the Amazon Resource Name (ARN) for AWS owned public documents.

 **Examples** 
+  [Example 1: Allow a user to run an automation document and view the automation execution](#automation-setup-identity-based-policies-example-1) 
+  [Example 2: Allow a user to run a specific version of an automation document](#automation-setup-identity-based-policies-example-2) 
+  [Example 3: Allow a user to execute automation documents with a specific tag](#automation-setup-identity-based-policies-example-3) 
+  [Example 4: Allow a user to run an automation document when a specific tag parameter is provided for the automation execution](#automation-setup-identity-based-policies-example-4) 

## Example 1: Allow a user to run an automation document and view the automation execution
<a name="automation-setup-identity-based-policies-example-1"></a>

The following example IAM policy allows a user to do the following:
+ Run the automation document specified in the policy. The name of the document is determined by the following entry.

  ```
  arn:aws:ssm:*:111122223333:document/{{DocumentName}}
  ```
+ Stop and send signals to an automation execution.
+ View details about the automation execution after it has been started.

------
#### [ JSON ]

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Action": "ssm:StartAutomationExecution",
            "Effect": "Allow",
            "Resource": [
                "arn:aws:ssm:*:111122223333:document/{{DocumentName}}",
                "arn:aws:ssm:*:111122223333:automation-execution/*"
            ]
        },
        {
            "Action": [
                "ssm:StopAutomationExecution",
                "ssm:GetAutomationExecution",
                "ssm:DescribeAutomationExecutions",
                "ssm:DescribeAutomationStepExecutions",
                "ssm:SendAutomationSignal"
            ],
            "Resource": [
                "arn:aws:ssm:*:111122223333:automation-execution/*"
            ],
            "Effect": "Allow"
        }
    ]
}
```

------

## Example 2: Allow a user to run a specific version of an automation document
<a name="automation-setup-identity-based-policies-example-2"></a>

The following example IAM policy allows a user to run a specific version of an automation document:
+ The name of the automation document is determined by the following entry.

  ```
  arn:aws:ssm:*:111122223333:document/{{DocumentName}}
  ```
+ The version of the automation document is determined by the following entry.

  ```
  "ssm:DocumentVersion": "5"
  ```

------
#### [ JSON ]

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Action": "ssm:StartAutomationExecution",
            "Effect": "Allow",
            "Resource": [
                "arn:aws:ssm:*:111122223333:document/{{DocumentName}}"
            ],
            "Condition": {
                "ForAnyValue:StringEquals": {
                   "ssm:DocumentVersion": ["5"]
                }
            }
        },
        {
            "Action": [
                "ssm:StartAutomationExecution"
            ],
            "Resource": [
                "arn:aws:ssm:*:111122223333:automation-execution/*"
            ],
            "Effect": "Allow"
        },
        {
            "Action": [
                "ssm:StopAutomationExecution",
                "ssm:GetAutomationExecution",
                "ssm:DescribeAutomationExecutions",
                "ssm:DescribeAutomationStepExecutions",
                "ssm:SendAutomationSignal"
            ],
            "Resource": [
                "arn:aws:ssm:*:111122223333:automation-execution/*"
            ],
            "Effect": "Allow"
        }
    ]
}
```

------

## Example 3: Allow a user to execute automation documents with a specific tag
<a name="automation-setup-identity-based-policies-example-3"></a>

The following example IAM policy allows a user to run any automation document that has a specific tag:
+ The name of the automation document is determined by the following entry.

  ```
  arn:aws:ssm:*:111122223333:document/{{DocumentName}}
  ```
+ The tag of the automation document is determined by the following entry.

  ```
  "ssm:DocumentVersion": "5"
  ```

------
#### [ JSON ]

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Action": "ssm:StartAutomationExecution",
            "Effect": "Allow",
            "Resource": [
                "arn:aws:ssm:*:111122223333:document/*"
            ],
            "Condition": {
                "StringEquals": {
                    "aws:ResourceTag/stage": "production"
                }
            }
        },
        {
            "Action": [
                "ssm:StartAutomationExecution"
            ],
            "Resource": [
                "arn:aws:ssm:*:111122223333:automation-execution/*"
            ],
            "Effect": "Allow"
        },
        {
            "Action": [
                "ssm:StopAutomationExecution",
                "ssm:GetAutomationExecution",
                "ssm:DescribeAutomationExecutions",
                "ssm:DescribeAutomationStepExecutions",
                "ssm:SendAutomationSignal"
            ],
            "Resource": [
                "arn:aws:ssm:*:111122223333:automation-execution/*"
            ],
            "Effect": "Allow"
        }
    ]
}
```

------

## Example 4: Allow a user to run an automation document when a specific tag parameter is provided for the automation execution
<a name="automation-setup-identity-based-policies-example-4"></a>

The following example IAM policy grants permissions to a user to run automation documents when a specific tag parameter is provided for the automation execution:
+ Run the automation document specified in the policy. The name of the document is determined by the following entry.

  ```
  arn:aws:ssm:*:111122223333:document/{{DocumentName}}
  ```
+ Must provide a specific tag parameter for the automation execution. The tag parameter for the automation execution resource is determined by the following entry.

  ```
  "aws:ResourceTag/stage": "production"
  ```
+ Stop and send signals to automation executions that have the specified tag.
+ View details about the automation executions that have the specified tag.
+ Add the specified tag to SSM resources.

------
#### [ JSON ]

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Action": "ssm:StartAutomationExecution",
            "Effect": "Allow",
            "Resource": [
                "arn:aws:ssm:*:111122223333:document/{{DocumentName}}"
            ]
        },
        {
            "Action": [
                "ssm:StartAutomationExecution",
                "ssm:StopAutomationExecution",
                "ssm:GetAutomationExecution",
                "ssm:DescribeAutomationExecutions",
                "ssm:DescribeAutomationStepExecutions",
                "ssm:SendAutomationSignal"
            ],
            "Resource": [
                "arn:aws:ssm:*:111122223333:automation-execution/*"
            ],
            "Effect": "Allow",
            "Condition": {
                "StringEquals": {
                    "aws:ResourceTag/environment": "beta"
                }
            }
        },
        {
            "Action": "ssm:AddTagsToResource",
            "Effect": "Allow",
            "Resource": [
                "arn:aws:ssm:*:111122223333:automation-execution/*"
            ]
        }
    ]
}
```

------

# Allowing Automation to adapt to your concurrency needs
<a name="adaptive-concurrency"></a>

By default, Automation allows you to run up to 100 concurrent automations at a time. Automation also provides an optional setting that you can use to adjust your concurrency automation quota automatically. With this setting, your concurrency automation quota can accommodate up to 500 concurrent automations, depending on available resources. 

**Note**  
If your automation calls API operations, adaptively scaling to your targets can result in throttling exceptions. If recurring throttling exceptions occur when running automations with adaptive concurrency turned on, you might have to request quota increases for the API operation if available.

**To turn on adaptive concurrency using the AWS Management Console**

1. Open the AWS Systems Manager console at [https://console.aws.amazon.com/systems-manager/](https://console.aws.amazon.com/systems-manager/).

1. In the navigation pane, choose **Automation**.

1. Choose the **Preferences** tab, and then choose **Edit**.

1. Select the check box next to **Enable adaptive concurrency**.

1. Choose **Save**.

**To turn on adaptive concurrency using the command line**
+ Open the AWS CLI or Tools for Windows PowerShell and run the following command to turn on adaptive concurrency for your account in the requesting Region.

------
#### [ Linux & macOS ]

  ```
  aws ssm update-service-setting \
      --setting-id /ssm/automation/enable-adaptive-concurrency \
      --setting-value True
  ```

------
#### [ Windows ]

  ```
  aws ssm update-service-setting ^
      --setting-id /ssm/automation/enable-adaptive-concurrency ^
      --setting-value True
  ```

------
#### [ PowerShell ]

  ```
  Update-SSMServiceSetting `
      -SettingId "/ssm/automation/enable-adaptive-concurrency" `
      -SettingValue "True"
  ```

------

# Configuring automatic retry for throttled operations
<a name="automation-throttling-retry"></a>

There is a limit on the number of concurrent automation executions that can run in each account. Attempting to run several automations concurrently in an account can lead to throttling issues. You can use the automatic throttling retry capability to configure retry behavior for throttled automation steps.

Automatic throttling retry for automation actions provides a more resilient execution environment for high-scale operations. The throttling retry capability supports all [automation actions](automation-actions.md) except for `aws:executeScript`.

The throttling retry setting works in addition to the existing `maxAttempts` step property. When both are configured, the system first attempts throttling retries within the specified time limit, then applies the `maxAttempts` setting if the step continues to fail.

**To configure throttling retry using the AWS Management Console**

1. Open the AWS Systems Manager console at [https://console.aws.amazon.com/systems-manager/](https://console.aws.amazon.com/systems-manager/).

1. In the navigation pane, choose **Automation**.

1. Choose the **Preferences** tab, and then choose **Edit**.

1. In the **Throttling retry time limit** field, enter a value between 0 and 3600 seconds. This specifies the maximum time that the system retries a step that is throttled.

1. Choose **Save**.

**To configure throttling retry using the command line**
+ Open the AWS CLI or Tools for Windows PowerShell and run the following command to configure throttling retry for your account in the requesting Region.

------
#### [ Linux & macOS ]

  ```
  aws ssm update-service-setting \
      --setting-id /ssm/automation/throttled-retry-time-limit \
      --setting-value 3600
  ```

------
#### [ Windows ]

  ```
  aws ssm update-service-setting ^
      --setting-id /ssm/automation/throttled-retry-time-limit ^
      --setting-value 3600
  ```

------
#### [ PowerShell ]

  ```
  Update-SSMServiceSetting `
      -SettingId "/ssm/automation/throttled-retry-time-limit" `
      -SettingValue "3600"
  ```

------

# Implement change controls for Automation
<a name="automation-change-calendar-integration"></a>

By default, Automation allows you to use runbooks without date and time constraints. By integrating Automation with Change Calendar, you can implement change controls to all automations in your AWS account. With this setting, AWS Identity and Access Management (IAM) principals in your account can only run automations during the time periods allowed by your change calendar. To learn more about working with Change Calendar, see [Working with Change Calendar](systems-manager-change-calendar-working.md).

**To turn on change controls (console)**

1. Open the AWS Systems Manager console at [https://console.aws.amazon.com/systems-manager/](https://console.aws.amazon.com/systems-manager/).

1. In the navigation pane, choose **Automation**.

1. Choose the **Preferences** tab, and then choose **Edit**.

1. Select the check box next to **Turn on Change Calendar integration**.

1. In the **Choose a change calendar** dropdown list, choose the change calendar that you want Automation to follow.

1. Choose **Save**.

# Run an automated operation powered by Systems Manager Automation
<a name="running-simple-automations"></a>

When you run an automation, by default, the automation runs in the context of the user who initiated the automation. This means, for example, if your user has administrator permissions, then the automation runs with administrator permissions and full access to the resources being configured by the automation. As a security best practice, we recommend that you run automation by using an IAM service role that is known in this case as an *assume* role that is configured with the AmazonSSMAutomationRole managed policy. You might need to add additional IAM policies to your assume role to use various runbooks. Using an IAM service role to run automation is called *delegated administration*.

When you use a service role, the automation is allowed to run against the AWS resources, but the user who ran the automation has restricted access (or no access) to those resources. For example, you can configure a service role and use it with Automation to restart one or more Amazon Elastic Compute Cloud (Amazon EC2) instances. Automation is a tool in AWS Systems Manager. The automation restarts the instances, but the service role doesn't give the user permission to access those instances.

You can specify a service role at runtime when you run an automation, or you can create custom runbooks and specify the service role directly in the runbook. If you specify a service role, either at runtime or in a runbook, then the service runs in the context of the specified service role. If you don't specify a service role, then the system creates a temporary session in the context of the user and runs the automation.

**Note**  
You must specify a service role for automation that you expect to run longer than 12 hours. If you start a long-running automation in the context of a user, the user's temporary session expires after 12 hours.

Delegated administration ensures elevated security and control of your AWS resources. It also allows an enhanced auditing experience because actions are being performed against your resources by a central service role instead of multiple IAM accounts.

**Before you begin**  
Before you complete the following procedures, you must create the IAM service role and configure a trust relationship for Automation, a tool in AWS Systems Manager. For more information, see [Task 1: Create a service role for Automation](automation-setup-iam.md#create-service-role).

The following procedures describe how to use the Systems Manager console or your preferred command line tool to run a simple automation.

## Running a simple automation (console)
<a name="simple-console"></a>

The following procedure describes how to use the Systems Manager console to run a simple automation.

**To run a simple automation**

1. Open the AWS Systems Manager console at [https://console.aws.amazon.com/systems-manager/](https://console.aws.amazon.com/systems-manager/).

1. In the navigation pane, choose **Automation**, and then choose **Execute automation**.

1. In the **Automation document** list, choose a runbook. Choose one or more options in the **Document categories** pane to filter SSM documents according to their purpose. To view a runbook that you own, choose the **Owned by me** tab. To view a runbook that is shared with your account, choose the **Shared with me** tab. To view all runbooks, choose the **All documents** tab.
**Note**  
You can view information about a runbook by choosing the runbook name.

1. In the **Document details** section, verify that **Document version** is set to the version that you want to run. The system includes the following version options: 
   + **Default version at runtime** – Choose this option if the Automation runbook is updated periodically and a new default version is assigned.
   + **Latest version at runtime** – Choose this option if the Automation runbook is updated periodically, and you want to run the version that was most recently updated.
   + **1 (Default)** – Choose this option to run the first version of the document, which is the default.

1. Choose **Next**.

1. In the **Execution Mode** section, choose **Simple execution**.

1. In the **Input parameters** section, specify the required inputs. Optionally, you can choose an IAM service role from the **AutomationAssumeRole** list.

1. (Optional) Choose a CloudWatch alarm to apply to your automation for monitoring. To attach a CloudWatch alarm to your automation, the IAM principal that starts the automation must have permission for the `iam:createServiceLinkedRole` action. For more information about CloudWatch alarms, see [Using Amazon CloudWatch alarms](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/AlarmThatSendsEmail.html). Note that if your alarm activates, the automation is stopped. If you use AWS CloudTrail, you will see the API call in your trail. 

1. Choose **Execute**. 

The console displays the status of the automation. If the automation fails to run, see [Troubleshooting Systems Manager Automation](automation-troubleshooting.md).

After an automation execution completes, you can rerun the execution with the same or modified parameters. For more information, see [Rerunning automation executions](automation-rerun-executions.md).

## Running a simple automation (command line)
<a name="simple-cli"></a>

The following procedure describes how to use the AWS CLI (on Linux or Windows) or AWS Tools for PowerShell to run a simple automation.

**To run a simple automation**

1. Install and configure the AWS CLI or the AWS Tools for PowerShell, if you haven't already.

   For information, see [Installing or updating the latest version of the AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html) and [Installing the AWS Tools for PowerShell](https://docs.aws.amazon.com/powershell/latest/userguide/pstools-getting-set-up.html).

1. Run the following command to start a simple automation. Replace each *example resource placeholder* with your own information.

------
#### [ Linux & macOS ]

   ```
   aws ssm start-automation-execution \
       --document-name runbook name \
       --parameters runbook parameters
   ```

------
#### [ Windows ]

   ```
   aws ssm start-automation-execution ^
       --document-name runbook name ^
       --parameters runbook parameters
   ```

------
#### [ PowerShell ]

   ```
   Start-SSMAutomationExecution `
     -DocumentName runbook name `
     -Parameter runbook parameters
   ```

------

   Here is an example using the runbook `AWS-RestartEC2Instance` to restart the specified EC2 instance.

------
#### [ Linux & macOS ]

   ```
   aws ssm start-automation-execution \
       --document-name "AWS-RestartEC2Instance" \
       --parameters "InstanceId=i-02573cafcfEXAMPLE"
   ```

------
#### [ Windows ]

   ```
   aws ssm start-automation-execution ^
       --document-name "AWS-RestartEC2Instance" ^
       --parameters "InstanceId=i-02573cafcfEXAMPLE"
   ```

------
#### [ PowerShell ]

   ```
   Start-SSMAutomationExecution `
     -DocumentName AWS-RestartEC2Instance `
     -Parameter @{"InstanceId"="i-02573cafcfEXAMPLE"}
   ```

------

   The system returns information like the following.

------
#### [ Linux & macOS ]

   ```
   {
       "AutomationExecutionId": "4105a4fc-f944-11e6-9d32-0123456789ab"
   }
   ```

------
#### [ Windows ]

   ```
   {
       "AutomationExecutionId": "4105a4fc-f944-11e6-9d32-0123456789ab"
   }
   ```

------
#### [ PowerShell ]

   ```
   4105a4fc-f944-11e6-9d32-0123456789ab
   ```

------

1. Run the following command to retrieve the status of the automation.

------
#### [ Linux & macOS ]

   ```
   aws ssm describe-automation-executions \
       --filter "Key=ExecutionId,Values=4105a4fc-f944-11e6-9d32-0123456789ab"
   ```

------
#### [ Windows ]

   ```
   aws ssm describe-automation-executions ^
       --filter "Key=ExecutionId,Values=4105a4fc-f944-11e6-9d32-0123456789ab"
   ```

------
#### [ PowerShell ]

   ```
   Get-SSMAutomationExecutionList | `
     Where {$_.AutomationExecutionId -eq "4105a4fc-f944-11e6-9d32-0123456789ab"}
   ```

------

   The system returns information like the following.

------
#### [ Linux & macOS ]

   ```
   {
       "AutomationExecutionMetadataList": [
           {
               "AutomationExecutionStatus": "InProgress",
               "CurrentStepName": "stopInstances",
               "Outputs": {},
               "DocumentName": "AWS-RestartEC2Instance",
               "AutomationExecutionId": "4105a4fc-f944-11e6-9d32-0123456789ab",
               "DocumentVersion": "1",
               "ResolvedTargets": {
                   "ParameterValues": [],
                   "Truncated": false
               },
               "AutomationType": "Local",
               "Mode": "Auto",
               "ExecutionStartTime": 1564600648.159,
               "CurrentAction": "aws:changeInstanceState",
               "ExecutedBy": "arn:aws:sts::123456789012:assumed-role/Administrator/Admin",
               "LogFile": "",
               "Targets": []
           }
       ]
   }
   ```

------
#### [ Windows ]

   ```
   {
       "AutomationExecutionMetadataList": [
           {
               "AutomationExecutionStatus": "InProgress",
               "CurrentStepName": "stopInstances",
               "Outputs": {},
               "DocumentName": "AWS-RestartEC2Instance",
               "AutomationExecutionId": "4105a4fc-f944-11e6-9d32-0123456789ab",
               "DocumentVersion": "1",
               "ResolvedTargets": {
                   "ParameterValues": [],
                   "Truncated": false
               },
               "AutomationType": "Local",
               "Mode": "Auto",
               "ExecutionStartTime": 1564600648.159,
               "CurrentAction": "aws:changeInstanceState",
               "ExecutedBy": "arn:aws:sts::123456789012:assumed-role/Administrator/Admin",
               "LogFile": "",
               "Targets": []
           }
       ]
   }
   ```

------
#### [ PowerShell ]

   ```
   AutomationExecutionId       : 4105a4fc-f944-11e6-9d32-0123456789ab
   AutomationExecutionStatus   : InProgress
   AutomationType              : Local
   CurrentAction               : aws:changeInstanceState
   CurrentStepName             : startInstances
   DocumentName                : AWS-RestartEC2Instance
   DocumentVersion             : 1
   ExecutedBy                  : arn:aws:sts::123456789012:assumed-role/Administrator/Admin
   ExecutionEndTime            : 1/1/0001 12:00:00 AM
   ExecutionStartTime          : 7/31/2019 7:17:28 PM
   FailureMessage              : 
   LogFile                     : 
   MaxConcurrency              : 
   MaxErrors                   : 
   Mode                        : Auto
   Outputs                     : {}
   ParentAutomationExecutionId : 
   ResolvedTargets             : Amazon.SimpleSystemsManagement.Model.ResolvedTargets
   Target                      : 
   TargetMaps                  : {}
   TargetParameterName         : 
   Targets                     : {}
   ```

------

# Rerunning automation executions
<a name="automation-rerun-executions"></a>

You can rerun AWS Systems Manager automation executions to repeat tasks with either identical or modified parameters. The rerun capability allows you to efficiently replicate automation executions without manually recreating automation configurations, reducing operational overhead and potential configuration errors.

When you rerun an automation execution, Systems Manager preserves the original runbook parameters, Amazon CloudWatch alarms, and tags from the previous execution. The system creates a new execution with a new execution ID and updated timestamps. You can rerun any type of automation execution, including simple executions, rate control executions, cross-account and cross-region executions, and manual executions.

## Rerun an automation execution (console)
<a name="rerun-console"></a>

The following procedures describe how to use the Systems Manager console to rerun an automation execution.

**To rerun an automation execution from the Automation home page**

Open the AWS Systems Manager console at [https://console.aws.amazon.com/systems-manager/](https://console.aws.amazon.com/systems-manager/).

1. In the navigation pane, choose **Automation**.

1. In the executions list, select the execution that you want to rerun.

1. Choose **Rerun execution**.

1. On the **Execute automation document** page, review the pre-populated parameters, execution mode, and target configuration from the original execution.

1. (Optional) Modify any parameters, targets, or other settings as needed for your rerun.

1. Choose **Execute** to start the rerun with a new execution ID.

**To rerun an automation execution from the execution details page**

Open the AWS Systems Manager console at [https://console.aws.amazon.com/systems-manager/](https://console.aws.amazon.com/systems-manager/).

1. In the navigation pane, choose **Automation**.

1. Choose the execution ID of the automation that you want to rerun.

1. On the execution details page, choose **Rerun execution**.

1. On the **Execute automation document** page, review the pre-populated parameters, execution mode, and target configuration from the original execution.

1. (Optional) Modify any parameters, targets, or other settings as needed for your rerun.

1. Choose **Execute** to start the rerun with a new execution ID.

**To copy an automation execution to a new execution**

Open the AWS Systems Manager console at [https://console.aws.amazon.com/systems-manager/](https://console.aws.amazon.com/systems-manager/).

1. In the navigation pane, choose **Automation**.

1. Choose the execution ID of the automation that you want to copy.

1. On the execution details page, choose **Actions**, and then choose **Copy to new**.

1. On the **Execute automation document** page, review the pre-populated parameters, execution mode, and target configuration from the original execution.

1. (Optional) Modify any parameters, targets, or other settings as needed for your new execution.

1. Choose **Execute** to start the new execution.

# Run an automation that requires approvals
<a name="running-automations-require-approvals"></a>

The following procedures describe how to use the AWS Systems Manager console and AWS Command Line Interface (AWS CLI) to run an automation with approvals using simple execution. The automation uses the automation action `aws:approve`, which temporarily pauses the automation until the designated principals either approve or deny the action. The automation runs in the context of the current user. This means that you don't need to configure additional IAM permissions as long as you have permission to use the runbook, and any actions called by the runbook. If you have administrator permissions in IAM, then you already have permission to use this runbook.

**Before you begin**  
In addition to the standard inputs required by the runbook, the `aws:approve` action requires the following two parameters: 
+ A list of approvers. The list of approvers must contain at least one approver in the form of a user name or a user ARN. If multiple approvers are provided, a corresponding minimum approval count must also be specified within the runbook. 
+ An Amazon Simple Notification Service (Amazon SNS) topic ARN. The Amazon SNS topic name must start with `Automation`.

This procedure assumes that you have already created an Amazon SNS topic, which is required to deliver the approval request. For information, see [Create a Topic](https://docs.aws.amazon.com/sns/latest/dg/sns-getting-started.html#CreateTopic) in the *Amazon Simple Notification Service Developer Guide*.

## Running an automation with approvers (console)
<a name="approval-console"></a>

**To run an automation with approvers**

The following procedure describes how to use the Systems Manager console to run an automation with approvers.

1. Open the AWS Systems Manager console at [https://console.aws.amazon.com/systems-manager/](https://console.aws.amazon.com/systems-manager/).

1. In the navigation pane, choose **Automation**, and then choose **Execute automation**.

1. In the **Automation document** list, choose a runbook. Choose one or more options in the **Document categories** pane to filter SSM documents according to their purpose. To view a runbook that you own, choose the **Owned by me** tab. To view a runbook that is shared with your account, choose the **Shared with me** tab. To view all runbooks, choose the **All documents** tab.
**Note**  
You can view information about a runbook by choosing the runbook name.

1. In the **Document details** section, verify that **Document version** is set to the version that you want to run. The system includes the following version options: 
   + **Default version at runtime** – Choose this option if the Automation runbook is updated periodically and a new default version is assigned.
   + **Latest version at runtime** – Choose this option if the Automation runbook is updated periodically, and you want to run the version that was most recently updated.
   + **1 (Default)** – Choose this option to run the first version of the document, which is the default.

1. Choose **Next**.

1. On the **Execute automation document** page, choose **Simple execution**.

1. In the **Input parameters** section, specify the required input parameters.

   For example, if you chose the `AWS-StartEC2InstanceWithApproval` runbook, then you must specify or choose instance IDs for the **InstanceId** parameter. 

1. In the **Approvers** section, specify the user names or user ARNs of approvers for the automation action.

1. In the **SNSTopicARN** section, specify the SNS topic ARN to use for sending approval notification. The SNS topic name must start with **Automation**.

1. Optionally, you can choose an IAM service role from the **AutomationAssumeRole** list. If you're targeting more than 100 accounts and Regions, you must specify the `AWS-SystemsManager-AutomationAdministrationRole`.

1. Choose **Execute automation**. 

The specified approver receives an Amazon SNS notification with details to approve or reject the automation. This approval action is valid for 7 days from the date of issue and can be issued using the Systems Manager console or the AWS Command Line Interface (AWS CLI).

If you chose to approve the automation, the automation continues to run the steps included in the specified runbook. The console displays the status of the automation. If the automation fails to run, see [Troubleshooting Systems Manager Automation](automation-troubleshooting.md).

**To approve or deny an automation**

1. Open the AWS Systems Manager console at [https://console.aws.amazon.com/systems-manager/](https://console.aws.amazon.com/systems-manager/).

1. In the navigation pane, choose **Automation**, and then select the automation that was run in the previous procedure.

1. Choose **Actions** and then choose **Approve/Deny**.

1. Choose to **Approve** or **Deny** and optionally provide a comment.

1. Choose **Submit**.

## Running an automation with approvers (command line)
<a name="approval-cli"></a>

The following procedure describes how to use the AWS CLI (on Linux or Windows) or AWS Tools for PowerShell to run an automation with approvers.

**To run an automation with approvers**

1. Install and configure the AWS CLI or the AWS Tools for PowerShell, if you haven't already.

   For information, see [Installing or updating the latest version of the AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html) and [Installing the AWS Tools for PowerShell](https://docs.aws.amazon.com/powershell/latest/userguide/pstools-getting-set-up.html).

1. Run the following command to run an automation with approvers. Replace each *example resource placeholder* with your own information. In the document name section, specify a runbook that includes the automation action, `aws:approve`.

   For `Approvers`, specify the user names or user ARNs of approvers for the action. For `SNSTopic`, specify the SNS topic ARN to use to send approval notification. The Amazon SNS topic name must start with `Automation`.
**Note**  
The specific names of the parameter values for approvers and the SNS topic depend on the values specified within the runbook you choose. 

------
#### [ Linux & macOS ]

   ```
   aws ssm start-automation-execution \
       --document-name "AWS-StartEC2InstanceWithApproval" \
       --parameters "InstanceId=i-02573cafcfEXAMPLE,Approvers=arn:aws:iam::123456789012:role/Administrator,SNSTopicArn=arn:aws:sns:region:123456789012:AutomationApproval"
   ```

------
#### [ Windows ]

   ```
   aws ssm start-automation-execution ^
       --document-name "AWS-StartEC2InstanceWithApproval" ^
       --parameters "InstanceId=i-02573cafcfEXAMPLE,Approvers=arn:aws:iam::123456789012:role/Administrator,SNSTopicArn=arn:aws:sns:region:123456789012:AutomationApproval"
   ```

------
#### [ PowerShell ]

   ```
   Start-SSMAutomationExecution `
       -DocumentName AWS-StartEC2InstanceWithApproval `
       -Parameters @{
           "InstanceId"="i-02573cafcfEXAMPLE"
           "Approvers"="arn:aws:iam::123456789012:role/Administrator"
           "SNSTopicArn"="arn:aws:sns:region:123456789012:AutomationApproval"
       }
   ```

------

   The system returns information like the following.

------
#### [ Linux & macOS ]

   ```
   {
       "AutomationExecutionId": "df325c6d-b1b1-4aa0-8003-6cb7338213c6"
   }
   ```

------
#### [ Windows ]

   ```
   {
       "AutomationExecutionId": "df325c6d-b1b1-4aa0-8003-6cb7338213c6"
   }
   ```

------
#### [ PowerShell ]

   ```
   df325c6d-b1b1-4aa0-8003-6cb7338213c6
   ```

------

**To approve an automation**
+ Run the following command to approve an automation. Replace each *example resource placeholder* with your own information.

------
#### [ Linux & macOS ]

  ```
  aws ssm send-automation-signal \
      --automation-execution-id "df325c6d-b1b1-4aa0-8003-6cb7338213c6" \
      --signal-type "Approve" \
      --payload "Comment=your comments"
  ```

------
#### [ Windows ]

  ```
  aws ssm send-automation-signal ^
      --automation-execution-id "df325c6d-b1b1-4aa0-8003-6cb7338213c6" ^
      --signal-type "Approve" ^
      --payload "Comment=your comments"
  ```

------
#### [ PowerShell ]

  ```
  Send-SSMAutomationSignal `
      -AutomationExecutionId df325c6d-b1b1-4aa0-8003-6cb7338213c6 `
      -SignalType Approve `
      -Payload @{"Comment"="your comments"}
  ```

------

  There is no output if the command succeeds.

**To deny an automation**
+ Run the following command to deny an automation. Replace each *example resource placeholder* with your own information.

------
#### [ Linux & macOS ]

  ```
  aws ssm send-automation-signal \
      --automation-execution-id "df325c6d-b1b1-4aa0-8003-6cb7338213c6" \
      --signal-type "Deny" \
      --payload "Comment=your comments"
  ```

------
#### [ Windows ]

  ```
  aws ssm send-automation-signal ^
      --automation-execution-id "df325c6d-b1b1-4aa0-8003-6cb7338213c6" ^
      --signal-type "Deny" ^
      --payload "Comment=your comments"
  ```

------
#### [ PowerShell ]

  ```
  Send-SSMAutomationSignal `
      -AutomationExecutionId df325c6d-b1b1-4aa0-8003-6cb7338213c6 `
      -SignalType Deny `
      -Payload @{"Comment"="your comments"}
  ```

------

  There is no output if the command succeeds.

# Run automated operations at scale
<a name="running-automations-scale"></a>

With AWS Systems Manager Automation, you can run automations on a fleet of AWS resources by using *targets*. Additionally, you can control the deployment of the automation across your fleet by specifying a concurrency value and an error threshold. The concurrency and error threshold features are collectively called *rate controls*. The concurrency value determines how many resources are allowed to run the automation simultaneously. Automation also provides an adaptive concurrency mode you can opt in to. Adaptive concurrency automatically scales your automation quota from 100 concurrently running automations up to 500. An error threshold determines how many automations are allowed to fail before Systems Manager stops sending the automation to other resources.

For more information about concurrency and error thresholds, see [Control automations at scale](running-automations-scale-controls.md). For more information about targets, see [Mapping targets for an automation](running-automations-map-targets.md).

The following procedures show you how to turn on adaptive concurrency, and how to run an automation with targets and rate controls by using the Systems Manager console and AWS Command Line Interface (AWS CLI).

## Running an automation with targets and rate controls (console)
<a name="scale-console"></a>

The following procedure describes how to use the Systems Manager console to run an automation with targets and rate controls.

**To run an automation with targets and rate controls**

1. Open the AWS Systems Manager console at [https://console.aws.amazon.com/systems-manager/](https://console.aws.amazon.com/systems-manager/).

1. In the navigation pane, choose **Automation**, and then choose **Execute automation**.

1. In the **Automation document** list, choose a runbook. Choose one or more options in the **Document categories** pane to filter SSM documents according to their purpose. To view a runbook that you own, choose the **Owned by me** tab. To view a runbook that is shared with your account, choose the **Shared with me** tab. To view all runbooks, choose the **All documents** tab.
**Note**  
You can view information about a runbook by choosing the runbook name.

1. In the **Document details** section, verify that **Document version** is set to the version that you want to run. The system includes the following version options: 
   + **Default version at runtime** – Choose this option if the Automation runbook is updated periodically and a new default version is assigned.
   + **Latest version at runtime** – Choose this option if the Automation runbook is updated periodically, and you want to run the version that was most recently updated.
   + **1 (Default)** – Choose this option to run the first version of the document, which is the default.

1. Choose **Next**.

1. In the **Execution Mode** section, choose **Rate Control**. You must use this mode or **Multi-account and Region** if you want to use targets and rate controls.

1. In the **Targets** section, choose how you want to target the AWS resources where you want to run the Automation. These options are required.

   1. Use the **Parameter** list to choose a parameter. The items in the **Parameter** list are determined by the parameters in the Automation runbook that you selected at the start of this procedure. By choosing a parameter you define the type of resource on which the Automation workflow runs. 

   1. Use the **Targets** list to choose how you want to target resources.

      1. If you chose to target resources by using parameter values, then enter the parameter value for the parameter you chose in the **Input parameters** section.

      1. If you chose to target resources by using AWS Resource Groups, then choose the name of the group from the **Resource Group** list.

      1. If you chose to target resources by using tags, then enter the tag key and (optionally) the tag value in the fields provided. Choose **Add**.

      1. If you want to run an Automation runbook on all instances in the current AWS account and AWS Region, then choose **All instances**.

1. In the **Input parameters** section, specify the required inputs. Optionally, you can choose an IAM service role from the **AutomationAssumeRole** list.
**Note**  
You might not need to choose some of the options in the **Input parameters** section. This is because you targeted resources by using tags or a resource group. For example, if you chose the `AWS-RestartEC2Instance` runbook, then you don't need to specify or choose instance IDs in the **Input parameters** section. The Automation execution locates the instances to restart by using the tags or resource group you specified.

1. Use the options in the **Rate control** section to restrict the number of AWS resources that can run the Automation within each account-Region pair. 

   In the **Concurrency** section, choose an option: 
   + Choose **targets** to enter an absolute number of targets that can run the Automation workflow simultaneously.
   + Choose **percentage** to enter a percentage of the target set that can run the Automation workflow simultaneously.

1. In the **Error threshold** section, choose an option:
   + Choose **errors** to enter an absolute number of errors allowed before Automation stops sending the workflow to other resources.
   + Choose **percentage** to enter a percentage of errors allowed before Automation stops sending the workflow to other resources.

1. (Optional) Choose a CloudWatch alarm to apply to your automation for monitoring. To attach a CloudWatch alarm to your automation, the IAM principal that starts the automation must have permission for the `iam:createServiceLinkedRole` action. For more information about CloudWatch alarms, see [Using Amazon CloudWatch alarms](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/AlarmThatSendsEmail.html). Note that if your alarm activates, the automation is stopped. If you use AWS CloudTrail, you will see the API call in your trail.

1. Choose **Execute**. 

To view automations started by your rate control automation, in the navigation pane, choose Automation, and then select **Show child automations**.

After an automation execution completes, you can rerun the execution with the same or modified parameters. For more information, see [Rerunning automation executions](automation-rerun-executions.md).

## Running an automation with targets and rate controls (command line)
<a name="scale-cli"></a>

The following procedure describes how to use the AWS CLI (on Linux or Windows) or AWS Tools for PowerShell to run an automation with targets and rate controls.

**To run an automation with targets and rate controls**

1. Install and configure the AWS CLI or the AWS Tools for PowerShell, if you haven't already.

   For information, see [Installing or updating the latest version of the AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html) and [Installing the AWS Tools for PowerShell](https://docs.aws.amazon.com/powershell/latest/userguide/pstools-getting-set-up.html).

1. Run the following command to view a list of documents.

------
#### [ Linux & macOS ]

   ```
   aws ssm list-documents
   ```

------
#### [ Windows ]

   ```
   aws ssm list-documents
   ```

------
#### [ PowerShell ]

   ```
   Get-SSMDocumentList
   ```

------

   Note the name of the runbook that you want to use.

1. Run the following command to view details about the runbook. Replace the *runbook name* with the name of the runbook whose details you want to view. Also, note a parameter name (for example, `InstanceId`) that you want to use for the `--target-parameter-name` option. This parameter determines the type of resource on which the automation runs.

------
#### [ Linux & macOS ]

   ```
   aws ssm describe-document \
       --name runbook name
   ```

------
#### [ Windows ]

   ```
   aws ssm describe-document ^
       --name runbook name
   ```

------
#### [ PowerShell ]

   ```
   Get-SSMDocumentDescription `
       -Name runbook name
   ```

------

1. Create a command that uses the targets and rate control options you want to run. Replace each *example resource placeholder* with your own information.

   *Targeting using tags*

------
#### [ Linux & macOS ]

   ```
   aws ssm start-automation-execution \
       --document-name runbook name \
       --targets Key=tag:key name,Values=value \
       --target-parameter-name parameter name \
       --parameters "input parameter name=input parameter value,input parameter 2 name=input parameter 2 value" \
       --max-concurrency 10 \
       --max-errors 25%
   ```

------
#### [ Windows ]

   ```
   aws ssm start-automation-execution ^
       --document-name runbook name ^
       --targets Key=tag:key name,Values=value ^
       --target-parameter-name parameter name ^
       --parameters "input parameter name=input parameter value,input parameter 2 name=input parameter 2 value" ^
       --max-concurrency 10 ^
       --max-errors 25%
   ```

------
#### [ PowerShell ]

   ```
   $Targets = New-Object Amazon.SimpleSystemsManagement.Model.Target
   $Targets.Key = "tag:key name"
   $Targets.Values = "value"
   
   Start-SSMAutomationExecution `
       DocumentName "runbook name" `
       -Targets $Targets `
       -TargetParameterName "parameter name" `
       -Parameter @{"input parameter name"="input parameter value";"input parameter 2 name"="input parameter 2 value"} `
       -MaxConcurrency "10" `
       -MaxError "25%"
   ```

------

   *Targeting using parameter values*

------
#### [ Linux & macOS ]

   ```
   aws ssm start-automation-execution \
       --document-name runbook name \
       --targets Key=ParameterValues,Values=value,value 2,value 3 \
       --target-parameter-name parameter name \
       --parameters "input parameter name=input parameter value" \
       --max-concurrency 10 \
       --max-errors 25%
   ```

------
#### [ Windows ]

   ```
   aws ssm start-automation-execution ^
       --document-name runbook name ^
       --targets Key=ParameterValues,Values=value,value 2,value 3 ^
       --target-parameter-name parameter name ^
       --parameters "input parameter name=input parameter value" ^
       --max-concurrency 10 ^
       --max-errors 25%
   ```

------
#### [ PowerShell ]

   ```
   $Targets = New-Object Amazon.SimpleSystemsManagement.Model.Target
   $Targets.Key = "ParameterValues"
   $Targets.Values = "value","value 2","value 3"
   
   Start-SSMAutomationExecution `
       -DocumentName "runbook name" `
       -Targets $Targets `
       -TargetParameterName "parameter name" `
       -Parameter @{"input parameter name"="input parameter value"} `
       -MaxConcurrency "10" `
       -MaxError "25%"
   ```

------

   *Targeting using AWS Resource Groups*

------
#### [ Linux & macOS ]

   ```
   aws ssm start-automation-execution \
       --document-name runbook name \
       --targets Key=ResourceGroup,Values=Resource group nname \
       --target-parameter-name parameter name \
       --parameters "input parameter name=input parameter value" \
       --max-concurrency 10 \
       --max-errors 25%
   ```

------
#### [ Windows ]

   ```
   aws ssm start-automation-execution ^
       --document-name runbook name ^
       --targets Key=ResourceGroup,Values=Resource group name ^
       --target-parameter-name parameter name ^
       --parameters "input parameter name=input parameter value" ^
       --max-concurrency 10 ^
       --max-errors 25%
   ```

------
#### [ PowerShell ]

   ```
   $Targets = New-Object Amazon.SimpleSystemsManagement.Model.Target
   $Targets.Key = "ResourceGroup"
   $Targets.Values = "Resource group name"
   
   Start-SSMAutomationExecution `
       -DocumentName "runbook name" `
       -Targets $Targets `
       -TargetParameterName "parameter name" `
       -Parameter @{"input parameter name"="input parameter value"} `
       -MaxConcurrency "10" `
       -MaxError "25%"
   ```

------

   *Targeting all Amazon EC2 instances in the current AWS account and AWS Region*

------
#### [ Linux & macOS ]

   ```
   aws ssm start-automation-execution \
       --document-name runbook name \
       --targets "Key=AWS::EC2::Instance,Values=*"  \
       --target-parameter-name instanceId \
       --parameters "input parameter name=input parameter value" \
       --max-concurrency 10 \
       --max-errors 25%
   ```

------
#### [ Windows ]

   ```
   aws ssm start-automation-execution ^
       --document-name runbook name ^
       --targets Key=AWS::EC2::Instance,Values=* ^
       --target-parameter-name instanceId ^
       --parameters "input parameter name=input parameter value" ^
       --max-concurrency 10 ^
       --max-errors 25%
   ```

------
#### [ PowerShell ]

   ```
   $Targets = New-Object Amazon.SimpleSystemsManagement.Model.Target
   $Targets.Key = "AWS::EC2::Instance"
   $Targets.Values = "*"
   
   Start-SSMAutomationExecution `
       -DocumentName "runbook name" `
       -Targets $Targets `
       -TargetParameterName "instanceId" `
       -Parameter @{"input parameter name"="input parameter value"} `
       -MaxConcurrency "10" `
       -MaxError "25%"
   ```

------

   The command returns an execution ID. Copy this ID to the clipboard. You can use this ID to view the status of the automation.

------
#### [ Linux & macOS ]

   ```
   {
       "AutomationExecutionId": "a4a3c0e9-7efd-462a-8594-01234EXAMPLE"
   }
   ```

------
#### [ Windows ]

   ```
   {
       "AutomationExecutionId": "a4a3c0e9-7efd-462a-8594-01234EXAMPLE"
   }
   ```

------
#### [ PowerShell ]

   ```
   a4a3c0e9-7efd-462a-8594-01234EXAMPLE
   ```

------

1. Run the following command to view the automation. Replace each *automation execution ID* with your own information.

------
#### [ Linux & macOS ]

   ```
   aws ssm describe-automation-executions \
       --filter Key=ExecutionId,Values=automation execution ID
   ```

------
#### [ Windows ]

   ```
   aws ssm describe-automation-executions ^
       --filter Key=ExecutionId,Values=automation execution ID
   ```

------
#### [ PowerShell ]

   ```
   Get-SSMAutomationExecutionList | `
       Where {$_.AutomationExecutionId -eq "automation execution ID"}
   ```

------

1. To view details about the automation progress, run the following command. Replace each *automation execution ID* with your own information.

------
#### [ Linux & macOS ]

   ```
   aws ssm get-automation-execution \
       --automation-execution-id automation execution ID
   ```

------
#### [ Windows ]

   ```
   aws ssm get-automation-execution ^
       --automation-execution-id automation execution ID
   ```

------
#### [ PowerShell ]

   ```
   Get-SSMAutomationExecution `
       -AutomationExecutionId automation execution ID
   ```

------

   The system returns information like the following.

------
#### [ Linux & macOS ]

   ```
   {
       "AutomationExecution": {
           "StepExecutionsTruncated": false,
           "AutomationExecutionStatus": "Success",
           "MaxConcurrency": "1",
           "Parameters": {},
           "MaxErrors": "1",
           "Outputs": {},
           "DocumentName": "AWS-StopEC2Instance",
           "AutomationExecutionId": "a4a3c0e9-7efd-462a-8594-01234EXAMPLE",
           "ResolvedTargets": {
               "ParameterValues": [
                   "i-02573cafcfEXAMPLE"
               ],
               "Truncated": false
           },
           "ExecutionEndTime": 1564681619.915,
           "Targets": [
               {
                   "Values": [
                       "DEV"
                   ],
                   "Key": "tag:ENV"
               }
           ],
           "DocumentVersion": "1",
           "ExecutionStartTime": 1564681576.09,
           "ExecutedBy": "arn:aws:sts::123456789012:assumed-role/Administrator/Admin",
           "StepExecutions": [
               {
                   "Inputs": {
                       "InstanceId": "i-02573cafcfEXAMPLE"
                   },
                   "Outputs": {},
                   "StepName": "i-02573cafcfEXAMPLE",
                   "ExecutionEndTime": 1564681619.093,
                   "StepExecutionId": "86c7b811-3896-4b78-b897-01234EXAMPLE",
                   "ExecutionStartTime": 1564681576.836,
                   "Action": "aws:executeAutomation",
                   "StepStatus": "Success"
               }
           ],
           "TargetParameterName": "InstanceId",
           "Mode": "Auto"
       }
   }
   ```

------
#### [ Windows ]

   ```
   {
       "AutomationExecution": {
           "StepExecutionsTruncated": false,
           "AutomationExecutionStatus": "Success",
           "MaxConcurrency": "1",
           "Parameters": {},
           "MaxErrors": "1",
           "Outputs": {},
           "DocumentName": "AWS-StopEC2Instance",
           "AutomationExecutionId": "a4a3c0e9-7efd-462a-8594-01234EXAMPLE",
           "ResolvedTargets": {
               "ParameterValues": [
                   "i-02573cafcfEXAMPLE"
               ],
               "Truncated": false
           },
           "ExecutionEndTime": 1564681619.915,
           "Targets": [
               {
                   "Values": [
                       "DEV"
                   ],
                   "Key": "tag:ENV"
               }
           ],
           "DocumentVersion": "1",
           "ExecutionStartTime": 1564681576.09,
           "ExecutedBy": "arn:aws:sts::123456789012:assumed-role/Administrator/Admin",
           "StepExecutions": [
               {
                   "Inputs": {
                       "InstanceId": "i-02573cafcfEXAMPLE"
                   },
                   "Outputs": {},
                   "StepName": "i-02573cafcfEXAMPLE",
                   "ExecutionEndTime": 1564681619.093,
                   "StepExecutionId": "86c7b811-3896-4b78-b897-01234EXAMPLE",
                   "ExecutionStartTime": 1564681576.836,
                   "Action": "aws:executeAutomation",
                   "StepStatus": "Success"
               }
           ],
           "TargetParameterName": "InstanceId",
           "Mode": "Auto"
       }
   }
   ```

------
#### [ PowerShell ]

   ```
   AutomationExecutionId       : a4a3c0e9-7efd-462a-8594-01234EXAMPLE
   AutomationExecutionStatus   : Success
   CurrentAction               : 
   CurrentStepName             : 
   DocumentName                : AWS-StopEC2Instance
   DocumentVersion             : 1
   ExecutedBy                  : arn:aws:sts::123456789012:assumed-role/Administrator/Admin
   ExecutionEndTime            : 8/1/2019 5:46:59 PM
   ExecutionStartTime          : 8/1/2019 5:46:16 PM
   FailureMessage              : 
   MaxConcurrency              : 1
   MaxErrors                   : 1
   Mode                        : Auto
   Outputs                     : {}
   Parameters                  : {}
   ParentAutomationExecutionId : 
   ProgressCounters            : 
   ResolvedTargets             : Amazon.SimpleSystemsManagement.Model.ResolvedTargets
   StepExecutions              : {i-02573cafcfEXAMPLE}
   StepExecutionsTruncated     : False
   Target                      : 
   TargetLocations             : {}
   TargetMaps                  : {}
   TargetParameterName         : InstanceId
   Targets                     : {tag:Name}
   ```

------
**Note**  
You can also monitor the status of the automation in the console. In the **Automation executions** list, choose the automation you just ran and then choose the **Execution steps** tab. This tab shows the status of the automation actions.

# Mapping targets for an automation
<a name="running-automations-map-targets"></a>

Use the `Targets` parameter to quickly define which resources are targeted by an automation. For example, if you want to run an automation that restarts your managed instances, then instead of manually selecting dozens of instance IDs in the console or typing them in a command, you can target instances by specifying Amazon Elastic Compute Cloud (Amazon EC2) tags with the `Targets` parameter.

When you run an automation that uses a target, AWS Systems Manager creates a child automation for each target. For example, if you target Amazon Elastic Block Store (Amazon EBS) volumes by specifying tags, and those tags resolve to 100 Amazon EBS volumes, then Systems Manager creates 100 child automations. The parent automation is complete when all child automations reach a final state.

**Note**  
Any `input parameters` that you specify at runtime (either in the **Input parameters** section of the console or by using the `parameters` option from the command line) are automatically processed by all child automations.

You can target resources for an automation by using tags, Resource Groups,and parameter values. Additionally, you can use the `TargetMaps` option to target multiple parameter values from the command line or a file. The following section describes each of these targeting options in more detail.

## Targeting a tag
<a name="target-tags"></a>

You can specify a single tag as the target of an automation. Many AWS resources support tags, including Amazon Elastic Compute Cloud (Amazon EC2) and Amazon Relational Database Service (Amazon RDS) instances, Amazon Elastic Block Store (Amazon EBS) volumes and snapshots, Resource Groups,and Amazon Simple Storage Service (Amazon S3) buckets, to name a few. You can quickly run automation on your AWS resources by targeting a tag. A tag is a key-value pair, such as Operating\$1System:Linux or Department:Finance. If you assign a specific name to a resource, then you can also use the word "Name" as a key, and the name of the resource as the value.

When you specify a tag as the target for an automation, you also specify a target parameter. The target parameter uses the `TargetParameterName` option. By choosing a target parameter, you define the type of resource on which the automation runs. The target parameter you specify with the tag must be a valid parameter defined in the runbook. For example, if you want to target dozens of EC2 instances by using tags, then choose the `InstanceId` target parameter. By choosing this parameter, you define *instances* as the resource type for the automation. When creating a custom runbook you must specify the **Target type** as `/AWS::EC2::Instance` to ensure only instances are used. Otherwise, all resources with the same tag will be targeted. When targeting instances with a tag, terminated instances might be included.

The following screenshot uses the `AWS-DetachEBSVolume` runbook. The logical target parameter is `VolumeId`.

![\[Using a tag as a target for a Systems Manager Automation\]](http://docs.aws.amazon.com/systems-manager/latest/userguide/images/automation-rate-control-tags-1-new.png)


The `AWS-DetachEBSVolume` runbook also includes a special property called **Target type**, which is set to `/AWS::EC2::Volume`. This means that if the tag-key pair `Finance:TestEnv` returns different types of resources (for example, EC2 instances, Amazon EBS volumes, Amazon EBS snapshots) then only Amazon EBS volumes will be used.

**Important**  
Target parameter names are case sensitive. If you run automations by using either the AWS Command Line Interface (AWS CLI) or AWS Tools for Windows PowerShell, then you must enter the target parameter name exactly as it's defined in the runbook. If you don't, the system returns an `InvalidAutomationExecutionParametersException` error. You can use the [DescribeDocument](https://docs.aws.amazon.com/systems-manager/latest/APIReference/API_DescribeDocument.html) API operation to see information about the available target parameters in a specific runbook. Following is an example AWS CLI command that provides information about the `AWS-DeleteSnapshot` document.  

```
aws ssm describe-document \
    --name AWS-DeleteSnapshot
```

Here are some example AWS CLI commands that target resources by using a tag.

**Example 1: Targeting a tag using a key-value pair to restart Amazon EC2 instances**

This example restarts all Amazon EC2 instances that are tagged with a key of *Department* and a value of *HumanResources*. The target parameter uses the *InstanceId* parameter from the runbook. The example uses an additional parameter to run the automation by using an Automation service role (also called an *assume role*).

```
aws ssm start-automation-execution \
    --document-name AWS-RestartEC2Instance \
    --targets Key=tag:Department,Values=HumanResources \
    --target-parameter-name InstanceId \
    --parameters "AutomationAssumeRole=arn:aws:iam::111122223333:role/AutomationServiceRole"
```

**Example 2: Targeting a tag using a key-value pair to delete Amazon EBS snapshots**

The following example uses the `AWS-DeleteSnapshot` runbook to delete all snapshots with a key of *Name* and a value of *January2018Backups*. The target parameter uses the *VolumeId* parameter.

```
aws ssm start-automation-execution \
    --document-name AWS-DeleteSnapshot \
    --targets Key=tag:Name,Values=January2018Backups \
    --target-parameter-name VolumeId
```

## Targeting AWS Resource Groups
<a name="target-resource-groups"></a>

You can specify a single AWS resource group as the target of an automation. Systems Manager creates a child automation for every object in the target Resource Group.

For example, say that one of your Resource Groups is named PatchedAMIs. This Resource Group includes a list of 25 Windows Amazon Machine Images (AMIs) that are routinely patched. If you run an automation that uses the `AWS-CreateManagedWindowsInstance` runbook and target this Resource Group, then Systems Manager creates a child automation for each of the 25 AMIs. This means, that by targeting the PatchedAMIs Resource Group, the automation creates 25 instances from a list of patched AMIs. The parent automation is complete when all child automations complete processing or reach a final state.

The following AWS CLI command applies to the PatchAMIs Resource Group example. The command takes the *AmiId* parameter for the `--target-parameter-name` option. The command doesn't include an additional parameter defining which type of instance to create from each AMI. The `AWS-CreateManagedWindowsInstance` runbook defaults to the t2.medium instance type, so this command would create 25 t2.medium Amazon EC2 instances for Windows Server.

```
aws ssm start-automation-execution \
    --document-name AWS-CreateManagedWindowsInstance \
    --targets Key=ResourceGroup,Values=PatchedAMIs  \
    --target-parameter-name AmiId
```

The following console example uses a Resource Group called t2-micro-instances.

![\[Targeting an AWS resource group with a Systems Manager automation\]](http://docs.aws.amazon.com/systems-manager/latest/userguide/images/automation-rate-control-resource-groups-new.png)


## Targeting parameter values
<a name="target-parameter-values"></a>

You can also target a parameter value. You enter `ParameterValues` as the key and then enter the specific resource value where you want the automation to run. If you specify multiple values, Systems Manager runs a child automation on each value specified.

For example, say that your runbook includes an **InstanceID** parameter. If you target the values of the **InstanceID** parameter when you run the Automation, then Systems Manager runs a child automation for each instance ID value specified. The parent automation is complete when the automation finishes running each specified instance, or if the automation fails. You can target a maximum of 50 parameter values.

The following example uses the `AWS-CreateImage` runbook. The target parameter name specified is *InstanceId*. The key uses *ParameterValues*. The values are two Amazon EC2 instance IDs. This command creates an automation for each instance, which produces an AMI from each instance. 

```
aws ssm start-automation-execution 
    --document-name AWS-CreateImage \
    --target-parameter-name InstanceId \
    --targets Key=ParameterValues,Values=i-02573cafcfEXAMPLE,i-0471e04240EXAMPLE
```

**Note**  
`AutomationAssumeRole` isn't a valid parameter. Don’t choose this item when running automation that target a parameter value.

### Targeting parameter value maps
<a name="target-maps"></a>

The `TargetMaps` option expands your ability to target `ParameterValues`. You can enter an array of parameter values by using `TargetMaps` at the command line. You can specify a maximum of 50 parameter values at the command line. If you want to run commands that specify more than 50 parameter values, then you can enter the values in a JSON file. You can then call the file from the command line.

**Note**  
The `TargetMaps` option isn't supported in the console.

Use the following format to specify multiple parameter values by using the `TargetMaps` option in a command. Replace each *example resource placeholder* with your own information.

```
aws ssm start-automation-execution \
    --document-name runbook name \
    --target-maps “parameter=value, parameter 2=value, parameter 3=value”  “parameter 4=value, parameter 5=value, parameter 6=value”
```

If you want to enter more than 50 parameter values for the `TargetMaps` option, then specify the values in a file by using the following JSON format. Using a JSON file also improves readability when providing multiple parameter values.

```
[

    {“parameter”: "value", “parameter 2”: "value", “parameter 3”: "value"},

    {“parameter 4”: "value", “parameter 5”: "value", "parameter 6": "value"}

]
```

Save the file with a .json file extension. You can call the file by using the following command. Replace each *example resource placeholder* with your own information.

```
aws ssm start-automation-execution \
    --document-name runbook name \
    –-parameters input parameters \
    --target-maps path to file/file name.json
```

You can also download the file from an Amazon Simple Storage Service (Amazon S3) bucket, as long as you have permission to read data from the bucket. Use the following command format. Replace each *example resource placeholder* with your own information.

```
aws ssm start-automation-execution \
    --document-name runbook name \
    --target-maps http://amzn-s3-demo-bucket.s3.amazonaws.com/file_name.json
```

Here is an example scenario to help you understand the `TargetMaps` option. In this scenario, a user wants to create Amazon EC2 instances of different types from different AMIs. To perform this task, the user creates a runbook named AMI\$1Testing. This runbook defines two input parameters: `instanceType` and `imageId`. 

```
{
  "description": "AMI Testing",
  "schemaVersion": "0.3",
  "assumeRole": "{{assumeRole}}",
  "parameters": {
    "assumeRole": {
      "type": "String",
      "description": "Role under which to run the automation",
      "default": ""
    },
    "instanceType": {
      "type": "String",
      "description": "Type of EC2 Instance to launch for this test"
    },
    "imageId": {
      "type": "String",
      "description": "Source AMI id from which to run instance"
    }
  },
  "mainSteps": [
    {
      "name": "runInstances",
      "action": "aws:runInstances",
      "maxAttempts": 1,
      "onFailure": "Abort",
      "inputs": {
        "ImageId": "{{imageId}}",
        "InstanceType": "{{instanceType}}",
        "MinInstanceCount": 1,
        "MaxInstanceCount": 1
      }
    }
  ],
  "outputs": [
    "runInstances.InstanceIds"
  ]
}
```

The user then specifies the following target parameter values in a file named `AMI_instance_types.json`.

```
[
  {
    "instanceType" : ["t2.micro"],     
    "imageId" : ["ami-b70554c8"]     
  },
  {
    "instanceType" : ["t2.small"],     
    "imageId" : ["ami-b70554c8"]     
  },
  {
    "instanceType" : ["t2.medium"],     
    "imageId" : ["ami-cfe4b2b0"]     
  },
  {
    "instanceType" : ["t2.medium"],     
    "imageId" : ["ami-cfe4b2b0"]     
  },
  {
    "instanceType" : ["t2.medium"],     
    "imageId" : ["ami-cfe4b2b0"]     
  }
]
```

The user can run the automation and create the five EC2 instances defined in `AMI_instance_types.json` by running the following command.

```
aws ssm start-automation-execution \
    --document-name AMI_Testing \
    --target-parameter-name imageId \
    --target-maps file:///home/TestUser/workspace/runinstances/AMI_instance_types.json
```

## Targeting all Amazon EC2 instances
<a name="target-all-instances"></a>

You can run an automation on all Amazon EC2 instances in the current AWS account and AWS Region by choosing **All instances** in the **Targets** list. For example, if you want to restart all Amazon EC2 instances your AWS account and the current AWS Region, you can choose the `AWS-RestartEC2Instance` runbook and then choose **All instances** from the **Targets** list.

![\[Targeting all Amazon EC2 instances for a runbook\]](http://docs.aws.amazon.com/systems-manager/latest/userguide/images/automation-rate-control-target-all-instances.png)


After you choose **All instances**, Systems Manager populates the **Instance** field with an asterisk (\$1) and makes the field unavailable for changes (the field is grayed out). Systems Manager also makes the **InstanceId** field in the **Input parameters** field unavailable for changes. Making these fields unavailable for changes is expected behavior if you choose to target all instances.

# Control automations at scale
<a name="running-automations-scale-controls"></a>

You can control the deployment of an automation across a fleet of AWS resources by specifying a concurrency value and an error threshold. Concurrency and error threshold are collectively called *rate controls*.

**Concurrency**  
Use Concurrency to specify how many resources are allowed to run an automation simultaneously. Concurrency helps to limit the impact or downtime on your resources when processing an automation. You can specify either an absolute number of resources, for example 20, or a percentage of the target set, for example 10%.

The queueing system delivers the automation to a single resource and waits until the initial invocation is complete before sending the automation to two more resources. The system exponentially sends the automation to more resources until the concurrency value is met.

**Error thresholds**  
Use an error threshold to specify how many automations are allowed to fail before AWS Systems Manager stops sending the automation to other resources. You can specify either an absolute number of errors, for example 10, or a percentage of the target set, for example 10%.

If you specify an absolute number of 3 errors, for example, the system stops running the automation when the fourth error is received. If you specify 0, then the system stops running the automation on additional targets after the first error result is returned.

If you send an automation to, for example, 50 instances and set the error threshold to 10%, then the system stops sending the command to additional instances when the fifth error is received. Invocations that are already running an automation when an error threshold is reached are allowed to be completed, but some of these automations might fail as well. If you need to ensure that there won’t be more errors than the number specified for the error threshold, then set the **Concurrency** value to 1 so that automations proceed one at a time. 

# Running automations in multiple AWS Regions and accounts
<a name="running-automations-multiple-accounts-regions"></a>

You can run AWS Systems Manager automations across multiple AWS Regions and AWS accounts or AWS Organizations organizational units (OUs) from a central account. Automation is a tool in AWS Systems Manager. Running automations in multiple Regions and accounts or OUs reduces the time required to administer your AWS resources while enhancing the security of your computing environment.

For example, you can do the following by using automation runbooks:
+ Implement patching and security updates centrally.
+ Remediate compliance drift on VPC configurations or Amazon S3 bucket policies.
+ Manage resources, such as Amazon Elastic Compute Cloud (Amazon EC2) EC2 instances, at scale.

The following diagram shows an example of a user who is running the `AWS-RestartEC2Instances` runbook in multiple Regions and accounts from a central account. The automation locates the instances by using the specified tags in the targeted Regions and accounts.

![\[Illustration showing Systems Manager Automation running in multiple Regions and multiple accounts.\]](http://docs.aws.amazon.com/systems-manager/latest/userguide/images/automation-multi-region-and-multi-account.png)


**Choose a central account for Automation**  
If you want to run automations across OUs, the central account must have permissions to list all of the accounts in the OUs. This is only possible from a delegated administrator account, or the management account of the organization. We recommend that you follow AWS Organizations best practices and use a delegated administrator account. For more information about AWS Organizations best practices, see [Best practices for the management account](https://docs.aws.amazon.com/organizations/latest/userguide/orgs_best-practices_mgmt-acct.html) in the *AWS Organizations User Guide*. To create a delegated administrator account for Systems Manager, you can use the `register-delegated-administrator` command with the AWS CLI as shown in the following example.

```
aws organizations register-delegated-administrator \
    --account-id delegated admin account ID \
    --service-principal ssm.amazonaws.com
```

If you want to run automations across multiple accounts that are not managed by AWS Organizations, we recommend creating a dedicated account for automation management. Running all cross-account automations from a dedicated account simplifies IAM permissions management, troubleshooting efforts, and creates a layer of separation between operations and administration. This approach is also recommended if you use AWS Organizations, but only want to target individual accounts and not OUs.

**How running automations works**  
Running automations across multiple Regions and accounts or OUs works as follows:

1. Sign in to the account that you want to configure as the Automation central account.

1. Use the [Setting up management account permissions for multi-Region and multi-account automation](#setup-management-account-iam-roles) procedure in this topic to create the following IAM roles:
   + `AWS-SystemsManager-AutomationAdministrationRole` - This role gives the user permission to run automations in multiple accounts and OUs.
   + `AWS-SystemsManager-AutomationExecutionRole` - This role gives the user permission to run automations in the targeted accounts.

1. Choose the runbook, Regions, and accounts or OUs where you want to run the automation.
**Note**  
Be sure that the target OU contains the desired accounts. If you choose a custom runbook, the runbook must be shared with all of the target accounts. For information about sharing runbooks, see [Sharing SSM documents](documents-ssm-sharing.md). For information about using shared runbooks, see [Using shared SSM documents](documents-ssm-sharing.md#using-shared-documents).

1. Run the automation.

1. Use the [GetAutomationExecution](https://docs.aws.amazon.com/systems-manager/latest/APIReference/API_GetAutomationExecution.html), [DescribeAutomationStepExecutions](https://docs.aws.amazon.com/systems-manager/latest/APIReference/API_DescribeAutomationStepExecutions.html), and [DescribeAutomationExecutions](https://docs.aws.amazon.com/systems-manager/latest/APIReference/API_DescribeAutomationExecutions.html) API operations from the AWS Systems Manager console or the AWS CLI to monitor automation progress. The output of the steps for the automation in your primary account will be the `AutomationExecutionId` of the child automations. To view the output of the child automations created in your target accounts, be sure to specify the appropriate account, Region, and `AutomationExecutionId` in your request.

## Setting up management account permissions for multi-Region and multi-account automation
<a name="setup-management-account-iam-roles"></a>

Use the following procedure to create the required IAM roles for Systems Manager Automation multi-Region and multi-account automation by using AWS CloudFormation. This procedure describes how to create the `AWS-SystemsManager-AutomationAdministrationRole` role. You only need to create this role in the Automation central account. This procedure also describes how to create the `AWS-SystemsManager-AutomationExecutionRole` role. You must create this role in *every* account that you want to target to run multi-Region and multi-account automations. We recommend using CloudFormation StackSets to create the `AWS-SystemsManager-AutomationExecutionRole` role in the accounts you want to target to run multi-Region and multi-account automations.

**To create the required IAM administration role for multi-Region and multi-account automations by using CloudFormation**

1. Download and unzip the [https://docs.aws.amazon.com/systems-manager/latest/userguide/samples/AWS-SystemsManager-AutomationAdministrationRole.zip](https://docs.aws.amazon.com/systems-manager/latest/userguide/samples/AWS-SystemsManager-AutomationAdministrationRole.zip).

   -or-

   If your accounts are managed by AWS Organizations [https://docs.aws.amazon.com/systems-manager/latest/userguide/samples/AWS-SystemsManager-AutomationAdministrationRole (org).zip](https://docs.aws.amazon.com/systems-manager/latest/userguide/samples/AWS-SystemsManager-AutomationAdministrationRole (org).zip).

   These files contain the `AWS-SystemsManager-AutomationAdministrationRole.yaml` and `AWS-SystemsManager-AutomationAdministrationRole (org).yaml` CloudFormation template files, respectively.

1. Open the CloudFormation console at [https://console.aws.amazon.com/cloudformation](https://console.aws.amazon.com/cloudformation/).

1. Choose **Create stack**.

1. In the **Specify template** section, choose **Upload a template**.

1. Choose **Choose file**, and then choose the `AWS-SystemsManager-AutomationAdministrationRole.yaml` or `AWS-SystemsManager-AutomationAdministrationRole (org).yaml` CloudFormation template file, depending on your selection in step 1.

1. Choose **Next**.

1. On the **Specify stack details** page, in the **Stack name** field, enter a name. 

1. Choose **Next**.

1. On the **Configure stack options** page, enter values for any options you want to use. Choose **Next**.

1. On the **Review** page, scroll down and choose the **I acknowledge that CloudFormation might create IAM resources with custom names** option.

1. Choose **Create stack**.

CloudFormation shows the **CREATE\$1IN\$1PROGRESS** status for approximately three minutes. The status changes to **CREATE\$1COMPLETE**.

You must repeat the following procedure in *every* account that you want to target to run multi-Region and multi-account automations.

**To create the required IAM automation role for multi-Region and multi-account automations by using CloudFormation**

1. Download the [https://docs.aws.amazon.com/systems-manager/latest/userguide/samples/AWS-SystemsManager-AutomationExecutionRole.zip](https://docs.aws.amazon.com/systems-manager/latest/userguide/samples/AWS-SystemsManager-AutomationExecutionRole.zip).

   -or

   If your accounts are managed by AWS Organizations [https://docs.aws.amazon.com/systems-manager/latest/userguide/samples/AWS-SystemsManager-AutomationExecutionRole (org).zip](https://docs.aws.amazon.com/systems-manager/latest/userguide/samples/AWS-SystemsManager-AutomationExecutionRole (org).zip).

   These files contains the `AWS-SystemsManager-AutomationExecutionRole.yaml` and `AWS-SystemsManager-AutomationExecutionRole (org).yaml`CloudFormation template files, respectively.

1. Open the CloudFormation console at [https://console.aws.amazon.com/cloudformation](https://console.aws.amazon.com/cloudformation/).

1. Choose **Create stack**.

1. In the **Specify template** section, choose **Upload a template**.

1. Choose **Choose file**, and then choose the `AWS-SystemsManager-AutomationExecutionRole.yaml` or `AWS-SystemsManager-AutomationExecutionRole (org).yaml` CloudFormation template file, depending on your selection in step 1.

1. Choose **Next**.

1. On the **Specify stack details** page, in the **Stack name** field, enter a name. 

1. In the **Parameters** section, in the **AdminAccountId** field, enter the ID for the Automation central account.

1. If you are setting up this role for an AWS Organizations environment, there is another field in the section called **OrganizationID**. Enter the ID of your AWS organization.

1. Choose **Next**.

1. On the **Configure stack options** page, enter values for any options you want to use. Choose **Next**.

1. On the **Review** page, scroll down and choose the **I acknowledge that CloudFormation might create IAM resources with custom names** option.

1. Choose **Create stack**.

CloudFormation shows the **CREATE\$1IN\$1PROGRESS** status for approximately three minutes. The status changes to **CREATE\$1COMPLETE**.

## Run an automation in multiple Regions and accounts (console)
<a name="multiple-console"></a>

The following procedure describes how to use the Systems Manager console to run an automation in multiple Regions and accounts from the Automation management account.

**Before you begin**  
Before you complete the following procedure, note the following information:
+ The user or role you use to run a multi-Region or multi-account automation must have the `iam:PassRole` permission for the `AWS-SystemsManager-AutomationAdministrationRole` role.
+ AWS account IDs or OUs where you want to run the automation.
+ [Regions supported by Systems Manager](https://docs.aws.amazon.com/general/latest/gr/ssm.html#ssm_region) where you want to run the automation.
+ The tag key and the tag value, or the name of the resource group, where you want to run the automation.

**To run an automation in multiple Regions and accounts**

1. Open the AWS Systems Manager console at [https://console.aws.amazon.com/systems-manager/](https://console.aws.amazon.com/systems-manager/).

1. In the navigation pane, choose **Automation**, and then choose **Execute automation**.

1. In the **Automation document** list, choose a runbook. Choose one or more options in the **Document categories** pane to filter SSM documents according to their purpose. To view a runbook that you own, choose the **Owned by me** tab. To view a runbook that is shared with your account, choose the **Shared with me** tab. To view all runbooks, choose the **All documents** tab.
**Note**  
You can view information about a runbook by choosing the runbook name.

1. In the **Document details** section, verify that **Document version** is set to the version that you want to run. The system includes the following version options: 
   + **Default version at runtime** – Choose this option if the Automation runbook is updated periodically and a new default version is assigned.
   + **Latest version at runtime** – Choose this option if the Automation runbook is updated periodically, and you want to run the version that was most recently updated.
   + **1 (Default)** – Choose this option to run the first version of the document, which is the default.

1. Choose **Next**.

1. On the **Execute automation document** page, choose **Multi-account and Region**.

1. In the **Target accounts and Regions** section, use the **Accounts, organizational units (OUs), and roots** field to specify the different AWS accounts or AWS organizational units (OUs) where you want to run the automation. Separate multiple accounts or OUs with a comma. 

   1. (Optional) Select the **Include child OUs** checkbox to include all child organizational units within the specified OUs.

   1. (Optional) In the **Exclude accounts and organizational units (OUs)** field, enter a comma-separated list of account IDs and OU IDs that you want to exclude from the expanded entities entered above.

1. Use the **Regions** list to choose one or more Regions where you want to run the automation.

1. Use the **Multi-Region and account rate control** options to restrict the automation to a limited number of accounts running in a limited number of Regions. These options don't restrict the number of AWS resources that can run the automations. 

   1. In the **Location (account-Region pair) concurrency** section, choose an option to restrict the number of automations that can run in multiple accounts and Regions at the same time. For example, if you choose to run an automation in five (5) AWS accounts, which are located in four (4) AWS Regions, then Systems Manager runs automations in a total of 20 account-Region pairs. You can use this option to specify an absolute number, such as **2**, so that the automation only runs in two account-Region pairs at the same time. Or you can specify a percentage of the account-Region pairs that can run at the same time. For example, with 20 account-Region pairs, if you specify 20%, then the automation simultaneously runs in a maximum of five (5) account-Region pairs. 
      + Choose **targets** to enter an absolute number of account-Region pairs that can run the automation simultaneously.
      + Choose **percent** to enter a percentage of the total number of account-Region pairs that can run the automation simultaneously.

   1. In the **Error threshold** section, choose an option:
      + Choose **errors** to enter an absolute number of errors allowed before Automation stops sending the automation to other resources.
      + Choose **percent** to enter a percentage of errors allowed before Automation stops sending the automation to other resources.

1. In the **Targets** section, choose how you want to target the AWS resources where you want to run the Automation. These options are required.

   1. Use the **Parameter** list to choose a parameter. The items in the **Parameter** list are determined by the parameters in the Automation runbook that you selected at the start of this procedure. By choosing a parameter you define the type of resource on which the Automation workflow runs. 

   1. Use the **Targets** list to choose how you want to target resources.

      1. If you chose to target resources by using parameter values, then enter the parameter value for the parameter you chose in the **Input parameters** section.

      1. If you chose to target resources by using AWS Resource Groups, then choose the name of the group from the **Resource Group** list.

      1. If you chose to target resources by using tags, then enter the tag key and (optionally) the tag value in the fields provided. Choose **Add**.

      1. If you want to run an Automation runbook on all instances in the current AWS account and AWS Region, then choose **All instances**.

1. In the **Input parameters** section, specify the required inputs. Choose the `AWS-SystemsManager-AutomationAdministrationRole` IAM service role from the **AutomationAssumeRole** list.
**Note**  
You might not need to choose some of the options in the **Input parameters** section. This is because you targeted resources in multiple Regions and accounts by using tags or a resource group. For example, if you chose the `AWS-RestartEC2Instance` runbook, then you don't need to specify or choose instance IDs in the **Input parameters** section. The automation locates the instances to restart by using the tags you specified. 

1. (Optional) Choose a CloudWatch alarm to apply to your automation for monitoring. To attach a CloudWatch alarm to your automation, the IAM principal that starts the automation must have permission for the `iam:createServiceLinkedRole` action. For more information about CloudWatch alarms, see [Using Amazon CloudWatch alarms](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/AlarmThatSendsEmail.html). Note that if your alarm activates, the automation is cancelled and any `OnCancel` steps you have defined run. If you use AWS CloudTrail, you will see the API call in your trail.

1. Use the options in the **Rate control** section to restrict the number of AWS resources that can run the Automation within each account-Region pair. 

   In the **Concurrency** section, choose an option: 
   + Choose **targets** to enter an absolute number of targets that can run the Automation workflow simultaneously.
   + Choose **percentage** to enter a percentage of the target set that can run the Automation workflow simultaneously.

1. In the **Error threshold** section, choose an option:
   + Choose **errors** to enter an absolute number of errors allowed before Automation stops sending the workflow to other resources.
   + Choose **percentage** to enter a percentage of errors allowed before Automation stops sending the workflow to other resources.

1. Choose **Execute**.

After an automation execution completes, you can rerun the execution with the same or modified parameters. For more information, see [Rerunning automation executions](automation-rerun-executions.md).

## Run an automation in multiple Regions and accounts (command line)
<a name="multiple-cli"></a>

The following procedure describes how to use the AWS CLI (on Linux or Windows) or AWS Tools for PowerShell to run an automation in multiple Regions and accounts from the Automation management account.

**Before you begin**  
Before you complete the following procedure, note the following information:
+ AWS account IDs or OUs where you want to run the automation.
+ [Regions supported by Systems Manager](https://docs.aws.amazon.com/general/latest/gr/ssm.html#ssm_region) where you want to run the automation.
+ The tag key and the tag value, or the name of the resource group, where you want to run the automation.

**To run an automation in multiple Regions and accounts**

1. Install and configure the AWS CLI or the AWS Tools for PowerShell, if you haven't already.

   For information, see [Installing or updating the latest version of the AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html) and [Installing the AWS Tools for PowerShell](https://docs.aws.amazon.com/powershell/latest/userguide/pstools-getting-set-up.html).

1. Use the following format to create a command to run an automation in multiple Regions and accounts. Replace each *example resource placeholder* with your own information.

------
#### [ Linux & macOS ]

   ```
   aws ssm start-automation-execution \
           --document-name runbook name \
           --parameters AutomationAssumeRole=arn:aws:iam::management account ID:role/AWS-SystemsManager-AutomationAdministrationRole \
           --target-parameter-name parameter name \
           --targets Key=tag key,Values=value \
           --target-locations Accounts=account ID,account ID 2,Regions=Region,Region 2,ExecutionRoleName=AWS-SystemsManager-AutomationExecutionRole
   ```

------
#### [ Windows ]

   ```
   aws ssm start-automation-execution ^
           --document-name runbook name ^
           --parameters AutomationAssumeRole=arn:aws:iam::management account ID:role/AWS-SystemsManager-AutomationAdministrationRole ^
           --target-parameter-name parameter name ^
           --targets Key=tag key,Values=value ^
           --target-locations Accounts=account ID,account ID 2,Regions=Region,Region 2,ExecutionRoleName=AWS-SystemsManager-AutomationExecutionRole
   ```

------
#### [ PowerShell ]

   ```
   $Targets = New-Object Amazon.SimpleSystemsManagement.Model.Target
       $Targets.Key = "tag key"
       $Targets.Values = "value"
       
       Start-SSMAutomationExecution `
           -DocumentName "runbook name" `
           -Parameter @{
           "AutomationAssumeRole"="arn:aws:iam::management account ID:role/AWS-SystemsManager-AutomationAdministrationRole" } `
           -TargetParameterName "parameter name" `
           -Target $Targets `
           -TargetLocation @{
           "Accounts"="account ID","account ID 2";
           "Regions"="Region","Region 2";
           "ExecutionRoleName"="AWS-SystemsManager-AutomationExecutionRole" }
   ```

------

**Examples: Running an automation in multiple Regions and accounts**  
The following are examples demonstrating how to use the AWS CLI and PowerShell to run automations in multiple accounts and Regions with a single command.

   **Example 1**: This example restarts EC2 instances in three Regions across an entire AWS Organizations organization. This is achieved by targeting the root ID of the organization, and including child OUs.

------
#### [ Linux & macOS ]

   ```
   aws ssm start-automation-execution \
           --document-name "AWS-RestartEC2Instance" \
           --target-parameter-name InstanceId \
           --targets '[{"Key":"AWS::EC2::Instance","Values":["*"]}]' \
           --target-locations '[{
               "Accounts": ["r-example"],
               "IncludeChildOrganizationUnits": true,
               "Regions": ["us-east-1", "us-east-2", "us-west-2"]
           }]'
   ```

------
#### [ Windows ]

   ```
   aws ssm start-automation-execution \
           --document-name "AWS-RestartEC2Instance" ^
           --target-parameter-name InstanceId ^
           --targets '[{"Key":"AWS::EC2::Instance","Values":["*"]}]' ^
           --target-locations '[{
               "Accounts": ["r-example"],
               "IncludeChildOrganizationUnits": true,
               "Regions": ["us-east-1", "us-east-2", "us-west-2"]
           }]'
   ```

------
#### [ PowerShell ]

   ```
   Start-SSMAutomationExecution `
           -DocumentName "AWS-RestartEC2Instance" `
           -TargetParameterName "InstanceId" `
           -Targets '[{"Key":"AWS::EC2::Instance","Values":["*"]}]'
           -TargetLocation @{
               "Accounts"="r-example";
               "Regions"="us-east-1", "us-east-2", "us-west-2";
               "IncludeChildOrganizationUnits"=true}
   ```

------

   **Example 2**: This example restarts specific EC2 instances in different accounts and Regions.
**Note**  
The `TargetLocationMaxConcurrency` option is available using the AWS CLI and AWS SDKs.

------
#### [ Linux & macOS ]

   ```
   aws ssm start-automation-execution \
           --document-name "AWS-RestartEC2Instance" \
           --target-parameter-name InstanceId \
           --target-locations '[{
               "Accounts": ["123456789012"],
               "Targets": [{
                   "Key":"ParameterValues",
                   "Values":["i-02573cafcfEXAMPLE", "i-0471e04240EXAMPLE"]
               }],
               "TargetLocationMaxConcurrency": "100%",
               "Regions": ["us-east-1"]
           }, {
               "Accounts": ["987654321098"],
               "Targets": [{
                   "Key":"ParameterValues",
                   "Values":["i-07782c72faEXAMPLE"]
               }],
               "TargetLocationMaxConcurrency": "100%",
               "Regions": ["us-east-2"]
           }]'
   ```

------
#### [ Windows ]

   ```
   aws ssm start-automation-execution ^
           --document-name "AWS-RestartEC2Instance" ^
           --target-parameter-name InstanceId ^
           --target-locations '[{
               "Accounts": ["123456789012"],
               "Targets": [{
                   "Key":"ParameterValues",
                   "Values":["i-02573cafcfEXAMPLE", "i-0471e04240EXAMPLE"]
               }],
               "TargetLocationMaxConcurrency": "100%",
               "Regions": ["us-east-1"]
           }, {
               "Accounts": ["987654321098"],
               "Targets": [{
                   "Key":"ParameterValues",
                   "Values":["i-07782c72faEXAMPLE"]
               }],
               "TargetLocationMaxConcurrency": "100%",
               "Regions": ["us-east-2"]
           }]'
   ```

------
#### [ PowerShell ]

   ```
   Start-SSMAutomationExecution `
           -DocumentName "AWS-RestartEC2Instance" `
           -TargetParameterName "InstanceId" `
           -Targets '[{"Key":"AWS::EC2::Instance","Values":["*"]}]'
           -TargetLocation @({
               "Accounts"="123456789012",
               "Targets"= @{
                   "Key":"ParameterValues",
                   "Values":["i-02573cafcfEXAMPLE", "i-0471e04240EXAMPLE"]
               },
               "TargetLocationMaxConcurrency"="100%",
               "Regions"=["us-east-1"]
           }, {
               "Accounts"="987654321098",
               "Targets": @{
                   "Key":"ParameterValues",
                   "Values":["i-07782c72faEXAMPLE"]
               },
               "TargetLocationMaxConcurrency": "100%",
               "Regions"=["us-east-2"]
           })
   ```

------

   **Example 3**: This example demonstrates specifying multiple AWS accounts and Regions where the automation should run using the `--target-locations-url` option. The value for this option must be a JSON file in a publicly accessible [presigned Amazon S3 URL](https://docs.aws.amazon.com/AmazonS3/latest/userguide/using-presigned-url.html).
**Note**  
`--target-locations-url` is available when using the AWS CLI and AWS SDKs.

------
#### [ Linux & macOS ]

   ```
   aws ssm start-automation-execution \
       --document-name "MyCustomAutomationRunbook" \
       --target-locations-url "https://amzn-s3-demo-bucket.s3.amazonaws.com/target-locations.json"
   ```

------
#### [ Windows ]

   ```
   aws ssm start-automation-execution ^
       --document-name "MyCustomAutomationRunbook" ^
       --target-locations-url "https://amzn-s3-demo-bucket.s3.amazonaws.com/target-locations.json"
   ```

------
#### [ PowerShell ]

   ```
   Start-SSMAutomationExecution `
       -DocumentName "MyCustomAutomationRunbook" `
       -TargetLocationsUrl "https://amzn-s3-demo-bucket.s3.amazonaws.com/target-locations.json"
   ```

------

   Sample content for the JSON file:

   ```
   [
   { 
            "Accounts": [ "123456789012", "987654321098", "456789123012" ],
            "ExcludeAccounts": [ "111222333444", "999888444666" ],
            "ExecutionRoleName": "MyAutomationExecutionRole",
            "IncludeChildOrganizationUnits": true,
            "Regions": [ "us-east-1", "us-west-2", "ap-south-1", "ap-northeast-1" ],
            "Targets": ["Key": "AWS::EC2::Instance", "Values": ["i-2"]],
            "TargetLocationMaxConcurrency": "50%",
            "TargetLocationMaxErrors": "10",
            "TargetsMaxConcurrency": "20",
            "TargetsMaxErrors": "12"
    }
   ]
   ```

   **Example 4**: This example restarts EC2 instances in the `123456789012` and `987654321098` accounts, which are located in the `us-east-2` and `us-west-1` Regions. The instances must be tagged with the tag key-pair value `Env-PROD`.

------
#### [ Linux & macOS ]

   ```
   aws ssm start-automation-execution \
           --document-name AWS-RestartEC2Instance \
           --parameters AutomationAssumeRole=arn:aws:iam::123456789012:role/AWS-SystemsManager-AutomationAdministrationRole \
           --target-parameter-name InstanceId \
           --targets Key=tag:Env,Values=PROD \
           --target-locations Accounts=123456789012,987654321098,Regions=us-east-2,us-west-1,ExecutionRoleName=AWS-SystemsManager-AutomationExecutionRole
   ```

------
#### [ Windows ]

   ```
   aws ssm start-automation-execution ^
           --document-name AWS-RestartEC2Instance ^
           --parameters AutomationAssumeRole=arn:aws:iam::123456789012:role/AWS-SystemsManager-AutomationAdministrationRole ^
           --target-parameter-name InstanceId ^
           --targets Key=tag:Env,Values=PROD ^
           --target-locations Accounts=123456789012,987654321098,Regions=us-east-2,us-west-1,ExecutionRoleName=AWS-SystemsManager-AutomationExecutionRole
   ```

------
#### [ PowerShell ]

   ```
   $Targets = New-Object Amazon.SimpleSystemsManagement.Model.Target
       $Targets.Key = "tag:Env"
       $Targets.Values = "PROD"
       
       Start-SSMAutomationExecution `
           -DocumentName "AWS-RestartEC2Instance" `
           -Parameter @{
           "AutomationAssumeRole"="arn:aws:iam::123456789012:role/AWS-SystemsManager-AutomationAdministrationRole" } `
           -TargetParameterName "InstanceId" `
           -Target $Targets `
           -TargetLocation @{
           "Accounts"="123456789012","987654321098";
           "Regions"="us-east-2","us-west-1";
           "ExecutionRoleName"="AWS-SystemsManager-AutomationExecutionRole" }
   ```

------

   **Example 5**: This example restarts EC2 instances in the `123456789012` and `987654321098` accounts, which are located in the `eu-central-1` Region. The instances must be members of the `prod-instances` AWS resource group.

------
#### [ Linux & macOS ]

   ```
   aws ssm start-automation-execution \
           --document-name AWS-RestartEC2Instance \
           --parameters AutomationAssumeRole=arn:aws:iam::123456789012:role/AWS-SystemsManager-AutomationAdministrationRole \
           --target-parameter-name InstanceId \
           --targets Key=ResourceGroup,Values=prod-instances \
           --target-locations Accounts=123456789012,987654321098,Regions=eu-central-1,ExecutionRoleName=AWS-SystemsManager-AutomationExecutionRole
   ```

------
#### [ Windows ]

   ```
   aws ssm start-automation-execution ^
           --document-name AWS-RestartEC2Instance ^
           --parameters AutomationAssumeRole=arn:aws:iam::123456789012:role/AWS-SystemsManager-AutomationAdministrationRole ^
           --target-parameter-name InstanceId ^
           --targets Key=ResourceGroup,Values=prod-instances ^
           --target-locations Accounts=123456789012,987654321098,Regions=eu-central-1,ExecutionRoleName=AWS-SystemsManager-AutomationExecutionRole
   ```

------
#### [ PowerShell ]

   ```
   $Targets = New-Object Amazon.SimpleSystemsManagement.Model.Target
       $Targets.Key = "ResourceGroup"
       $Targets.Values = "prod-instances"
       
       Start-SSMAutomationExecution `
           -DocumentName "AWS-RestartEC2Instance" `
           -Parameter @{
           "AutomationAssumeRole"="arn:aws:iam::123456789012:role/AWS-SystemsManager-AutomationAdministrationRole" } `
           -TargetParameterName "InstanceId" `
           -Target $Targets `
           -TargetLocation @{
           "Accounts"="123456789012","987654321098";
           "Regions"="eu-central-1";
           "ExecutionRoleName"="AWS-SystemsManager-AutomationExecutionRole" }
   ```

------

   **Example 6**: This example restarts EC2 instances in the `ou-1a2b3c-4d5e6c` AWS organizational unit (OU). The instances are located in the `us-west-1` and `us-west-2` Regions. The instances must be members of the `WebServices` AWS resource group.

------
#### [ Linux & macOS ]

   ```
   aws ssm start-automation-execution \
           --document-name AWS-RestartEC2Instance \
           --parameters AutomationAssumeRole=arn:aws:iam::123456789012:role/AWS-SystemsManager-AutomationAdministrationRole \
           --target-parameter-name InstanceId \
           --targets Key=ResourceGroup,Values=WebServices \
           --target-locations Accounts=ou-1a2b3c-4d5e6c,Regions=us-west-1,us-west-2,ExecutionRoleName=AWS-SystemsManager-AutomationExecutionRole
   ```

------
#### [ Windows ]

   ```
   aws ssm start-automation-execution ^
           --document-name AWS-RestartEC2Instance ^
           --parameters AutomationAssumeRole=arn:aws:iam::123456789012:role/AWS-SystemsManager-AutomationAdministrationRole ^
           --target-parameter-name InstanceId ^
           --targets Key=ResourceGroup,Values=WebServices ^
           --target-locations Accounts=ou-1a2b3c-4d5e6c,Regions=us-west-1,us-west-2,ExecutionRoleName=AWS-SystemsManager-AutomationExecutionRole
   ```

------
#### [ PowerShell ]

   ```
   $Targets = New-Object Amazon.SimpleSystemsManagement.Model.Target
       $Targets.Key = "ResourceGroup"
       $Targets.Values = "WebServices"
       
       Start-SSMAutomationExecution `
           -DocumentName "AWS-RestartEC2Instance" `
           -Parameter @{
           "AutomationAssumeRole"="arn:aws:iam::123456789012:role/AWS-SystemsManager-AutomationAdministrationRole" } `
           -TargetParameterName "InstanceId" `
           -Target $Targets `
           -TargetLocation @{
           "Accounts"="ou-1a2b3c-4d5e6c";
           "Regions"="us-west-1";
           "ExecutionRoleName"="AWS-SystemsManager-AutomationExecutionRole" }
   ```

------

   The system returns information similar to the following.

------
#### [ Linux & macOS ]

   ```
   {
           "AutomationExecutionId": "4f7ca192-7e9a-40fe-9192-5cb15EXAMPLE"
       }
   ```

------
#### [ Windows ]

   ```
   {
           "AutomationExecutionId": "4f7ca192-7e9a-40fe-9192-5cb15EXAMPLE"
       }
   ```

------
#### [ PowerShell ]

   ```
   4f7ca192-7e9a-40fe-9192-5cb15EXAMPLE
   ```

------

1. Run the following command to view details for the automation. Replace *automation execution ID* with your own information.

------
#### [ Linux & macOS ]

   ```
   aws ssm describe-automation-executions \
           --filters Key=ExecutionId,Values=automation execution ID
   ```

------
#### [ Windows ]

   ```
   aws ssm describe-automation-executions ^
           --filters Key=ExecutionId,Values=automation execution ID
   ```

------
#### [ PowerShell ]

   ```
   Get-SSMAutomationExecutionList | `
           Where {$_.AutomationExecutionId -eq "automation execution ID"}
   ```

------

1. Run the following command to view details about the automation progress.

------
#### [ Linux & macOS ]

   ```
   aws ssm get-automation-execution \
           --automation-execution-id 4f7ca192-7e9a-40fe-9192-5cb15EXAMPLE
   ```

------
#### [ Windows ]

   ```
   aws ssm get-automation-execution ^
           --automation-execution-id 4f7ca192-7e9a-40fe-9192-5cb15EXAMPLE
   ```

------
#### [ PowerShell ]

   ```
   Get-SSMAutomationExecution `
           -AutomationExecutionId a4a3c0e9-7efd-462a-8594-01234EXAMPLE
   ```

------
**Note**  
You can also monitor the status of the automation in the console. In the **Automation executions** list, choose the automation you just ran and then choose the **Execution steps** tab. This tab shows the status of the automation actions.

**More info**  
[Centralized multi-account and multi-Region patching with AWS Systems Manager Automation](https://aws.amazon.com/blogs/mt/centralized-multi-account-and-multi-region-patching-with-aws-systems-manager-automation/)

# Run automations based on EventBridge events
<a name="running-automations-event-bridge"></a>

You can start an automation by specifying a runbook as the target of an Amazon EventBridge event. You can start automations according to a schedule, or when a specific AWS system event occurs. For example, let's say you create a runbook named *BootStrapInstances* that installs software on an instance when an instance starts. To specify the *BootStrapInstances* runbook (and corresponding automation) as a target of an EventBridge event, you first create a new EventBridge rule. (Here's an example rule: **Service name**: EC2, **Event Type**: EC2 Instance State-change Notification, **Specific state(s)**: running, **Any instance**.) Then you use the following procedures to specify the *BootStrapInstances* runbook as the target of the event using the EventBridge console and AWS Command Line Interface (AWS CLI). When a new instance starts, the system runs the automation and installs software.

For information about creating runbooks, see [Creating your own runbooks](automation-documents.md).

## Creating an EventBridge event that uses a runbook (console)
<a name="automation-cwe-target-console"></a>

Use the following procedure to configure a runbook as the target of a EventBridge event.

**To configure a runbook as a target of a EventBridge event rule**

1. Open the Amazon EventBridge console at [https://console.aws.amazon.com/events/](https://console.aws.amazon.com/events/).

1. In the navigation pane, choose **Rules**.

1. Choose **Create rule**.

1. Enter a name and description for the rule.

   A rule can't have the same name as another rule in the same Region and on the same event bus.

1. For **Event bus**, choose the event bus that you want to associate with this rule. If you want this rule to respond to matching events that come from your own AWS account, select **default**. When an AWS service in your account emits an event, it always goes to your account’s default event bus.

1. Choose how the rule is triggered.    
[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/systems-manager/latest/userguide/running-automations-event-bridge.html)

1. Choose **Next**.

1. For **Target types**, choose **AWS service**.

1. For **Select a target**, choose **Systems Manager Automation**. 

1. For **Document**, choose a runbook to use when your target is invoked.

1. In the **Configure automation parameter(s)** section, either keep the default parameter values (if available) or enter your own values. 
**Note**  
To create a target, you must specify a value for each required parameter. If you don't, the system creates the rule, but the rule won't run.

1. For many target types, EventBridge needs permissions to send events to the target. In these cases, EventBridge can create the IAM role needed for your rule to run. Do one of the following:
   + To create an IAM role automatically, choose **Create a new role for this specific resource**.
   + To use an IAM role that you created earlier, choose **Use existing role** and select the existing role from the dropdown. Note that you might need to update the trust policy for your IAM role to include EventBridge. The following is an example:

------
#### [ JSON ]

****  

   ```
   {
       "Version":"2012-10-17",		 	 	 
       "Statement": [
           {
               "Sid": "",
               "Effect": "Allow",
               "Principal": {
                   "Service": [
                       "events.amazonaws.com",
                       "ssm.amazonaws.com"
                   ]
               },
               "Action": "sts:AssumeRole"
           }
       ]
   }
   ```

------

1. Choose **Next**.

1. (Optional) Enter one or more tags for the rule. For more information, see [Tagging Your Amazon EventBridge Resources](https://docs.aws.amazon.com/eventbridge/latest/userguide/eventbridge-tagging.html) in the *Amazon EventBridge User Guide*.

1. Choose **Next**.

1. Review the details of the rule and choose **Create rule**.

## Create an EventBridge event that uses a runbook (command line)
<a name="automation-cwe-target-commandline"></a>

The following procedure describes how to use the AWS CLI (on Linux or Windows) or AWS Tools for PowerShell to create an EventBridge event rule and configure a runbook as the target.

**To configure a runbook as a target of an EventBridge event rule**

1. Install and configure the AWS CLI or the AWS Tools for PowerShell, if you haven't already.

   For information, see [Installing or updating the latest version of the AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html) and [Installing the AWS Tools for PowerShell](https://docs.aws.amazon.com/powershell/latest/userguide/pstools-getting-set-up.html).

1. Create a command to specify a new EventBridge event rule. Replace each *example resource placeholder* with your own information.

   *Triggers based on a schedule*

------
#### [ Linux & macOS ]

   ```
   aws events put-rule \
   --name "rule name" \
   --schedule-expression "cron or rate expression"
   ```

------
#### [ Windows ]

   ```
   aws events put-rule ^
   --name "rule name" ^
   --schedule-expression "cron or rate expression"
   ```

------
#### [ PowerShell ]

   ```
   Write-CWERule `
   -Name "rule name" `
   -ScheduleExpression "cron or rate expression"
   ```

------

   The following example creates an EventBridge event rule that starts every day at 9:00 AM (UTC).

------
#### [ Linux & macOS ]

   ```
   aws events put-rule \
   --name "DailyAutomationRule" \
   --schedule-expression "cron(0 9 * * ? *)"
   ```

------
#### [ Windows ]

   ```
   aws events put-rule ^
   --name "DailyAutomationRule" ^
   --schedule-expression "cron(0 9 * * ? *)"
   ```

------
#### [ PowerShell ]

   ```
   Write-CWERule `
   -Name "DailyAutomationRule" `
   -ScheduleExpression "cron(0 9 * * ? *)"
   ```

------

   *Triggers based on an event*

------
#### [ Linux & macOS ]

   ```
   aws events put-rule \
   --name "rule name" \
   --event-pattern "{\"source\":[\"aws.service\"],\"detail-type\":[\"service event detail type\"]}"
   ```

------
#### [ Windows ]

   ```
   aws events put-rule ^
   --name "rule name" ^
   --event-pattern "{\"source\":[\"aws.service\"],\"detail-type\":[\"service event detail type\"]}"
   ```

------
#### [ PowerShell ]

   ```
   Write-CWERule `
   -Name "rule name" `
   -EventPattern '{"source":["aws.service"],"detail-type":["service event detail type"]}'
   ```

------

   The following example creates an EventBridge event rule that starts when any EC2 instance in the Region changes state.

------
#### [ Linux & macOS ]

   ```
   aws events put-rule \
   --name "EC2InstanceStateChanges" \
   --event-pattern "{\"source\":[\"aws.ec2\"],\"detail-type\":[\"EC2 Instance State-change Notification\"]}"
   ```

------
#### [ Windows ]

   ```
   aws events put-rule ^
   --name "EC2InstanceStateChanges" ^
   --event-pattern "{\"source\":[\"aws.ec2\"],\"detail-type\":[\"EC2 Instance State-change Notification\"]}"
   ```

------
#### [ PowerShell ]

   ```
   Write-CWERule `
   -Name "EC2InstanceStateChanges" `
   -EventPattern '{"source":["aws.ec2"],"detail-type":["EC2 Instance State-change Notification"]}'
   ```

------

   The command returns details for the new EventBridge rule similar to the following.

------
#### [ Linux & macOS ]

   ```
   {
   "RuleArn": "arn:aws:events:us-east-1:123456789012:rule/automationrule"
   }
   ```

------
#### [ Windows ]

   ```
   {
   "RuleArn": "arn:aws:events:us-east-1:123456789012:rule/automationrule"
   }
   ```

------
#### [ PowerShell ]

   ```
   arn:aws:events:us-east-1:123456789012:rule/EC2InstanceStateChanges
   ```

------

1. Create a command to specify a runbook as a target of the EventBridge event rule you created in step 2. Replace each *example resource placeholder* with your own information.

------
#### [ Linux & macOS ]

   ```
   aws events put-targets \
   --rule rule name \
   --targets '{"Arn": " arn:aws:ssm:region:account ID:automation-definition/runbook name","Input":"{\"Message\":[\"{\\\"Key\\\":\\\"key name\\\",\\\"Values\\\":[\\\"value\\\"]}\"]}","Id": "target ID","RoleArn": "arn:aws:iam::123456789012:role/service-role/EventBridge service role"}'
   ```

------
#### [ Windows ]

   ```
   aws events put-targets ^
   --rule rule name ^
   --targets '{"Arn": "arn:aws:ssm:region:account ID:automation-definition/runbook name","Input":"{\"Message\":[\"{\\\"Key\\\":\\\"key name\\\",\\\"Values\\\":[\\\"value\\\"]}\"]}","Id": "target ID","RoleArn": "arn:aws:iam::123456789012:role/service-role/EventBridge service role"}'
   ```

------
#### [ PowerShell ]

   ```
   $Target = New-Object Amazon.CloudWatchEvents.Model.Target
   $Target.Id = "target ID"
   $Target.Arn = "arn:aws:ssm:region:account ID:automation-definition/runbook name"
   $Target.RoleArn = "arn:aws:iam::123456789012:role/service-role/EventBridge service role"
   $Target.Input = '{"input parameter":["value"],"AutomationAssumeRole":["arn:aws:iam::123456789012:role/AutomationServiceRole"]}'
   
   Write-CWETarget `
   -Rule "rule name" `
   -Target $Target
   ```

------

   The following example creates an EventBridge event target that starts the specified instance ID using the runbook `AWS-StartEC2Instance`.

------
#### [ Linux & macOS ]

   ```
   aws events put-targets \
   --rule DailyAutomationRule \
   --targets '{"Arn": "arn:aws:ssm:region:*:automation-definition/AWS-StartEC2Instance","Input":"{\"InstanceId\":[\"i-02573cafcfEXAMPLE\"],\"AutomationAssumeRole\":[\"arn:aws:iam::123456789012:role/AutomationServiceRole\"]}","Id": "Target1","RoleArn": "arn:aws:iam::123456789012:role/service-role/AWS_Events_Invoke_Start_Automation_Execution_1213609520"}'
   ```

------
#### [ Windows ]

   ```
   aws events put-targets ^
   --rule DailyAutomationRule ^
   --targets '{"Arn": "arn:aws:ssm:region:*:automation-definition/AWS-StartEC2Instance","Input":"{\"InstanceId\":[\"i-02573cafcfEXAMPLE\"],\"AutomationAssumeRole\":[\"arn:aws:iam::123456789012:role/AutomationServiceRole\"]}","Id": "Target1","RoleArn": "arn:aws:iam::123456789012:role/service-role/AWS_Events_Invoke_Start_Automation_Execution_1213609520"}'
   ```

------
#### [ PowerShell ]

   ```
   $Target = New-Object Amazon.CloudWatchEvents.Model.Target
   $Target.Id = "Target1"
   $Target.Arn = "arn:aws:ssm:region:*:automation-definition/AWS-StartEC2Instance"
   $Target.RoleArn = "arn:aws:iam::123456789012:role/service-role/AWS_Events_Invoke_Start_Automation_Execution_1213609520"
   $Target.Input = '{"InstanceId":["i-02573cafcfEXAMPLE"],"AutomationAssumeRole":["arn:aws:iam::123456789012:role/AutomationServiceRole"]}'
   
   Write-CWETarget `
   -Rule "DailyAutomationRule" `
   -Target $Target
   ```

------

   The system returns information like the following.

------
#### [ Linux & macOS ]

   ```
   {
   "FailedEntries": [],
   "FailedEntryCount": 0
   }
   ```

------
#### [ Windows ]

   ```
   {
   "FailedEntries": [],
   "FailedEntryCount": 0
   }
   ```

------
#### [ PowerShell ]

   There is no output if the command succeeds for PowerShell.

------

# Run an automation step by step
<a name="automation-working-executing-manually"></a>

The following procedures describe how to use the AWS Systems Manager console and AWS Command Line Interface (AWS CLI) to run an automation using the manual execution mode. By using the manual execution mode, the automation starts in a *Waiting* status and pauses in the *Waiting* status between each step. This allows you to control when the automation proceeds, which is useful if you need to review the result of a step before continuing.

The automation runs in the context of the current user. This means that you don't need to configure additional IAM permissions as long as you have permission to use the runbook, and any actions called by the runbook. If you have administrator permissions in IAM, then you already have permission to run this automation.

## Running an automation step by step (console)
<a name="automation-working-executing-manually-console"></a>

The following procedure shows how to use the Systems Manager console to manually run an automation step by step.

**To run an automation step by step**

1. Open the AWS Systems Manager console at [https://console.aws.amazon.com/systems-manager/](https://console.aws.amazon.com/systems-manager/).

1. In the navigation pane, choose **Automation**, and then choose **Execute automation**.

1. In the **Automation document** list, choose a runbook. Choose one or more options in the **Document categories** pane to filter SSM documents according to their purpose. To view a runbook that you own, choose the **Owned by me** tab. To view a runbook that is shared with your account, choose the **Shared with me** tab. To view all runbooks, choose the **All documents** tab.
**Note**  
You can view information about a runbook by choosing the runbook name.

1. In the **Document details** section, verify that **Document version** is set to the version that you want to run. The system includes the following version options: 
   + **Default version at runtime** – Choose this option if the Automation runbook is updated periodically and a new default version is assigned.
   + **Latest version at runtime** – Choose this option if the Automation runbook is updated periodically, and you want to run the version that was most recently updated.
   + **1 (Default)** – Choose this option to run the first version of the document, which is the default.

1. Choose **Next**.

1. In the **Execution Mode** section, choose **Manual execution**.

1. In the **Input parameters** section, specify the required inputs. Optionally, you can choose an IAM service role from the **AutomationAssumeRole** list.

1. Choose **Execute**. 

1. Choose **Execute this step** when you're ready to start the first step of the automation. The automation proceeds with step one and pauses before running any subsequent steps specified in the runbook you chose in step 3 of this procedure. If the runbook has multiple steps, you must select **Execute this step** for each step for the automation to proceed. Each time you choose **Execute this step** the action runs.
**Note**  
The console displays the status of the automation. If the automation fails to run a step, see [Troubleshooting Systems Manager Automation](automation-troubleshooting.md).

1. After you complete all steps specified in the runbook, choose **Complete and view results** to finish the automation and view the results.

After an automation execution completes, you can rerun the execution with the same or modified parameters. For more information, see [Rerunning automation executions](automation-rerun-executions.md).

## Running an automation step by step (command line)
<a name="automation-working-executing-manually-commandline"></a>

The following procedure describes how to use the AWS CLI (on Linux, macOS, or Windows) or AWS Tools for PowerShell to manually run an automation step by step.

**To run an automation step by step**

1. Install and configure the AWS CLI or the AWS Tools for PowerShell, if you haven't already.

   For information, see [Installing or updating the latest version of the AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html) and [Installing the AWS Tools for PowerShell](https://docs.aws.amazon.com/powershell/latest/userguide/pstools-getting-set-up.html).

1. Run the following command to start a manual automation. Replace each *example resource placeholder* with your own information.

------
#### [ Linux & macOS ]

   ```
   aws ssm start-automation-execution \
       --document-name runbook name \
       --mode Interactive \
       --parameters runbook parameters
   ```

------
#### [ Windows ]

   ```
   aws ssm start-automation-execution ^
       --document-name runbook name ^
       --mode Interactive ^
       --parameters runbook parameters
   ```

------
#### [ PowerShell ]

   ```
   Start-SSMAutomationExecution `
       -DocumentName runbook name `
       -Mode Interactive `
       -Parameter runbook parameters
   ```

------

   Here is an example using the runbook `AWS-RestartEC2Instance` to restart the specified EC2 instance.

------
#### [ Linux & macOS ]

   ```
   aws ssm start-automation-execution \
       --document-name "AWS-RestartEC2Instance" \
       --mode Interactive \
       --parameters "InstanceId=i-02573cafcfEXAMPLE"
   ```

------
#### [ Windows ]

   ```
   aws ssm start-automation-execution ^
       --document-name "AWS-RestartEC2Instance" ^
       --mode Interactive ^
       --parameters "InstanceId=i-02573cafcfEXAMPLE"
   ```

------
#### [ PowerShell ]

   ```
   Start-SSMAutomationExecution `
       -DocumentName AWS-RestartEC2Instance `
       -Mode Interactive 
       -Parameter @{"InstanceId"="i-02573cafcfEXAMPLE"}
   ```

------

   The system returns information like the following.

------
#### [ Linux & macOS ]

   ```
   {
       "AutomationExecutionId": "ba9cd881-1b36-4d31-a698-0123456789ab"
   }
   ```

------
#### [ Windows ]

   ```
   {
       "AutomationExecutionId": "ba9cd881-1b36-4d31-a698-0123456789ab"
   }
   ```

------
#### [ PowerShell ]

   ```
   ba9cd881-1b36-4d31-a698-0123456789ab
   ```

------

1. Run the following command when you're ready to start the first step of the automation. Replace each *example resource placeholder* with your own information. The automation proceeds with step one and pauses before running any subsequent steps specified in the runbook you chose in step 1 of this procedure. If the runbook has multiple steps, you must run the following command for each step for the automation to proceed.

------
#### [ Linux & macOS ]

   ```
   aws ssm send-automation-signal \
       --automation-execution-id ba9cd881-1b36-4d31-a698-0123456789ab \
       --signal-type StartStep \
       --payload StepName="stopInstances"
   ```

------
#### [ Windows ]

   ```
   aws ssm send-automation-signal ^
       --automation-execution-id ba9cd881-1b36-4d31-a698-0123456789ab ^
       --signal-type StartStep ^
       --payload StepName="stopInstances"
   ```

------
#### [ PowerShell ]

   ```
   Send-SSMAutomationSignal `
       -AutomationExecutionId ba9cd881-1b36-4d31-a698-0123456789ab `
       -SignalType StartStep 
       -Payload @{"StepName"="stopInstances"}
   ```

------

   There is no output if the command succeeds.

1. Run the following command to retrieve the status of each step execution in the automation.

------
#### [ Linux & macOS ]

   ```
   aws ssm describe-automation-step-executions \
       --automation-execution-id ba9cd881-1b36-4d31-a698-0123456789ab
   ```

------
#### [ Windows ]

   ```
   aws ssm describe-automation-step-executions ^
       --automation-execution-id ba9cd881-1b36-4d31-a698-0123456789ab
   ```

------
#### [ PowerShell ]

   ```
   Get-SSMAutomationStepExecution `
       -AutomationExecutionId ba9cd881-1b36-4d31-a698-0123456789ab
   ```

------

   The system returns information like the following.

------
#### [ Linux & macOS ]

   ```
   {
       "StepExecutions": [
           {
               "StepName": "stopInstances",
               "Action": "aws:changeInstanceState",
               "ExecutionStartTime": 1557167178.42,
               "ExecutionEndTime": 1557167220.617,
               "StepStatus": "Success",
               "Inputs": {
                   "DesiredState": "\"stopped\"",
                   "InstanceIds": "[\"i-02573cafcfEXAMPLE\"]"
               },
               "Outputs": {
                   "InstanceStates": [
                       "stopped"
                   ]
               },
               "StepExecutionId": "654243ba-71e3-4771-b04f-0123456789ab",
               "OverriddenParameters": {},
               "ValidNextSteps": [
                   "startInstances"
               ]
           },
           {
               "StepName": "startInstances",
               "Action": "aws:changeInstanceState",
               "ExecutionStartTime": 1557167273.754,
               "ExecutionEndTime": 1557167480.73,
               "StepStatus": "Success",
               "Inputs": {
                   "DesiredState": "\"running\"",
                   "InstanceIds": "[\"i-02573cafcfEXAMPLE\"]"
               },
               "Outputs": {
                   "InstanceStates": [
                       "running"
                   ]
               },
               "StepExecutionId": "8a4a1e0d-dc3e-4039-a599-0123456789ab",
               "OverriddenParameters": {}
           }
       ]
   }
   ```

------
#### [ Windows ]

   ```
   {
       "StepExecutions": [
           {
               "StepName": "stopInstances",
               "Action": "aws:changeInstanceState",
               "ExecutionStartTime": 1557167178.42,
               "ExecutionEndTime": 1557167220.617,
               "StepStatus": "Success",
               "Inputs": {
                   "DesiredState": "\"stopped\"",
                   "InstanceIds": "[\"i-02573cafcfEXAMPLE\"]"
               },
               "Outputs": {
                   "InstanceStates": [
                       "stopped"
                   ]
               },
               "StepExecutionId": "654243ba-71e3-4771-b04f-0123456789ab",
               "OverriddenParameters": {},
               "ValidNextSteps": [
                   "startInstances"
               ]
           },
           {
               "StepName": "startInstances",
               "Action": "aws:changeInstanceState",
               "ExecutionStartTime": 1557167273.754,
               "ExecutionEndTime": 1557167480.73,
               "StepStatus": "Success",
               "Inputs": {
                   "DesiredState": "\"running\"",
                   "InstanceIds": "[\"i-02573cafcfEXAMPLE\"]"
               },
               "Outputs": {
                   "InstanceStates": [
                       "running"
                   ]
               },
               "StepExecutionId": "8a4a1e0d-dc3e-4039-a599-0123456789ab",
               "OverriddenParameters": {}
           }
       ]
   }
   ```

------
#### [ PowerShell ]

   ```
   Action: aws:changeInstanceState
   ExecutionEndTime     : 5/6/2019 19:45:46
   ExecutionStartTime   : 5/6/2019 19:45:03
   FailureDetails       : 
   FailureMessage       : 
   Inputs               : {[DesiredState, "stopped"], [InstanceIds, ["i-02573cafcfEXAMPLE"]]}
   IsCritical           : False
   IsEnd                : False
   MaxAttempts          : 0
   NextStep             : 
   OnFailure            : 
   Outputs              : {[InstanceStates, Amazon.Runtime.Internal.Util.AlwaysSendList`1[System.String]]}
   OverriddenParameters : {}
   Response             : 
   ResponseCode         : 
   StepExecutionId      : 8fcc9641-24b7-40b3-a9be-0123456789ab
   StepName             : stopInstances
   StepStatus           : Success
   TimeoutSeconds       : 0
   ValidNextSteps       : {startInstances}
   ```

------

1. Run the following command to complete the automation after all steps specified within the chosen runbook have finished. Replace each *example resource placeholder* with your own information.

------
#### [ Linux & macOS ]

   ```
   aws ssm stop-automation-execution \
       --automation-execution-id ba9cd881-1b36-4d31-a698-0123456789ab \
       --type Complete
   ```

------
#### [ Windows ]

   ```
   aws ssm stop-automation-execution ^
       --automation-execution-id ba9cd881-1b36-4d31-a698-0123456789ab ^
       --type Complete
   ```

------
#### [ PowerShell ]

   ```
   Stop-SSMAutomationExecution `
       -AutomationExecutionId ba9cd881-1b36-4d31-a698-0123456789ab `
       -Type Complete
   ```

------

   There is no output if the command succeeds.

# Scheduling automations with State Manager associations
<a name="scheduling-automations-state-manager-associations"></a>

You can start an automation by creating a State Manager association with a runbook. State Manager is a tool in AWS Systems Manager. By creating a State Manager association with a runbook, you can target different types of AWS resources. For example, you can create associations that enforce a desired state on an AWS resource, including the following:
+ Attach a Systems Manager role to Amazon Elastic Compute Cloud (Amazon EC2) instances to make them *managed instances*.
+ Enforce desired ingress and egress rules for a security group.
+ Create or delete Amazon DynamoDB backups.
+ Create or delete Amazon Elastic Block Store (Amazon EBS) snapshots.
+ Turn off read and write permissions on Amazon Simple Storage Service (Amazon S3) buckets.
+ Start, restart, or stop managed instances and Amazon Relational Database Service (Amazon RDS) instances.
+ Apply patches to Linux, macOS, and Window AMIs.

Use the following procedures to create a State Manager association that runs an automation using the AWS Systems Manager console and AWS Command Line Interface (AWS CLI). For general information about associations and information about creating an association that uses an SSM `Command` document or `Policy` document, see [Creating associations](state-manager-associations-creating.md).

**Before you begin**  
Be aware of the following important details before you run an automation by using State Manager:
+ Before you can create an association that uses a runbook, verify that you configured permissions for Automation, a tool in AWS Systems Manager. For more information, see [Setting up Automation](automation-setup.md).
+ State Manager associations that use runbooks contribute to the maximum number of concurrently running automations in your AWS account. You can have a maximum of 100 concurrent automations running. For information, see [Systems Manager service quotas](https://docs.aws.amazon.com/general/latest/gr/ssm.html#limits_ssm) in the *Amazon Web Services General Reference*.
+ When running an automation, State Manager does not log the API operations initiated by the automation in AWS CloudTrail.
+ Systems Manager automatically creates a service-linked role so that State Manager has permission to call Systems Manager Automation API operations. If you want, you can create the service-linked role yourself by running the following command from the AWS CLI or AWS Tools for PowerShell.

------
#### [ Linux & macOS ]

  ```
  aws iam create-service-linked-role \
  --aws-service-name ssm.amazonaws.com
  ```

------
#### [ Windows ]

  ```
  aws iam create-service-linked-role ^
  --aws-service-name ssm.amazonaws.com
  ```

------
#### [ PowerShell ]

  ```
  New-IAMServiceLinkedRole `
  -AWSServiceName ssm.amazonaws.com
  ```

------

  For more information about service-linked roles, see [Using service-linked roles for Systems Manager](using-service-linked-roles.md).

## Creating an association that runs an automation (console)
<a name="create-automation-association-console"></a>

The following procedure describes how to use the Systems Manager console to create a State Manager association that runs an automation.

**To create a State Manager association that runs an automation**

1. Open the AWS Systems Manager console at [https://console.aws.amazon.com/systems-manager/](https://console.aws.amazon.com/systems-manager/).

1. In the navigation pane, choose **State Manager**, and then choose **Create association**.

1. In the **Name** field, specify a name. This is optional, but recommended.

1. In the **Document** list, choose a runbook. Use the Search bar to filter on **Document type : Equal : Automation** runbooks. To view more runbooks, use the numbers to the right of the Search bar. 
**Note**  
You can view information about a runbook by choosing the runbook name.

1. Choose **Simple execution** to run the automation on one or more targets by specifying the resource ID for those targets. Choose **Rate control** to run the automation across a fleet of AWS resources by specifying a targeting option such as tags or AWS Resource Groups. You can also control the operation of the automation across your resources by specifying concurrency and error thresholds.

   If you chose **Rate control**, the **Targets** section is displayed.

1. In the **Targets** section, choose a method for targeting resources.

   1. (Required) In the **Parameter** list, choose a parameter. The items in the **Parameter** list are determined by the parameters in the runbook that you selected at the start of this procedure. By choosing a parameter, you define the type of resource on which the automation runs. 

   1. (Required) In the **Targets** list, choose a method for targeting the resources.
      + **Resource Group**: Choose the name of the group from the **Resource Group** list. For more information about targeting AWS Resource Groups in runbooks, see [Targeting AWS Resource Groups](running-automations-map-targets.md#target-resource-groups).
      + **Tags**: Enter the tag key and (optionally) the tag value in the fields provided. Choose **Add**. For more information about targeting tags in runbooks, see [Targeting a tag](running-automations-map-targets.md#target-tags).
      + **Parameter Values**: Enter values in the **Input parameters** section. If you specify multiple values, Systems Manager runs a child automation on each value specified.

        For example, say that your runbook includes an **InstanceID** parameter. If you target the values of the **InstanceID** parameter when you run the automation, then Systems Manager runs a child automation for each instance ID value specified. The parent automation is complete when the automation finishes running each specified instance, or if the automation fails. You can target a maximum of 50 parameter values. For more information about targeting parameter values in runbooks, see [Targeting parameter values](running-automations-map-targets.md#target-parameter-values).

1. In the **Input parameters** section, specify the required input parameters.

   If you chose to target resources by using tags or a resource group, then you might not need to choose some of the options in the **Input parameters** section. For example, if you chose the `AWS-RestartEC2Instance` runbook, and you chose to target instances by using tags, then you don't need to specify or choose instance IDs in the **Input parameters** section. The automation locates the instances to restart by using the tags you specified. 
**Important**  
You must specify a role ARN in the **AutomationAssumeRole** field. State Manager uses the assume role to call AWS services specified in the runbook and run Automation associations on your behalf.

1. In the **Specify schedule** section, choose **On Schedule** if you want to run the association at regular intervals. If you choose this option, then use the options provided to create the schedule using Cron or Rate expressions. For more information about Cron and Rate expressions for State Manager, see [Cron and rate expressions for associations](reference-cron-and-rate-expressions.md#reference-cron-and-rate-expressions-association). 
**Note**  
Rate expressions are the preferred scheduling mechanism for State Manager associations that use runbooks. Rate expressions allow more flexibility for running associations in the event that you reach the maximum number of concurrently running automations. With a rate schedule, Systems Manager can retry the automation shortly after receiving notification that concurrent automations have reached their maximum and have been throttled.

   Choose **No schedule** if you want to run the association one time. 

1. (Optional) In the **Rate Control** section, choose **Concurrency** and **Error threshold** options to control the automation deployment across your AWS resources.

   1. In the **Concurrency** section, choose an option: 
      + Choose **targets** to enter an absolute number of targets that can run the automation simultaneously.
      + Choose **percentage** to enter a percentage of the target set that can run the automation simultaneously.

   1. In the **Error threshold** section, choose an option:
      + Choose **errors** to enter an absolute number of errors allowed before Automation stops sending the automation to other resources.
      + Choose **percentage** to enter a percentage of errors allowed before Automation stops sending the automation to other resources.

   For more information about using targets and rate controls with Automation, see [Run automated operations at scale](running-automations-scale.md).

1. Choose **Create Association**. 
**Important**  
When you create an association, the association immediately runs against the specified targets. The association then runs based on the cron or rate expression you chose. If you chose **No schedule**, the association doesn't run again.

## Creating an association that runs an automation (command line)
<a name="create-automation-association-cli"></a>

The following procedure describes how to use the AWS CLI (on Linux or Windows Server) or AWS Tools for PowerShell to create a State Manager association that runs an automation.

**Before you begin**  
Before you complete the following procedure, make sure you have created an IAM service role that contains the permissions necessary to run the runbook, and configured a trust relationship for Automation, a tool in AWS Systems Manager. For more information, see [Task 1: Create a service role for Automation](automation-setup-iam.md#create-service-role).

**To create an association that runs an automation**

1. Install and configure the AWS CLI or the AWS Tools for PowerShell, if you haven't already.

   For information, see [Installing or updating the latest version of the AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html) and [Installing the AWS Tools for PowerShell](https://docs.aws.amazon.com/powershell/latest/userguide/pstools-getting-set-up.html).

1. Run the following command to view a list of documents.

------
#### [ Linux & macOS ]

   ```
   aws ssm list-documents
   ```

------
#### [ Windows ]

   ```
   aws ssm list-documents
   ```

------
#### [ PowerShell ]

   ```
   Get-SSMDocumentList
   ```

------

   Note the name of the runbook that you want to use for the association.

1. Run the following command to view details about the runbook. In the following command, replace *runbook name* with your own information.

------
#### [ Linux & macOS ]

   ```
   aws ssm describe-document \
   --name runbook name
   ```

   Note a parameter name (for example, `InstanceId`) that you want to use for the `--automation-target-parameter-name` option. This parameter determines the type of resource on which the automation runs.

------
#### [ Windows ]

   ```
   aws ssm describe-document ^
   --name runbook name
   ```

   Note a parameter name (for example, `InstanceId`) that you want to use for the `--automation-target-parameter-name` option. This parameter determines the type of resource on which the automation runs.

------
#### [ PowerShell ]

   ```
   Get-SSMDocumentDescription `
   -Name runbook name
   ```

   Note a parameter name (for example, `InstanceId`) that you want to use for the `AutomationTargetParameterName` option. This parameter determines the type of resource on which the automation runs.

------

1. Create a command that runs an automation using a State Manager association. Replace each *example resource placeholder* with your own information.

   *Targeting using tags*

------
#### [ Linux & macOS ]

   ```
   aws ssm create-association \
   --association-name association name \
   --targets Key=tag:key name,Values=value \
   --name runbook name \
   --parameters AutomationAssumeRole=arn:aws:iam::123456789012:role/RunbookAssumeRole \
   --automation-target-parameter-name target parameter \
   --schedule "cron or rate expression"
   ```

**Note**  
If you create an association by using the AWS CLI, use the `--targets` parameter to target instances for the association. Don't use the `--instance-id` parameter. The `--instance-id` parameter is a legacy parameter. 

------
#### [ Windows ]

   ```
   aws ssm create-association ^
   --association-name association name ^
   --targets Key=tag:key name,Values=value ^
   --name runbook name ^
   --parameters AutomationAssumeRole=arn:aws:iam::123456789012:role/RunbookAssumeRole ^
   --automation-target-parameter-name target parameter ^
   --schedule "cron or rate expression"
   ```

**Note**  
If you create an association by using the AWS CLI, use the `--targets` parameter to target instances for the association. Don't use the `--instance-id` parameter. The `--instance-id` parameter is a legacy parameter. 

------
#### [ PowerShell ]

   ```
   $Targets = New-Object Amazon.SimpleSystemsManagement.Model.Target
   $Targets.Key = "tag:key name"
   $Targets.Values = "value"
   
   New-SSMAssociation `
   -AssociationName "association name" `
   -Target $Targets `
   -Name "runbook name" `
   -Parameters @{
   "AutomationAssumeRole"="arn:aws:iam::123456789012:role/RunbookAssumeRole" } `
   -AutomationTargetParameterName "target parameter" `
   -ScheduleExpression "cron or rate expression"
   ```

**Note**  
If you create an association by using the AWS Tools for PowerShell, use the `Target` parameter to target instances for the association. Don't use the `InstanceId` parameter. The `InstanceId` parameter is a legacy parameter. 

------

   *Targeting using parameter values*

------
#### [ Linux & macOS ]

   ```
   aws ssm create-association \
   --association-name association name \
   --targets Key=ParameterValues,Values=value,value 2,value 3 \
   --name runbook name \
   --parameters AutomationAssumeRole=arn:aws:iam::123456789012:role/RunbookAssumeRole \
   --automation-target-parameter-name target parameter \
   --schedule "cron or rate expression"
   ```

------
#### [ Windows ]

   ```
   aws ssm create-association ^
   --association-name association name ^
   --targets Key=ParameterValues,Values=value,value 2,value 3 ^
   --name runbook name ^
   --parameters AutomationAssumeRole=arn:aws:iam::123456789012:role/RunbookAssumeRole ^
   --automation-target-parameter-name target parameter ^
   --schedule "cron or rate expression"
   ```

------
#### [ PowerShell ]

   ```
   $Targets = New-Object Amazon.SimpleSystemsManagement.Model.Target
   $Targets.Key = "ParameterValues"
   $Targets.Values = "value","value 2","value 3"
   
   New-SSMAssociation `
   -AssociationName "association name" `
   -Target $Targets `
   -Name "runbook name" `
   -Parameters @{
   "AutomationAssumeRole"="arn:aws:iam::123456789012:role/RunbookAssumeRole"} `
   -AutomationTargetParameterName "target parameter" `
   -ScheduleExpression "cron or rate expression"
   ```

------

   *Targeting using AWS Resource Groups*

------
#### [ Linux & macOS ]

   ```
   aws ssm create-association \
   --association-name association name \
   --targets Key=ResourceGroup,Values=resource group name \
   --name runbook name \
   --parameters AutomationAssumeRole=arn:aws:iam::123456789012:role/RunbookAssumeRole \
   --automation-target-parameter-name target parameter \
   --schedule "cron or rate expression"
   ```

------
#### [ Windows ]

   ```
   aws ssm create-association ^
   --association-name association name ^
   --targets Key=ResourceGroup,Values=resource group name ^
   --name runbook name ^
   --parameters AutomationAssumeRole=arn:aws:iam::123456789012:role/RunbookAssumeRole ^
   --automation-target-parameter-name target parameter ^
   --schedule "cron or rate expression"
   ```

------
#### [ PowerShell ]

   ```
   $Targets = New-Object Amazon.SimpleSystemsManagement.Model.Target
   $Targets.Key = "ResourceGroup"
   $Targets.Values = "resource group name"
   
   New-SSMAssociation `
   -AssociationName "association name" `
   -Target $Targets `
   -Name "runbook name" `
   -Parameters @{
   "AutomationAssumeRole"="arn:aws:iam::123456789012:role/RunbookAssumeRole"} `
   -AutomationTargetParameterName "target parameter" `
   -ScheduleExpression "cron or rate expression"
   ```

------

   *Targeting multiple accounts and Regions*

------
#### [ Linux & macOS ]

   ```
   aws ssm create-association \
   --association-name association name \
   --targets Key=ResourceGroup,Values=resource group name \
   --name runbook name \
   --parameters AutomationAssumeRole=arn:aws:iam::123456789012:role/RunbookAssumeRole \
   --automation-target-parameter-name target parameter \
   --schedule "cron or rate expression" \ 
   --target-locations Accounts=111122223333,444455556666,444455556666,Regions=region,region
   ```

------
#### [ Windows ]

   ```
   aws ssm create-association ^
   --association-name association name ^
   --targets Key=ResourceGroup,Values=resource group name ^
   --name runbook name ^
   --parameters AutomationAssumeRole=arn:aws:iam::123456789012:role/RunbookAssumeRole ^
   --automation-target-parameter-name target parameter ^
   --schedule "cron or rate expression" ^ 
   --target-locations Accounts=111122223333,444455556666,444455556666,Regions=region,region
   ```

------
#### [ PowerShell ]

   ```
   $Targets = New-Object Amazon.SimpleSystemsManagement.Model.Target
   $Targets.Key = "ResourceGroup"
   $Targets.Values = "resource group name"
   
   New-SSMAssociation `
   -AssociationName "association name" `
   -Target $Targets `
   -Name "runbook name" `
   -Parameters @{
   "AutomationAssumeRole"="arn:aws:iam::123456789012:role/RunbookAssumeRole"} `
   -AutomationTargetParameterName "target parameter" `
   -ScheduleExpression "cron or rate expression" `
   -TargetLocations @{
       "Accounts"=["111122223333,444455556666,444455556666"],
       "Regions"=["region,region"]
   ```

------

   The command returns details for the new association similar to the following.

------
#### [ Linux & macOS ]

   ```
   {
   "AssociationDescription": {
       "ScheduleExpression": "cron(0 7 ? * MON *)",
       "Name": "AWS-StartEC2Instance",
       "Parameters": {
           "AutomationAssumeRole": [
               "arn:aws:iam::123456789012:role/RunbookAssumeRole"
           ]
       },
       "Overview": {
           "Status": "Pending",
           "DetailedStatus": "Creating"
       },
       "AssociationId": "1450b4b7-bea2-4e4b-b340-01234EXAMPLE",
       "DocumentVersion": "$DEFAULT",
       "AutomationTargetParameterName": "InstanceId",
       "LastUpdateAssociationDate": 1564686638.498,
       "Date": 1564686638.498,
       "AssociationVersion": "1",
       "AssociationName": "CLI",
       "Targets": [
           {
               "Values": [
                   "DEV"
               ],
               "Key": "tag:ENV"
           }
       ]
   }
   }
   ```

------
#### [ Windows ]

   ```
   {
   "AssociationDescription": {
       "ScheduleExpression": "cron(0 7 ? * MON *)",
       "Name": "AWS-StartEC2Instance",
       "Parameters": {
           "AutomationAssumeRole": [
               "arn:aws:iam::123456789012:role/RunbookAssumeRole"
           ]
       },
       "Overview": {
           "Status": "Pending",
           "DetailedStatus": "Creating"
       },
       "AssociationId": "1450b4b7-bea2-4e4b-b340-01234EXAMPLE",
       "DocumentVersion": "$DEFAULT",
       "AutomationTargetParameterName": "InstanceId",
       "LastUpdateAssociationDate": 1564686638.498,
       "Date": 1564686638.498,
       "AssociationVersion": "1",
       "AssociationName": "CLI",
       "Targets": [
           {
               "Values": [
                   "DEV"
               ],
               "Key": "tag:ENV"
           }
       ]
   }
   }
   ```

------
#### [ PowerShell ]

   ```
   Name                  : AWS-StartEC2Instance
   InstanceId            : 
   Date                  : 8/1/2019 7:31:38 PM
   Status.Name           : 
   Status.Date           : 
   Status.Message        : 
   Status.AdditionalInfo :
   ```

------

**Note**  
If you use tags to create an association on one or more target instances, and then you remove the tags from an instance, that instance no longer runs the association. The instance is disassociated from the State Manager document. 

## Troubleshooting automations run by State Manager associations
<a name="troubleshooting-automation-associations"></a>

Systems Manager Automation enforces a limit of 100 concurrent automations, and 1,000 queued automations per account, per Region. If a State Manager association that uses a runbook shows a status of **Failed** and a detailed status of **AutomationExecutionLimitExceeded**, then your automation might have reached the limit. As a result, Systems Manager throttles the automations. To resolve this issue, do the following:
+ Use a different rate or cron expression for your association. For example, if the association is scheduled to run every 30 minutes, then change the expression so that it runs every hour or two.
+ Delete existing automations that have a status of **Pending**. By deleting these automations, you clear the current queue.

# Schedule automations with maintenance windows
<a name="scheduling-automations-maintenance-windows"></a>

You can start an automation by configuring a runbook as a registered task for a maintenance window. By registering the runbook as a registered task, the maintenance window runs the automation during the scheduled maintenance period. 

For example, let's say you create a runbook named `CreateAMI` that creates an Amazon Machine Image (AMI) of instances registered as targets to the maintenance window. To specify the `CreateAMI` runbook (and corresponding automation) as a registered task of a maintenance window, you first create a maintenance window and register targets. Then you use the following procedure to specify the `CreateAMI` document as a registered task within the maintenance window. When the maintenance window starts during the scheduled period, the system runs the automation and creates an AMI of the registered targets.

For information about creating Automation runbooks, see [Creating your own runbooks](automation-documents.md). Automation is a tool in AWS Systems Manager.

Use the following procedures to configure an automation as a registered task for a maintenance window using the AWS Systems Manager console, AWS Command Line Interface (AWS CLI), or AWS Tools for Windows PowerShell.

## Registering an automation task to a maintenance window (console)
<a name="register-automation-task-maintenance-window-console"></a>

The following procedure describes how to use the Systems Manager console to configure an automation as a registered task for a maintenance window.

**Before you begin**  
Before you complete the following procedure, you must create a maintenance window and register at least one target. For more information, see the following procedures: 
+ [Create a maintenance window using the console](sysman-maintenance-create-mw.md).
+ [Assign targets to a maintenance window using the console](sysman-maintenance-assign-targets.md)

**To configure an automation as a registered task for a maintenance window**

1. Open the AWS Systems Manager console at [https://console.aws.amazon.com/systems-manager/](https://console.aws.amazon.com/systems-manager/).

1. In the left navigation pane, choose **Maintenance Windows**, and then choose the maintenance window you want to register an Automation task with.

1. Choose **Actions**. Then choose **Register Automation task** to run your choice of an automation on targets by using a runbook.

1. For **Name**, enter a name for the task.

1. For **Description**, enter a description.

1. For **Document**, choose the runbook that defines the tasks to run.

1. For **Document version**, choose the runbook version to use.

1. For **Task priority**, specify a priority for this task. `1` is the highest priority. Tasks in a maintenance window are scheduled in priority order; tasks that have the same priority are scheduled in parallel.

1. In the **Targets** section, if the runbook you chose is one that runs tasks on resources, identify the targets on which you want to run this automation by specifying tags or by selecting instances manually.
**Note**  
If you want to pass the resources through input parameters instead of targets, you don't need to specify a maintenance window target.  
In many cases, you don't need to explicitly specify a target for an automation task. For example, say that you're creating an Automation-type task to update an Amazon Machine Image (AMI) for Linux using the `AWS-UpdateLinuxAmi` runbook. When the task runs, the AMI is updated with the latest available Linux distribution packages and Amazon software. New instances created from the AMI already have these updates installed. Because the ID of the AMI to be updated is specified in the input parameters for the runbook, there is no need to specify a target again in the maintenance window task.

   For information about maintenance window tasks that don't require targets, see [Registering maintenance window tasks without targets](maintenance-windows-targetless-tasks.md).

1. (Optional) For **Rate control**:
**Note**  
If the task you're running doesn't specify targets, you don;t need to specify rate controls.
   + For **Concurrency**, specify either a number or a percentage of targets on which to run the automation at the same time.

     If you selected targets by choosing tag key-value pairs, and you aren't certain how many targets use the selected tags, then limit the number of automations that can run at the same time by specifying a percentage.

     When the maintenance window runs, a new automation is initiated per target. There is a limit of 100 concurrent automations per AWS account. If you specify a concurrency rate greater than 100, concurrent automations greater than 100 are automatically added to the automation queue. For information, see [Systems Manager service quotas](https://docs.aws.amazon.com/general/latest/gr/ssm.html#limits_ssm) in the *Amazon Web Services General Reference*. 
   + For **Error threshold**, specify when to stop running the automation on other targets after it fails on either a number or a percentage of targets. For example, if you specify three errors, then Systems Manager stops running automations when the fourth error is received. Targets still processing the automation might also send errors.

1. In the **Input Parameters** section, specify parameters for the runbook. For runbooks, the system auto-populates some of the values. You can keep or replace these values.
**Important**  
For runbooks, you can optionally specify an Automation Assume Role. If you don't specify a role for this parameter, then the automation assumes the maintenance window service role you choose in step 11. As such, you must ensure that the maintenance window service role you choose has the appropriate AWS Identity and Access Management (IAM) permissions to perform the actions defined within the runbook.   
For example, the service-linked role for Systems Manager doesn't have the IAM permission `ec2:CreateSnapshot`, which is required to use the runbook `AWS-CopySnapshot`. In this scenario, you must either use a custom maintenance window service role or specify an Automation assume role that has `ec2:CreateSnapshot` permissions. For information, see [Setting up Automation](automation-setup.md).

1. In the ** IAM service role** area, choose a role to provide permissions for Systems Manager to start the automation.

   To create a service role for maintenance window tasks, see [Setting up Maintenance Windows](setting-up-maintenance-windows.md).

1. Choose **Register Automation task**.

## Registering an Automation task to a maintenance window (command line)
<a name="register-automation-task-maintenance-window-cli"></a>

The following procedure describes how to use the AWS CLI (on Linux or Windows Server) or AWS Tools for PowerShell to configure an automation as a registered task for a maintenance window.

**Before you begin**  
Before you complete the following procedure, you must create a maintenance window and register at least one target. For more information, see the following procedures:
+ [Step 1: Create the maintenance window using the AWS CLI](mw-cli-tutorial-create-mw.md).
+ [Step 2: Register a target node with the maintenance window using the AWS CLI](mw-cli-tutorial-targets.md)

**To configure an automation as a registered task for a maintenance window**

1. Install and configure the AWS CLI or the AWS Tools for PowerShell, if you haven't already.

   For information, see [Installing or updating the latest version of the AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html) and [Installing the AWS Tools for PowerShell](https://docs.aws.amazon.com/powershell/latest/userguide/pstools-getting-set-up.html).

1. Create a command to configure an automation as a registered task for a maintenance window. Replace each *example resource placeholder* with your own information.

------
#### [ Linux & macOS ]

   ```
   aws ssm register-task-with-maintenance-window \
   --window-id window ID \
   --name task name \
   --task-arn runbook name \
   --targets Key=targets,Values=value \
   --service-role-arn IAM role arn \
   --task-type AUTOMATION \
   --task-invocation-parameters task parameters \
   --priority task priority \
   --max-concurrency 10% \
   --max-errors 5
   ```

**Note**  
If you configure an automation as a registered task by using the AWS CLI, use the `--Task-Invocation-Parameters` parameter to specify parameters to pass to a task when it runs. Don't use the `--Task-Parameters` parameter. The `--Task-Parameters` parameter is a legacy parameter.  
For maintenance window tasks without a target specified, you can't supply values for `--max-errors` and `--max-concurrency`. Instead, the system inserts a placeholder value of `1`, which might be reported in the response to commands such as [https://docs.aws.amazon.com/cli/latest/reference/ssm/describe-maintenance-window-tasks.html](https://docs.aws.amazon.com/cli/latest/reference/ssm/describe-maintenance-window-tasks.html) and [https://docs.aws.amazon.com/cli/latest/reference/ssm/get-maintenance-window-task.html](https://docs.aws.amazon.com/cli/latest/reference/ssm/get-maintenance-window-task.html). These values don't affect the running of your task and can be ignored.  
For information about maintenance window tasks that don't require targets, see [Registering maintenance window tasks without targets](maintenance-windows-targetless-tasks.md).

------
#### [ Windows ]

   ```
   aws ssm register-task-with-maintenance-window ^
   --window-id window ID ^
   --name task name ^
   --task-arn runbook name ^
   --targets Key=targets,Values=value ^
   --service-role-arn IAM role arn ^
   --task-type AUTOMATION ^
   --task-invocation-parameters task parameters ^
   --priority task priority ^
   --max-concurrency 10% ^
   --max-errors 5
   ```

**Note**  
If you configure an automation as a registered task by using the AWS CLI, use the `--task-invocation-parameters` parameter to specify parameters to pass to a task when it runs. Don't use the `--task-parameters` parameter. The `--task-parameters` parameter is a legacy parameter.  
For maintenance window tasks without a target specified, you can't supply values for `--max-errors` and `--max-concurrency`. Instead, the system inserts a placeholder value of `1`, which might be reported in the response to commands such as [https://docs.aws.amazon.com/cli/latest/reference/ssm/describe-maintenance-window-tasks.html](https://docs.aws.amazon.com/cli/latest/reference/ssm/describe-maintenance-window-tasks.html) and [https://docs.aws.amazon.com/cli/latest/reference/ssm/get-maintenance-window-task.html](https://docs.aws.amazon.com/cli/latest/reference/ssm/get-maintenance-window-task.html). These values don't affect the running of your task and can be ignored.  
For information about maintenance window tasks that don't require targets, see [Registering maintenance window tasks without targets](maintenance-windows-targetless-tasks.md).

------
#### [ PowerShell ]

   ```
   Register-SSMTaskWithMaintenanceWindow `
   -WindowId window ID `
   -Name "task name" `
   -TaskArn "runbook name" `
   -Target @{ Key="targets";Values="value" } `
   -ServiceRoleArn "IAM role arn" `
   -TaskType "AUTOMATION" `
   -Automation_Parameter @{ "task parameter"="task parameter value"} `
   -Priority task priority `
   -MaxConcurrency 10% `
   -MaxError 5
   ```

**Note**  
If you configure an automation as a registered task by using the AWS Tools for PowerShell, use the `-Automation_Parameter` parameter to specify parameters to pass to a task when the task runs. Don't use the `-TaskParameters` parameter. The `-TaskParameters` parameter is a legacy parameter.  
For maintenance window tasks without a target specified, you can't supply values for `-MaxError` and `-MaxConcurrency`. Instead, the system inserts a placeholder value of 1, which might be reported in the response to commands such as `Get-SSMMaintenanceWindowTaskList` and `Get-SSMMaintenanceWindowTask`. These values don't affect the running of your task and can be ignored.  
For information about maintenance window tasks that don't require targets, see [Registering maintenance window tasks without targets](maintenance-windows-targetless-tasks.md).

------

   The following example configures an automation as a registered task to a maintenance window with priority 1. It also demonstrates omitting the `--targets`, `--max-errors`, and `--max-concurrency` options for a targetless maintenance window task. The automation uses the `AWS-StartEC2Instance` runbook and the specified Automation assume role to start EC2 instances registered as targets to the maintenance window. The maintenance window runs the automation simultaneously on 5 instances maximum at any given time. Also, the registered task stops running on more instances for a particular interval if the error count exceeds 1.

------
#### [ Linux & macOS ]

   ```
   aws ssm register-task-with-maintenance-window \
   --window-id mw-0c50858d01EXAMPLE \
   --name StartEC2Instances \
   --task-arn AWS-StartEC2Instance \
   --service-role-arn arn:aws:iam::123456789012:role/MaintenanceWindowRole \
   --task-type AUTOMATION \
   --task-invocation-parameters "{\"Automation\":{\"Parameters\":{\"InstanceId\":[\"{{TARGET_ID}}\"],\"AutomationAssumeRole\":[\"arn:aws:iam::123456789012:role/AutomationAssumeRole\"]}}}" \
   --priority 1
   ```

------
#### [ Windows ]

   ```
   aws ssm register-task-with-maintenance-window ^
   --window-id mw-0c50858d01EXAMPLE ^
   --name StartEC2Instances ^
   --task-arn AWS-StartEC2Instance ^
   --service-role-arn arn:aws:iam::123456789012:role/MaintenanceWindowRole ^
   --task-type AUTOMATION ^
   --task-invocation-parameters "{\"Automation\":{\"Parameters\":{\"InstanceId\":[\"{{TARGET_ID}}\"],\"AutomationAssumeRole\":[\"arn:aws:iam::123456789012:role/AutomationAssumeRole\"]}}}" ^
   --priority 1
   ```

------
#### [ PowerShell ]

   ```
   Register-SSMTaskWithMaintenanceWindow `
   -WindowId mw-0c50858d01EXAMPLE `
   -Name "StartEC2" `
   -TaskArn "AWS-StartEC2Instance" `
   -ServiceRoleArn "arn:aws:iam::123456789012:role/MaintenanceWindowRole" `
   -TaskType "AUTOMATION" `
   -Automation_Parameter @{ "InstanceId"="{{TARGET_ID}}";"AutomationAssumeRole"="arn:aws:iam::123456789012:role/AutomationAssumeRole" } `
   -Priority 1
   ```

------

   The command returns details for the new registered task similar to the following.

------
#### [ Linux & macOS ]

   ```
   {
   "WindowTaskId": "4f7ca192-7e9a-40fe-9192-5cb15EXAMPLE"
   }
   ```

------
#### [ Windows ]

   ```
   {
   "WindowTaskId": "4f7ca192-7e9a-40fe-9192-5cb15EXAMPLE"
   }
   ```

------
#### [ PowerShell ]

   ```
   4f7ca192-7e9a-40fe-9192-5cb15EXAMPLE
   ```

------

1. To view the registered task, run the following command. Replace *maintenance windows ID* with your own information.

------
#### [ Linux & macOS ]

   ```
   aws ssm describe-maintenance-window-tasks \
   --window-id maintenance window ID
   ```

------
#### [ Windows ]

   ```
   aws ssm describe-maintenance-window-tasks ^
   --window-id maintenance window ID
   ```

------
#### [ PowerShell ]

   ```
   Get-SSMMaintenanceWindowTaskList `
   -WindowId maintenance window ID
   ```

------

   The system returns information like the following.

------
#### [ Linux & macOS ]

   ```
   {
   "Tasks": [
       {
           "ServiceRoleArn": "arn:aws:iam::123456789012:role/MaintenanceWindowRole",
           "MaxErrors": "1",
           "TaskArn": "AWS-StartEC2Instance",
           "MaxConcurrency": "1",
           "WindowTaskId": "4f7ca192-7e9a-40fe-9192-5cb15EXAMPLE",
           "TaskParameters": {},
           "Priority": 1,
           "WindowId": "mw-0c50858d01EXAMPLE",
           "Type": "AUTOMATION",
           "Targets": [
           ],
           "Name": "StartEC2"
       }
   ]
   }
   ```

------
#### [ Windows ]

   ```
   {
   "Tasks": [
       {
           "ServiceRoleArn": "arn:aws:iam::123456789012:role/MaintenanceWindowRole",
           "MaxErrors": "1",
           "TaskArn": "AWS-StartEC2Instance",
           "MaxConcurrency": "1",
           "WindowTaskId": "4f7ca192-7e9a-40fe-9192-5cb15EXAMPLE",
           "TaskParameters": {},
           "Priority": 1,
           "WindowId": "mw-0c50858d01EXAMPLE",
           "Type": "AUTOMATION",
           "Targets": [
           ],
           "Name": "StartEC2"
       }
   ]
   }
   ```

------
#### [ PowerShell ]

   ```
   Description    : 
   LoggingInfo    : 
   MaxConcurrency : 5
   MaxErrors      : 1
   Name           : StartEC2
   Priority       : 1
   ServiceRoleArn : arn:aws:iam::123456789012:role/MaintenanceWindowRole
   Targets        : {}
   TaskArn        : AWS-StartEC2Instance
   TaskParameters : {}
   Type           : AUTOMATION
   WindowId       : mw-0c50858d01EXAMPLE
   WindowTaskId   : 4f7ca192-7e9a-40fe-9192-5cb15EXAMPLE
   ```

------

# Systems Manager Automation actions reference
<a name="automation-actions"></a>

This reference describes the Automation actions that you can specify in an Automation runbook. Automation is a tool in AWS Systems Manager. These actions can't be used in other types of Systems Manager (SSM) documents. For information about plugins for other types of SSM documents, see [Command document plugin reference](documents-command-ssm-plugin-reference.md).

Systems Manager Automation runs steps defined in Automation runbooks. Each step is associated with a particular action. The action determines the inputs, behavior, and outputs of the step. Steps are defined in the `mainSteps` section of your runbook.

You don't need to specify the outputs of an action or step. The outputs are predetermined by the action associated with the step. When you specify step inputs in your runbooks, you can reference one or more outputs from an earlier step. For example, you can make the output of `aws:runInstances` available for a subsequent `aws:runCommand` action. You can also reference outputs from earlier steps in the `Output` section of the runbook. 

**Important**  
If you run an automation workflow that invokes other services by using an AWS Identity and Access Management (IAM) service role, be aware that the service role must be configured with permission to invoke those services. This requirement applies to all AWS Automation runbooks (`AWS-*` runbooks) such as the `AWS-ConfigureS3BucketLogging`, `AWS-CreateDynamoDBBackup`, and `AWS-RestartEC2Instance` runbooks, to name a few. This requirement also applies to any custom Automation runbooks you create that invoke other AWS services by using actions that call other services. For example, if you use the `aws:executeAwsApi`, `aws:createStack`, or `aws:copyImage` actions, configure the service role with permission to invoke those services. You can give permissions to other AWS services by adding an IAM inline policy to the role. For more information, see [(Optional) Add an Automation inline policy or customer managed policy to invoke other AWS services](automation-setup-iam.md#add-inline-policy).

**Topics**
+ [Properties shared by all actions](#automation-common)
+ [`aws:approve` – Pause an automation for manual approval](automation-action-approve.md)
+ [`aws:assertAwsResourceProperty` – Assert an AWS resource state or event state](automation-action-assertAwsResourceProperty.md)
+ [`aws:branch` – Run conditional automation steps](automation-action-branch.md)
+ [`aws:changeInstanceState` – Change or assert instance state](automation-action-changestate.md)
+ [`aws:copyImage` – Copy or encrypt an Amazon Machine Image](automation-action-copyimage.md)
+ [`aws:createImage` – Create an Amazon Machine Image](automation-action-create.md)
+ [`aws:createStack` – Create an CloudFormation stack](automation-action-createstack.md)
+ [`aws:createTags` – Create tags for AWS resources](automation-action-createtag.md)
+ [`aws:deleteImage` – Delete an Amazon Machine Image](automation-action-delete.md)
+ [`aws:deleteStack` – Delete an CloudFormation stack](automation-action-deletestack.md)
+ [`aws:executeAutomation` – Run another automation](automation-action-executeAutomation.md)
+ [`aws:executeAwsApi` – Call and run AWS API operations](automation-action-executeAwsApi.md)
+ [`aws:executeScript` – Run a script](automation-action-executeScript.md)
+ [`aws:executeStateMachine` – Run an AWS Step Functions state machine](automation-action-executeStateMachine.md)
+ [`aws:invokeWebhook` – Invoke an Automation webhook integration](invoke-webhook.md)
+ [`aws:invokeLambdaFunction` – Invoke an AWS Lambda function](automation-action-lamb.md)
+ [`aws:loop` – Iterate over steps in an automation](automation-action-loop.md)
+ [`aws:pause` – Pause an automation](automation-action-pause.md)
+ [`aws:runCommand` – Run a command on a managed instance](automation-action-runcommand.md)
+ [`aws:runInstances` – Launch an Amazon EC2 instance](automation-action-runinstance.md)
+ [`aws:sleep` – Delay an automation](automation-action-sleep.md)
+ [`aws:updateVariable` – Updates a value for a runbook variable](automation-action-update-variable.md)
+ [`aws:waitForAwsResourceProperty` – Wait on an AWS resource property](automation-action-waitForAwsResourceProperty.md)
+ [Automation system variables](automation-variables.md)

## Properties shared by all actions
<a name="automation-common"></a>

Common properties are parameters or options that are found in all actions. Some options define behavior for a step, such as how long to wait for a step to complete and what to do if the step fails. The following properties are common to all actions.

[description](#descriptProp)  
Information you provide to describe the purpose of a runbook or a step.  
Type: String  
Required: No

[name](#nameProp)  
An identifier that must be unique across all step names in the runbook.  
Type: String  
Allowed pattern: [a-zA-Z0-9\$1]\$1\$1  
Required: Yes

[action](#actProp)  
The name of the action the step is to run. [`aws:runCommand` – Run a command on a managed instance](automation-action-runcommand.md) is an example of an action you can specify here. This document provides detailed information about all available actions.  
Type: String  
Required: Yes

[maxAttempts](#maxProp)  
The number of times the step should be retried in case of failure. If the value is greater than 1, the step isn't considered to have failed until all retry attempts have failed. The default value is 1.  
Type: Integer  
Required: No

[timeoutSeconds](#timeProp)  
The timeout value for the step. If the timeout is reached and the value of `maxAttempts` is greater than 1, then the step isn't considered to have timed out until all retries have been attempted.  
Type: Integer  
Required: No

[onFailure](#failProp)  
Indicates whether the automation should stop, continue, or go to a different step on failure. The default value for this option is abort.  
Type: String  
Valid values: Abort \$1 Continue \$1 step:*step\$1name*  
Required: No

[onCancel](#canProp)  
Indicates which step the automation should go to in the event that a user cancels the automation. Automation runs the cancellation workflow for a maximum of two minutes.  
Type: String  
Valid values: Abort \$1 step:*step\$1name*  
Required: No  
The `onCancel` property doesn't support moving to the following actions:  
+ `aws:approve`
+ `aws:copyImage`
+ `aws:createImage`
+ `aws:createStack`
+ `aws:createTags`
+ `aws:loop`
+ `aws:pause`
+ `aws:runInstances`
+ `aws:sleep`

[isEnd](#endProp)  
This option stops an automation at the end of a specific step. The automation stops if the step failed or succeeded. The default value is false.  
Type: Boolean  
Valid values: true \$1 false  
Required: No

[nextStep](#nextProp)  
Specifies which step in an automation to process next after successfully completing a step.  
Type: String  
Required: No

[isCritical](#critProp)  
Designates a step as critical for the successful completion of the Automation. If a step with this designation fails, then Automation reports the final status of the Automation as Failed. This property is only evaluated if you explicitly define it in your step. If the `onFailure` property is set to `Continue` in a step, the value defaults to false. Otherwise, the default value for this option is true.  
Type: Boolean  
Valid values: true \$1 false  
Required: No

[inputs](#inProp)  
The properties specific to the action.  
Type: Map  
Required: Yes

### Example
<a name="automation-demo"></a>

```
---
description: "Custom Automation Example"
schemaVersion: '0.3'
assumeRole: "{{ AutomationAssumeRole }}"
parameters:
  AutomationAssumeRole:
    type: String
    description: "(Required) The ARN of the role that allows Automation to perform
      the actions on your behalf. If no role is specified, Systems Manager Automation
      uses your IAM permissions to run this runbook."
    default: ''
  InstanceId:
      type: String
      description: "(Required) The Instance Id whose root EBS volume you want to restore the latest Snapshot."
      default: ''
mainSteps:
- name: getInstanceDetails
  action: aws:executeAwsApi
  onFailure: Abort
  inputs:
    Service: ec2
    Api: DescribeInstances
    InstanceIds:
    - "{{ InstanceId }}"
  outputs:
    - Name: availabilityZone
      Selector: "$.Reservations[0].Instances[0].Placement.AvailabilityZone"
      Type: String
    - Name: rootDeviceName
      Selector: "$.Reservations[0].Instances[0].RootDeviceName"
      Type: String
  nextStep: getRootVolumeId
- name: getRootVolumeId
  action: aws:executeAwsApi
  maxAttempts: 3
  onFailure: Abort
  inputs:
    Service: ec2
    Api: DescribeVolumes
    Filters:
    -  Name: attachment.device
       Values: ["{{ getInstanceDetails.rootDeviceName }}"]
    -  Name: attachment.instance-id
       Values: ["{{ InstanceId }}"]
  outputs:
    - Name: rootVolumeId
      Selector: "$.Volumes[0].VolumeId"
      Type: String
  nextStep: getSnapshotsByStartTime
- name: getSnapshotsByStartTime
  action: aws:executeScript
  timeoutSeconds: 45
  onFailure: Abort
  inputs:
    Runtime: python3.8
    Handler: getSnapshotsByStartTime
    InputPayload:
      rootVolumeId : "{{ getRootVolumeId.rootVolumeId }}"
    Script: |-
      def getSnapshotsByStartTime(events,context):
        import boto3

        #Initialize client
        ec2 = boto3.client('ec2')
        rootVolumeId = events['rootVolumeId']
        snapshotsQuery = ec2.describe_snapshots(
          Filters=[
            {
              "Name": "volume-id",
              "Values": [rootVolumeId]
            }
          ]
        )
        if not snapshotsQuery['Snapshots']:
          noSnapshotFoundString = "NoSnapshotFound"
          return { 'noSnapshotFound' : noSnapshotFoundString }
        else:
          jsonSnapshots = snapshotsQuery['Snapshots']
          sortedSnapshots = sorted(jsonSnapshots, key=lambda k: k['StartTime'], reverse=True)
          latestSortedSnapshotId = sortedSnapshots[0]['SnapshotId']
          return { 'latestSnapshotId' : latestSortedSnapshotId }
  outputs:
  - Name: Payload
    Selector: $.Payload
    Type: StringMap
  - Name: latestSnapshotId
    Selector: $.Payload.latestSnapshotId
    Type: String
  - Name: noSnapshotFound
    Selector: $.Payload.noSnapshotFound
    Type: String 
  nextStep: branchFromResults
- name: branchFromResults
  action: aws:branch
  onFailure: Abort
  onCancel: step:startInstance
  inputs:
    Choices:
    - NextStep: createNewRootVolumeFromSnapshot
      Not:
        Variable: "{{ getSnapshotsByStartTime.noSnapshotFound }}"
        StringEquals: "NoSnapshotFound"
  isEnd: true
- name: createNewRootVolumeFromSnapshot
  action: aws:executeAwsApi
  onFailure: Abort
  inputs:
    Service: ec2
    Api: CreateVolume
    AvailabilityZone: "{{ getInstanceDetails.availabilityZone }}"
    SnapshotId: "{{ getSnapshotsByStartTime.latestSnapshotId }}"
  outputs:
    - Name: newRootVolumeId
      Selector: "$.VolumeId"
      Type: String
  nextStep: stopInstance
- name: stopInstance
  action: aws:executeAwsApi
  onFailure: Abort
  inputs:
    Service: ec2
    Api: StopInstances
    InstanceIds:
    - "{{ InstanceId }}"
  nextStep: verifyVolumeAvailability
- name: verifyVolumeAvailability
  action: aws:waitForAwsResourceProperty
  timeoutSeconds: 120
  inputs:
    Service: ec2
    Api: DescribeVolumes
    VolumeIds:
    - "{{ createNewRootVolumeFromSnapshot.newRootVolumeId }}"
    PropertySelector: "$.Volumes[0].State"
    DesiredValues:
    - "available"
  nextStep: verifyInstanceStopped
- name: verifyInstanceStopped
  action: aws:waitForAwsResourceProperty
  timeoutSeconds: 120
  inputs:
    Service: ec2
    Api: DescribeInstances
    InstanceIds:
    - "{{ InstanceId }}"
    PropertySelector: "$.Reservations[0].Instances[0].State.Name"
    DesiredValues:
    - "stopped"
  nextStep: detachRootVolume
- name: detachRootVolume
  action: aws:executeAwsApi
  onFailure: Abort
  isCritical: true
  inputs:
    Service: ec2
    Api: DetachVolume
    VolumeId: "{{ getRootVolumeId.rootVolumeId }}"
  nextStep: verifyRootVolumeDetached
- name: verifyRootVolumeDetached
  action: aws:waitForAwsResourceProperty
  timeoutSeconds: 30
  inputs:
    Service: ec2
    Api: DescribeVolumes
    VolumeIds:
    - "{{ getRootVolumeId.rootVolumeId }}"
    PropertySelector: "$.Volumes[0].State"
    DesiredValues:
    - "available"
  nextStep: attachNewRootVolume
- name: attachNewRootVolume
  action: aws:executeAwsApi
  onFailure: Abort
  inputs:
    Service: ec2
    Api: AttachVolume
    Device: "{{ getInstanceDetails.rootDeviceName }}"
    InstanceId: "{{ InstanceId }}"
    VolumeId: "{{ createNewRootVolumeFromSnapshot.newRootVolumeId }}"
  nextStep: verifyNewRootVolumeAttached
- name: verifyNewRootVolumeAttached
  action: aws:waitForAwsResourceProperty
  timeoutSeconds: 30
  inputs:
    Service: ec2
    Api: DescribeVolumes
    VolumeIds:
    - "{{ createNewRootVolumeFromSnapshot.newRootVolumeId }}"
    PropertySelector: "$.Volumes[0].Attachments[0].State"
    DesiredValues:
    - "attached"
  nextStep: startInstance
- name: startInstance
  action: aws:executeAwsApi
  onFailure: Abort
  inputs:
    Service: ec2
    Api: StartInstances
    InstanceIds:
    - "{{ InstanceId }}"
```

# `aws:approve` – Pause an automation for manual approval
<a name="automation-action-approve"></a>

Temporarily pauses an automation until designated principals either approve or reject the action. After the required number of approvals is reached, the automation resumes. You can insert the approval step any place in the `mainSteps` section of your runbook. 

**Note**  
This action doesn't support multi-account and Region automations. The default timeout for this action is 7 days (604800 seconds) and the maximum value is 30 days (2592000 seconds). You can limit or extend the timeout by specifying the `timeoutSeconds` parameter for an `aws:approve` step.

In the following example, the `aws:approve` action temporarily pauses the automation until one approver either accepts or rejects the automation. Upon approval, the automation runs a simple PowerShell command. 

------
#### [ YAML ]

```
---
description: RunInstancesDemo1
schemaVersion: '0.3'
assumeRole: "{{ assumeRole }}"
parameters:
  assumeRole:
    type: String
  message:
    type: String
mainSteps:
- name: approve
  action: aws:approve
  timeoutSeconds: 1000
  onFailure: Abort
  inputs:
    NotificationArn: arn:aws:sns:us-east-2:12345678901:AutomationApproval
    Message: "{{ message }}"
    MinRequiredApprovals: 1
    Approvers:
    - arn:aws:iam::12345678901:user/AWS-User-1
- name: run
  action: aws:runCommand
  inputs:
    InstanceIds:
    - i-1a2b3c4d5e6f7g
    DocumentName: AWS-RunPowerShellScript
    Parameters:
      commands:
      - date
```

------
#### [ JSON ]

```
{
   "description":"RunInstancesDemo1",
   "schemaVersion":"0.3",
   "assumeRole":"{{ assumeRole }}",
   "parameters":{
      "assumeRole":{
         "type":"String"
      },
      "message":{
         "type":"String"
      }
   },
   "mainSteps":[
      {
         "name":"approve",
         "action":"aws:approve",
         "timeoutSeconds":1000,
         "onFailure":"Abort",
         "inputs":{
            "NotificationArn":"arn:aws:sns:us-east-2:12345678901:AutomationApproval",
            "Message":"{{ message }}",
            "MinRequiredApprovals":1,
            "Approvers":[
               "arn:aws:iam::12345678901:user/AWS-User-1"
            ]
         }
      },
      {
         "name":"run",
         "action":"aws:runCommand",
         "inputs":{
            "InstanceIds":[
               "i-1a2b3c4d5e6f7g"
            ],
            "DocumentName":"AWS-RunPowerShellScript",
            "Parameters":{
               "commands":[
                  "date"
               ]
            }
         }
      }
   ]
}
```

------

You can approve or deny Automations that are waiting for approval in the console.

**To approve or deny waiting Automations**

1. Open the AWS Systems Manager console at [https://console.aws.amazon.com/systems-manager/](https://console.aws.amazon.com/systems-manager/).

1. In the navigation pane, choose **Automation**.

1. Choose the option next to an Automation with a status of **Waiting**.  
![\[Accessing the Approve/Deny Automation page\]](http://docs.aws.amazon.com/systems-manager/latest/userguide/images/automation-approve-action-aws.png)

1. Choose **Approve/Deny**.

1. Review the details of the Automation.

1. Choose either **Approve** or **Deny**, type an optional comment, and then choose **Submit**.

**Input example**

------
#### [ YAML ]

```
NotificationArn: arn:aws:sns:us-west-1:12345678901:Automation-ApprovalRequest
Message: Please approve this step of the Automation.
MinRequiredApprovals: 3
Approvers:
- IamUser1
- IamUser2
- arn:aws:iam::12345678901:user/IamUser3
- arn:aws:iam::12345678901:role/IamRole
```

------
#### [ JSON ]

```
{
   "NotificationArn":"arn:aws:sns:us-west-1:12345678901:Automation-ApprovalRequest",
   "Message":"Please approve this step of the Automation.",
   "MinRequiredApprovals":3,
   "Approvers":[
      "IamUser1",
      "IamUser2",
      "arn:aws:iam::12345678901:user/IamUser3",
      "arn:aws:iam::12345678901:role/IamRole"
   ]
}
```

------

NotificationArn  
The Amazon Resource Name (ARN of an Amazon Simple Notification Service (Amazon SNS) topic for Automation approvals. When you specify an `aws:approve` step in a runbook, Automation sends a message to this topic letting principals know that they must either approve or reject an Automation step. The title of the Amazon SNS topic must be prefixed with "Automation".  
Type: String  
Required: No

Message  
The information you want to include in the Amazon SNS topic when the approval request is sent. The maximum message length is 4096 characters.   
Type: String  
Required: No

MinRequiredApprovals  
The minimum number of approvals required to resume the automation. If you don't specify a value, the system defaults to one. The value for this parameter must be a positive number. The value for this parameter can't exceed the number of approvers defined by the `Approvers` parameter.   
Type: Integer  
Required: No

Approvers  
A list of AWS authenticated principals who are able to either approve or reject the action. The maximum number of approvers is 10. You can specify principals by using any of the following formats:  
+ A user name
+ A user ARN
+ An IAM role ARN
+ An IAM assume role ARN
Type: StringList  
Required: Yes

EnhancedApprovals  
This input is only used for Change Manager templates. A list of AWS authenticated principals who are able to either approve or reject the action, the type of IAM principal, and the minimum number of approvers. The following is an example:  

```
schemaVersion: "0.3"
emergencyChange: false
autoApprovable: false
mainSteps:
    - name: ApproveAction1
    action: aws:approve
    timeoutSeconds: 604800
    inputs:
        Message: Please approve this change request
        MinRequiredApprovals: 3
        EnhancedApprovals:
        Approvers:
            - approver: John Stiles
            type: IamUser
            minRequiredApprovals: 0
            - approver: Ana Carolina Silva
            type: IamUser
            minRequiredApprovals: 0
            - approver: GroupOfThree
            type: IamGroup
            minRequiredApprovals: 0
            - approver: RoleOfTen
            type: IamRole
            minRequiredApprovals: 0
```
Type: StringList  
Required: Yes

**Output**

ApprovalStatus  
The approval status of the step. The status can be one of the following: Approved, Rejected, or Waiting. Waiting means that Automation is waiting for input from approvers.  
Type: String

ApproverDecisions  
A JSON map that includes the approval decision of each approver.  
Type: MapList

# `aws:assertAwsResourceProperty` – Assert an AWS resource state or event state
<a name="automation-action-assertAwsResourceProperty"></a>

The `aws:assertAwsResourceProperty` action allows you to assert a specific resource state or event state for a specific Automation step.

**Note**  
The `aws:assertAwsResourceProperty` action supports automatic throttling retry. For more information, see [Configuring automatic retry for throttled operations](automation-throttling-retry.md).

For more examples of how to use this action, see [Additional runbook examples](automation-document-examples.md).

**Input**  
Inputs are defined by the API operation that you choose. 

------
#### [ YAML ]

```
action: aws:assertAwsResourceProperty
inputs:
  Service: The official namespace of the service
  Api: The API operation or method name
  API operation inputs or parameters: A value
  PropertySelector: Response object
  DesiredValues:
  - Desired property values
```

------
#### [ JSON ]

```
{
  "action": "aws:assertAwsResourceProperty",
  "inputs": {
    "Service":"The official namespace of the service",
    "Api":"The API operation or method name",
    "API operation inputs or parameters":"A value",
    "PropertySelector": "Response object",
    "DesiredValues": [
      "Desired property values"
    ]
  }
}
```

------

Service  
The AWS service namespace that contains the API operation that you want to run. For example, the namespace for Systems Manager is `ssm`. The namespace for Amazon EC2 is `ec2`. You can view a list of supported AWS service namespaces in the [Available Services](https://docs.aws.amazon.com/cli/latest/reference/#available-services) section of the *AWS CLI Command Reference*.  
Type: String  
Required: Yes

Api  
The name of the API operation that you want to run. You can view the API operations (also called methods) by choosing a service in the left navigation on the following [Services Reference](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/index.html) page. Choose a method in the **Client** section for the service that you want to invoke. For example, all API operations (methods) for Amazon Relational Database Service (Amazon RDS) are listed on the following page: [Amazon RDS methods](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/rds.html).  
Type: String  
Required: Yes

API operation inputs  
One or more API operation inputs. You can view the available inputs (also called parameters) by choosing a service in the left navigation on the following [Services Reference](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/index.html) page. Choose a method in the **Client** section for the service that you want to invoke. For example, all methods for Amazon RDS are listed on the following page: [Amazon RDS methods](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/rds.html). Choose the [describe\$1db\$1instances](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/rds.html#RDS.Client.describe_db_instances) method and scroll down to see the available parameters, such as **DBInstanceIdentifier**, **Name**, and **Values**. Use the following format to specify more than one input.  

```
inputs:
  Service: The official namespace of the service
  Api: The API operation name
  API input 1: A value
  API Input 2: A value
  API Input 3: A value
```

```
"inputs":{
      "Service":"The official namespace of the service",
      "Api":"The API operation name",
      "API input 1":"A value",
      "API Input 2":"A value",
      "API Input 3":"A value"
}
```
Type: Determined by chosen API operation  
Required: Yes

PropertySelector  
The JSONPath to a specific attribute in the response object. You can view the response objects by choosing a service in the left navigation on the following [Services Reference](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/index.html) page. Choose a method in the **Client** section for the service that you want to invoke. For example, all methods for Amazon RDS are listed on the following page: [Amazon RDS methods](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/rds.html). Choose the [describe\$1db\$1instances](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/rds.html#RDS.Client.describe_db_instances) method and scroll down to the **Response Structure** section. **DBInstances** is listed as a response object.  
Type: String  
Required: Yes

DesiredValues  
The expected status or state on which to continue the automation. If you specify a Boolean value, you must use a capital letter such as True or False.  
Type: StringList  
Required: Yes

# `aws:branch` – Run conditional automation steps
<a name="automation-action-branch"></a>

The `aws:branch` action allows you to create a dynamic automation that evaluates different choices in a single step and then jumps to a different step in the runbook based on the results of that evaluation. 

When you specify the `aws:branch` action for a step, you specify `Choices` that the automation must evaluate. The `Choices` can be based on either a value that you specified in the `Parameters` section of the runbook, or a dynamic value generated as the output from the previous step. The automation evaluates each choice by using a Boolean expression. If the first choice is true, then the automation jumps to the step designated for that choice. If the first choice is false, the automation evaluates the next choice. The automation continues evaluating each choice until it process a true choice. The automation then jumps to the designated step for the true choice.

If none of the choices are true, the automation checks to see if the step contains a `default` value. A default value defines a step that the automation should jump to if none of the choices are true. If no `default` value is specified for the step, then the automation processes the next step in the runbook.

The `aws:branch` action supports complex choice evaluations by using a combination of `And`, `Not`, and `Or` operators. For more information about how to use `aws:branch`, including example runbooks and examples that use different operators, see [Using conditional statements in runbooks](automation-branch-condition.md).

**Input**  
Specify one or more `Choices` in a step. The `Choices` can be based on either a value that you specified in the `Parameters` section of the runbook, or a dynamic value generated as the output from the previous step. Here is a YAML sample that evaluates a parameter.

```
mainSteps:
- name: chooseOS
  action: aws:branch
  inputs:
    Choices:
    - NextStep: runWindowsCommand
      Variable: "{{Name of a parameter defined in the Parameters section. For example: OS_name}}"
      StringEquals: windows
    - NextStep: runLinuxCommand
      Variable: "{{Name of a parameter defined in the Parameters section. For example: OS_name}}"
      StringEquals: linux
    Default:
      sleep3
```

Here is a YAML sample that evaluates output from a previous step.

```
mainSteps:
- name: chooseOS
  action: aws:branch
  inputs:
    Choices:
    - NextStep: runPowerShellCommand
      Variable: "{{Name of a response object. For example: GetInstance.platform}}"
      StringEquals: Windows
    - NextStep: runShellCommand
      Variable: "{{Name of a response object. For example: GetInstance.platform}}"
      StringEquals: Linux
    Default:
      sleep3
```

Choices  
One or more expressions that the Automation should evaluate when determining the next step to process. Choices are evaluated by using a Boolean expression. Each choice must define the following options:  
+ **NextStep**: The next step in the runbook to process if the designated choice is true.
+ **Variable**: Specify either the name of a parameter that is defined in the `Parameters` section of the runbook. Or specify an output object from a previous step in the runbook. For more information about creating variables for `aws:branch`, see [About creating the output variable](automation-branch-condition.md#branch-action-output).
+ **Operation**: The criteria used to evaluate the choice. The `aws:branch` action supports the following operations:

**String operations**
  + StringEquals
  + EqualsIgnoreCase
  + StartsWith
  + EndsWith
  + Contains

**Numeric operations**
  + NumericEquals
  + NumericGreater
  + NumericLesser
  + NumericGreaterOrEquals
  + NumericLesser
  + NumericLesserOrEquals

**Boolean operation**
  + BooleanEquals
**Important**  
When you create a runbook, the system validates each operation in the runbook. If an operation isn't supported, the system returns an error when you try to create the runbook.

Default  
The name of a step the automation should jump to if none of the `Choices` are true.  
Type: String  
Required: No

**Note**  
The `aws:branch` action supports `And`, `Or`, and `Not` operators. For examples of `aws:branch` that use operators, see [Using conditional statements in runbooks](automation-branch-condition.md).

# `aws:changeInstanceState` – Change or assert instance state
<a name="automation-action-changestate"></a>

Changes or asserts the state of the instance.

This action can be used in assert mode (doesn't run the API to change the state but verifies the instance is in the desired state.) To use assert mode, set the `CheckStateOnly` parameter to true. This mode is useful when running the Sysprep command on Windows Server, which is an asynchronous command that can run in the background for a long time. You can ensure that the instance is stopped before you create an Amazon Machine Image (AMI).

**Note**  
The default timeout value for this action is 3600 seconds (one hour). You can limit or extend the timeout by specifying the `timeoutSeconds` parameter for an `aws:changeInstanceState` step.

**Note**  
The `aws:changeInstanceState` action supports automatic throttling retry. For more information, see [Configuring automatic retry for throttled operations](automation-throttling-retry.md).

**Input**

------
#### [ YAML ]

```
name: stopMyInstance
action: aws:changeInstanceState
maxAttempts: 3
timeoutSeconds: 3600
onFailure: Abort
inputs:
  InstanceIds:
  - i-1234567890abcdef0
  CheckStateOnly: true
  DesiredState: stopped
```

------
#### [ JSON ]

```
{
    "name":"stopMyInstance",
    "action": "aws:changeInstanceState",
    "maxAttempts": 3,
    "timeoutSeconds": 3600,
    "onFailure": "Abort",
    "inputs": {
        "InstanceIds": ["i-1234567890abcdef0"],
        "CheckStateOnly": true,
        "DesiredState": "stopped"
    }
}
```

------

InstanceIds  
The IDs of the instances.  
Type: StringList  
Required: Yes

CheckStateOnly  
If false, sets the instance state to the desired state. If true, asserts the desired state using polling.  
Default: `false`  
Type: Boolean  
Required: No

DesiredState  
The desired state. When set to `running`, this action waits for the Amazon EC2 state to be `Running`, the Instance Status to be `OK`, and the System Status to be `OK` before completing.  
Type: String  
Valid values: `running` \$1 `stopped` \$1 `terminated`  
Required: Yes

Force  
If set, forces the instances to stop. The instances don't have an opportunity to flush file system caches or file system metadata. If you use this option, you must perform file system check and repair procedures. This option isn't recommended for EC2 instances for Windows Server.  
Type: Boolean  
Required: No

AdditionalInfo  
Reserved.  
Type: String  
Required: No

**Output**  
None

# `aws:copyImage` – Copy or encrypt an Amazon Machine Image
<a name="automation-action-copyimage"></a>

Copies an Amazon Machine Image (AMI) from any AWS Region into the current Region. This action can also encrypt the new AMI.

**Note**  
The `aws:copyImage` action supports automatic throttling retry. For more information, see [Configuring automatic retry for throttled operations](automation-throttling-retry.md).

**Input**  
This action supports most `CopyImage` parameters. For more information, see [CopyImage](https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_CopyImage.html).

The following example creates a copy of an AMI in the Seoul region (`SourceImageID`: ami-0fe10819. `SourceRegion`: ap-northeast-2). The new AMI is copied to the region where you initiated the Automation action. The copied AMI will be encrypted because the optional `Encrypted` flag is set to `true`.

------
#### [ YAML ]

```
name: createEncryptedCopy
action: aws:copyImage
maxAttempts: 3
onFailure: Abort
inputs:
  SourceImageId: ami-0fe10819
  SourceRegion: ap-northeast-2
  ImageName: Encrypted Copy of LAMP base AMI in ap-northeast-2
  Encrypted: true
```

------
#### [ JSON ]

```
{   
    "name": "createEncryptedCopy",
    "action": "aws:copyImage",
    "maxAttempts": 3,
    "onFailure": "Abort",
    "inputs": {
        "SourceImageId": "ami-0fe10819",
        "SourceRegion": "ap-northeast-2",
        "ImageName": "Encrypted Copy of LAMP base AMI in ap-northeast-2",
        "Encrypted": true
    }   
}
```

------

SourceRegion  
The region where the source AMI exists.  
Type: String  
Required: Yes

SourceImageId  
The AMI ID to copy from the source Region.  
Type: String  
Required: Yes

ImageName  
The name for the new image.  
Type: String  
Required: Yes

ImageDescription  
A description for the target image.  
Type: String  
Required: No

Encrypted  
Encrypt the target AMI.  
Type: Boolean  
Required: No

KmsKeyId  
The full Amazon Resource Name (ARN) of the AWS KMS key to use when encrypting the snapshots of an image during a copy operation. For more information, see [CopyImage](https://docs.aws.amazon.com/AWSEC2/latest/APIReference/api_copyimage.html).  
Type: String  
Required: No

ClientToken  
A unique, case-sensitive identifier that you provide to ensure request idempotency. For more information, see [CopyImage](https://docs.aws.amazon.com/AWSEC2/latest/APIReference/api_copyimage.html).  
Type: String  
Required: NoOutput

ImageId  
The ID of the copied image.

ImageState  
The state of the copied image.  
Valid values: `available` \$1 `pending` \$1 `failed`

# `aws:createImage` – Create an Amazon Machine Image
<a name="automation-action-create"></a>

Creates an Amazon Machine Image (AMI) from an instance that is either running, stopping, or stopped, and polls for the `ImageState` to be `available`.

**Note**  
The `aws:createImage` action supports automatic throttling retry. For more information, see [Configuring automatic retry for throttled operations](automation-throttling-retry.md).

**Input**  
This action supports the following `CreateImage` parameters. For more information, see [CreateImage](https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_CreateImage.html).

------
#### [ YAML ]

```
name: createMyImage
action: aws:createImage
maxAttempts: 3
onFailure: Abort
inputs:
  InstanceId: i-1234567890abcdef0
  ImageName: AMI Created on{{global:DATE_TIME}}
  NoReboot: true
  ImageDescription: My newly created AMI
```

------
#### [ JSON ]

```
{
    "name": "createMyImage",
    "action": "aws:createImage",
    "maxAttempts": 3,
    "onFailure": "Abort",
    "inputs": {
        "InstanceId": "i-1234567890abcdef0",
        "ImageName": "AMI Created on{{global:DATE_TIME}}",
        "NoReboot": true,
        "ImageDescription": "My newly created AMI"
    }
}
```

------

InstanceId  
The ID of the instance.  
Type: String  
Required: Yes

ImageName  
The name for the image.  
Type: String  
Required: Yes

ImageDescription  
A description of the image.  
Type: String  
Required: No

NoReboot  
A Boolean literal.  
By default, Amazon Elastic Compute Cloud (Amazon EC2) attempts to shut down and reboot the instance before creating the image. If the **No Reboot** option is set to `true`, Amazon EC2 doesn't shut down the instance before creating the image. When this option is used, file system integrity on the created image can't be guaranteed.   
If you don't want the instance to run after you create an AMI from it, first use the [`aws:changeInstanceState` – Change or assert instance state](automation-action-changestate.md) action to stop the instance, and then use this `aws:createImage` action with the **NoReboot** option set to `true`.  
Type: Boolean  
Required: No

BlockDeviceMappings  
The block devices for the instance.  
Type: Map  
Required: NoOutput

ImageId  
The ID of the newly created image.  
Type: String

ImageState  
The current state of the image. If the state is available, the image is successfully registered and can be used to launch an instance.  
Type: String

# `aws:createStack` – Create an CloudFormation stack
<a name="automation-action-createstack"></a>

Creates an AWS CloudFormation stack from a template.

**Note**  
The `aws:createStack` action supports automatic throttling retry. For more information, see [Configuring automatic retry for throttled operations](automation-throttling-retry.md).

For supplemental information about creating CloudFormation stacks, see [CreateStack](https://docs.aws.amazon.com/AWSCloudFormation/latest/APIReference/API_CreateStack.html) in the *AWS CloudFormation API Reference*. 

**Input**

------
#### [ YAML ]

```
name: makeStack
action: aws:createStack
maxAttempts: 1
onFailure: Abort
inputs:
  Capabilities:
  - CAPABILITY_IAM
  StackName: myStack
  TemplateURL: http://s3.amazonaws.com/amzn-s3-demo-bucket/myStackTemplate
  TimeoutInMinutes: 5
  Parameters:
    - ParameterKey: LambdaRoleArn
      ParameterValue: "{{LambdaAssumeRole}}"
    - ParameterKey: createdResource
      ParameterValue: createdResource-{{automation:EXECUTION_ID}}
```

------
#### [ JSON ]

```
{
    "name": "makeStack",
    "action": "aws:createStack",
    "maxAttempts": 1,
    "onFailure": "Abort",
    "inputs": {
        "Capabilities": [
            "CAPABILITY_IAM"
        ],
        "StackName": "myStack",
        "TemplateURL": "http://s3.amazonaws.com/amzn-s3-demo-bucket/myStackTemplate",
        "TimeoutInMinutes": 5,
        "Parameters": [
          {
            "ParameterKey": "LambdaRoleArn",
            "ParameterValue": "{{LambdaAssumeRole}}"
          },
          {
            "ParameterKey": "createdResource",
            "ParameterValue": "createdResource-{{automation:EXECUTION_ID}}"
          }
    }
}
```

------

Capabilities  
A list of values that you specify before CloudFormation can create certain stacks. Some stack templates include resources that can affect permissions in your AWS account. For those stacks, you must explicitly acknowledge their capabilities by specifying this parameter.   
Valid values include `CAPABILITY_IAM`, `CAPABILITY_NAMED_IAM`, and `CAPABILITY_AUTO_EXPAND`.   
**CAPABILITY\$1IAM and CAPABILITY\$1NAMED\$1IAM**  
If you have IAM resources, you can specify either capability. If you have IAM resources with custom names, you must specify `CAPABILITY_NAMED_IAM`. If you don't specify this parameter, this action returns an `InsufficientCapabilities` error. The following resources require you to specify either `CAPABILITY_IAM` or `CAPABILITY_NAMED_IAM`.
+ [https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-iam-accesskey.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-iam-accesskey.html)
+ [https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-iam-group.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-iam-group.html)
+ [https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-iam-instanceprofile.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-iam-instanceprofile.html)
+ [https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-iam-policy.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-iam-policy.html)
+ [https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-iam-role.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-iam-role.html)
+ [https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-iam-user.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-iam-user.html)
+ [https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-iam-addusertogroup.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-iam-addusertogroup.html)
If your stack template contains these resources, we recommend that you review all permissions associated with them and edit their permissions, if necessary.   
For more information, see [Acknowledging IAM Resources in CloudFormation Templates](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/using-iam-template.html#capabilities).   
**CAPABILITY\$1AUTO\$1EXPAND**  
Some template contain macros. Macros perform custom processing on templates; this can include simple actions like find-and-replace operations, all the way to extensive transformations of entire templates. Because of this, users typically create a change set from the processed template, so that they can review the changes resulting from the macros before actually creating the stack. If your stack template contains one or more macros, and you choose to create a stack directly from the processed template, without first reviewing the resulting changes in a change set, you must acknowledge this capability. 
For more information, see [Using AWS CloudFormation Macros to Perform Custom Processing on Templates](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/template-macros.html) in the *AWS CloudFormation User Guide*.  
Type: array of Strings  
Valid Values: `CAPABILITY_IAM | CAPABILITY_NAMED_IAM | CAPABILITY_AUTO_EXPAND`  
Required: No

ClientRequestToken  
A unique identifier for this CreateStack request. Specify this token if you set maxAttempts in this step to a value greater than 1. By specifying this token, CloudFormation knows that you aren't attempting to create a new stack with the same name.  
Type: String  
Required: No  
Length Constraints: Minimum length of 1. Maximum length of 128.  
Pattern: [a-zA-Z0-9][-a-zA-Z0-9]\$1

DisableRollback  
Set to `true` to turn off rollback of the stack if stack creation failed.  
Conditional: You can specify either the `DisableRollback` parameter or the `OnFailure` parameter, but not both.   
Default: `false`  
Type: Boolean  
Required: No

NotificationARNs  
The Amazon Simple Notification Service (Amazon SNS) topic ARNs for publishing stack-related events. You can find SNS topic ARNs using the Amazon SNS console, [https://console.aws.amazon.com/sns/v3/home](https://console.aws.amazon.com/sns/v3/home).   
Type: array of Strings  
Array Members: Maximum number of 5 items.  
Required: No

OnFailure  
Determines the action to take if stack creation failed. You must specify `DO_NOTHING`, `ROLLBACK`, or `DELETE`.  
Conditional: You can specify either the `OnFailure` parameter or the `DisableRollback` parameter, but not both.   
Default: `ROLLBACK`  
Type: String  
Valid Values:` DO_NOTHING | ROLLBACK | DELETE`  
Required: No

Parameters  
A list of `Parameter` structures that specify input parameters for the stack. For more information, see the [Parameter](https://docs.aws.amazon.com/AWSCloudFormation/latest/APIReference/API_Parameter.html) data type.   
Type: array of [Parameter](https://docs.aws.amazon.com/AWSCloudFormation/latest/APIReference/API_Parameter.html) objects   
Required: No

ResourceTypes  
The template resource types that you have permissions to work with for this create stack action. For example: `AWS::EC2::Instance`, `AWS::EC2::*`, or `Custom::MyCustomInstance`. Use the following syntax to describe template resource types.  
+ For all AWS resources:

  ```
  AWS::*
  ```
+ For all custom resources:

  ```
  Custom::*
  ```
+ For a specific custom resource:

  ```
  Custom::logical_ID
  ```
+ For all resources of a particular AWS service:

  ```
  AWS::service_name::*
  ```
+ For a specific AWS resource:

  ```
  AWS::service_name::resource_logical_ID
  ```
If the list of resource types doesn't include a resource that you're creating, the stack creation fails. By default, CloudFormation grants permissions to all resource types. IAM uses this parameter for CloudFormation-specific condition keys in IAM policies. For more information, see [Controlling Access with AWS Identity and Access Management](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/using-iam-template.html).   
Type: array of Strings  
Length Constraints: Minimum length of 1. Maximum length of 256.  
Required: No

RoleARN  
The Amazon Resource Name (ARN) of an IAM role that CloudFormation assumes to create the stack. CloudFormation uses the role's credentials to make calls on your behalf. CloudFormation always uses this role for all future operations on the stack. As long as users have permission to operate on the stack, CloudFormation uses this role even if the users don't have permission to pass it. Ensure that the role grants the least amount of privileges.   
If you don't specify a value, CloudFormation uses the role that was previously associated with the stack. If no role is available, CloudFormation uses a temporary session that is generated from your user credentials.   
Type: String  
Length Constraints: Minimum length of 20. Maximum length of 2048.  
Required: No

StackName  
The name that is associated with the stack. The name must be unique in the Region in which you're creating the stack.  
A stack name can contain only alphanumeric characters (case sensitive) and hyphens. It must start with an alphabetic character and can't be longer than 128 characters. 
Type: String  
Required: Yes

StackPolicyBody  
Structure containing the stack policy body. For more information, see [Prevent Updates to Stack Resources](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/protect-stack-resources.html).  
Conditional: You can specify either the `StackPolicyBody` parameter or the `StackPolicyURL` parameter, but not both.   
Type: String  
Length Constraints: Minimum length of 1. Maximum length of 16384.  
Required: No

StackPolicyURL  
Location of a file containing the stack policy. The URL must point to a policy located in an S3 bucket in the same region as the stack. The maximum file size allowed for the stack policy is 16 KB.  
Conditional: You can specify either the `StackPolicyBody` parameter or the `StackPolicyURL` parameter, but not both.   
Type: String  
Length Constraints: Minimum length of 1. Maximum length of 1350.  
Required: No

Tags  
Key-value pairs to associate with this stack. CloudFormation also propagates these tags to the resources created in the stack. You can specify a maximum number of 10 tags.   
Type: array of [Tag](https://docs.aws.amazon.com/AWSCloudFormation/latest/APIReference/API_Tag.html) objects   
Required: No

TemplateBody  
Structure containing the template body with a minimum length of 1 byte and a maximum length of 51,200 bytes. For more information, see [Template Anatomy](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/template-anatomy.html).   
Conditional: You can specify either the `TemplateBody` parameter or the `TemplateURL` parameter, but not both.   
Type: String  
Length Constraints: Minimum length of 1.  
Required: No

TemplateURL  
Location of a file containing the template body. The URL must point to a template that is located in an S3 bucket. The maximum size allowed for the template is 460,800 bytes. For more information, see [Template Anatomy](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/template-anatomy.html).   
Conditional: You can specify either the `TemplateBody` parameter or the `TemplateURL` parameter, but not both.   
Type: String  
Length Constraints: Minimum length of 1. Maximum length of 1024.  
Required: No

TimeoutInMinutes  
The amount of time that can pass before the stack status becomes `CREATE_FAILED`. If `DisableRollback` isn't set or is set to `false`, the stack will be rolled back.   
Type: Integer  
Valid Range: Minimum value of 1.  
Required: No

## Outputs
<a name="automation-action-createstack-output"></a>

StackId  
Unique identifier of the stack.  
Type: String

StackStatus  
Current status of the stack.  
Type: String  
Valid Values: `CREATE_IN_PROGRESS | CREATE_FAILED | CREATE_COMPLETE | ROLLBACK_IN_PROGRESS | ROLLBACK_FAILED | ROLLBACK_COMPLETE | DELETE_IN_PROGRESS | DELETE_FAILED | DELETE_COMPLETE | UPDATE_IN_PROGRESS | UPDATE_COMPLETE_CLEANUP_IN_PROGRESS | UPDATE_COMPLETE | UPDATE_ROLLBACK_IN_PROGRESS | UPDATE_ROLLBACK_FAILED | UPDATE_ROLLBACK_COMPLETE_CLEANUP_IN_PROGRESS | UPDATE_ROLLBACK_COMPLETE | REVIEW_IN_PROGRESS`  
Required: Yes

StackStatusReason  
Success or failure message associated with the stack status.  
Type: String  
Required: No  
For more information, see [CreateStack](https://docs.aws.amazon.com/AWSCloudFormation/latest/APIReference/API_CreateStack.html).

## Security considerations
<a name="automation-action-createstack-security"></a>

Before you can use the `aws:createStack` action, you must assign the following policy to the IAM Automation assume role. For more information about the assume role, see [Task 1: Create a service role for Automation](automation-setup-iam.md#create-service-role). 

------
#### [ JSON ]

****  

```
{
   "Version":"2012-10-17",		 	 	 
   "Statement":[
      {
         "Effect":"Allow",
         "Action":[
            "sqs:*",
            "cloudformation:CreateStack",
            "cloudformation:DescribeStacks"
         ],
         "Resource":"*"
      }
   ]
}
```

------

# `aws:createTags` – Create tags for AWS resources
<a name="automation-action-createtag"></a>

Creates new tags for Amazon Elastic Compute Cloud (Amazon EC2) instances or AWS Systems Manager managed instances.

**Note**  
The `aws:createTags` action supports automatic throttling retry. For more information, see [Configuring automatic retry for throttled operations](automation-throttling-retry.md).

**Input**  
This action supports most Amazon EC2 `CreateTags` and Systems Manager `AddTagsToResource` parameters. For more information, see [CreateTags](https://docs.aws.amazon.com/AWSEC2/latest/APIReference/api_createtags.html) and [AddTagsToResource](https://docs.aws.amazon.com/AWSEC2/latest/APIReference/api_addtagstoresource.html).

The following example shows how to tag an Amazon Machine Image (AMI) and an instance as production resources for a particular department.

------
#### [ YAML ]

```
name: createTags
action: aws:createTags
maxAttempts: 3
onFailure: Abort
inputs:
  ResourceType: EC2
  ResourceIds:
  - ami-9a3768fa
  - i-02951acd5111a8169
  Tags:
  - Key: production
    Value: ''
  - Key: department
    Value: devops
```

------
#### [ JSON ]

```
{
    "name": "createTags",
    "action": "aws:createTags",
    "maxAttempts": 3,
    "onFailure": "Abort",
    "inputs": {
        "ResourceType": "EC2",
        "ResourceIds": [
            "ami-9a3768fa",
            "i-02951acd5111a8169"
        ],
        "Tags": [
            {
                "Key": "production",
                "Value": ""
            },
            {
                "Key": "department",
                "Value": "devops"
            }
        ]
    }
}
```

------

ResourceIds  
The IDs of the resource(s) to be tagged. If resource type isn't “EC2”, this field can contain only a single item.  
Type: String List  
Required: Yes

Tags  
The tags to associate with the resource(s).  
Type: List of Maps  
Required: Yes

ResourceType  
The type of resource(s) to be tagged. If not supplied, the default value of “EC2” is used.  
Type: String  
Required: No  
Valid Values: `EC2` \$1 `ManagedInstance` \$1 `MaintenanceWindow` \$1 `Parameter`

**Output**  
None

# `aws:deleteImage` – Delete an Amazon Machine Image
<a name="automation-action-delete"></a>

Deletes the specified Amazon Machine Image (AMI) and all related snapshots.

**Note**  
The `aws:deleteImage` action supports automatic throttling retry. For more information, see [Configuring automatic retry for throttled operations](automation-throttling-retry.md).

**Input**  
This action supports only one parameter. For more information, see the documentation for [DeregisterImage](https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_DeregisterImage.html) and [DeleteSnapshot](https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_DeleteSnapshot.html).

------
#### [ YAML ]

```
name: deleteMyImage
action: aws:deleteImage
maxAttempts: 3
timeoutSeconds: 180
onFailure: Abort
inputs:
  ImageId: ami-12345678
```

------
#### [ JSON ]

```
{
    "name": "deleteMyImage",
    "action": "aws:deleteImage",
    "maxAttempts": 3,
    "timeoutSeconds": 180,
    "onFailure": "Abort",
    "inputs": {
        "ImageId": "ami-12345678"
    }
}
```

------

ImageId  
The ID of the image to be deleted.  
Type: String  
Required: Yes

**Output**  
None

# `aws:deleteStack` – Delete an CloudFormation stack
<a name="automation-action-deletestack"></a>

Deletes an AWS CloudFormation stack.

**Note**  
The `aws:deleteStack` action supports automatic throttling retry. For more information, see [Configuring automatic retry for throttled operations](automation-throttling-retry.md).

**Input**

------
#### [ YAML ]

```
name: deleteStack
action: aws:deleteStack
maxAttempts: 1
onFailure: Abort
inputs:
  StackName: "{{stackName}}"
```

------
#### [ JSON ]

```
{
   "name":"deleteStack",
   "action":"aws:deleteStack",
   "maxAttempts":1,
   "onFailure":"Abort",
   "inputs":{
      "StackName":"{{stackName}}"
   }
}
```

------

ClientRequestToken  
A unique identifier for this `DeleteStack` request. Specify this token if you plan to retry requests so that CloudFormation knows that you aren't attempting to delete a stack with the same name. You can retry `DeleteStack` requests to verify that CloudFormation received them.  
Type: String  
Length Constraints: Minimum length of 1. Maximum length of 128.  
Pattern: [a-zA-Z][-a-zA-Z0-9]\$1  
Required: No

RetainResources.member.N  
This input applies only to stacks that are in a `DELETE_FAILED` state. A list of logical resource IDs for the resources you want to retain. During deletion, CloudFormation deletes the stack, but doesn't delete the retained resources.  
Retaining resources is useful when you can't delete a resource, such as a non-empty S3 bucket, but you want to delete the stack.  
Type: array of strings  
Required: No

RoleARN  
The Amazon Resource Name (ARN) of an AWS Identity and Access Management (IAM) role that CloudFormation assumes to create the stack. CloudFormation uses the role's credentials to make calls on your behalf. CloudFormation always uses this role for all future operations on the stack. As long as users have permission to operate on the stack, CloudFormation uses this role even if the users don't have permission to pass it. Ensure that the role grants the least amount of privileges.   
If you don't specify a value, CloudFormation uses the role that was previously associated with the stack. If no role is available, CloudFormation uses a temporary session that is generated from your user credentials.   
Type: String  
Length Constraints: Minimum length of 20. Maximum length of 2048.  
Required: No

StackName  
The name or the unique stack ID that is associated with the stack.  
Type: String  
Required: Yes

## Security considerations
<a name="automation-action-deletestack-security"></a>

Before you can use the `aws:deleteStack` action, you must assign the following policy to the IAM Automation assume role. For more information about the assume role, see [Task 1: Create a service role for Automation](automation-setup-iam.md#create-service-role). 

------
#### [ JSON ]

****  

```
{
   "Version":"2012-10-17",		 	 	 
   "Statement":[
      {
         "Effect":"Allow",
         "Action":[
            "sqs:*",
            "cloudformation:DeleteStack",
            "cloudformation:DescribeStacks"
         ],
         "Resource":"*"
      }
   ]
}
```

------

# `aws:executeAutomation` – Run another automation
<a name="automation-action-executeAutomation"></a>

Runs a secondary automation by calling a secondary runbook. With this action, you can create runbooks for your most common operations, and reference those runbooks during an automation. This action can simplify your runbooks by removing the need to duplicate steps across similar runbooks.

The secondary automation runs in the context of the user who initiated the primary automation. This means that the secondary automation uses the same AWS Identity and Access Management (IAM) role or user as the user who started the first automation.

**Important**  
If you specify parameters in a secondary automation that use an assume role (a role that uses the iam:passRole policy), then the user or role that initiated the primary automation must have permission to pass the assume role specified in the secondary automation. For more information about setting up an assume role for Automation, see [Create the service roles for Automation using the console](automation-setup-iam.md).

**Input**

------
#### [ YAML ]

```
name: Secondary_Automation
action: aws:executeAutomation
maxAttempts: 3
timeoutSeconds: 3600
onFailure: Abort
inputs:
  DocumentName: secondaryAutomation
  RuntimeParameters:
    instanceIds:
    - i-1234567890abcdef0
```

------
#### [ JSON ]

```
{
   "name":"Secondary_Automation",
   "action":"aws:executeAutomation",
   "maxAttempts":3,
   "timeoutSeconds":3600,
   "onFailure":"Abort",
   "inputs":{
      "DocumentName":"secondaryAutomation",
      "RuntimeParameters":{
         "instanceIds":[
            "i-1234567890abcdef0"
         ]
      }
   }
}
```

------

DocumentName  
The name of the secondary runbook to run during the step. For runbooks in the same AWS account, specify the runbook name. For runbooks shared from a different AWS account, specify the Amazon Resource Name (ARN) of the runbook. For information about using shared runbooks, see [Using shared SSM documents](documents-ssm-sharing.md#using-shared-documents).  
Type: String  
Required: Yes

DocumentVersion  
The version of the secondary runbook to run. If not specified, Automation runs the default runbook version.  
Type: String  
Required: No

MaxConcurrency  
The maximum number of targets allowed to run this task in parallel. You can specify a number, such as 10, or a percentage, such as 10%.  
Type: String  
Required: No

MaxErrors  
The number of errors that are allowed before the system stops running the automation on additional targets. You can specify either an absolute number of errors, for example 10, or a percentage of the target set, for example 10%. If you specify 3, for example, the system stops running the automation when the fourth error is received. If you specify 0, then the system stops running the automation on additional targets after the first error result is returned. If you run an automation on 50 resources and set `MaxErrors` to 10%, then the system stops running the automation on additional targets when the sixth error is received.  
Automations that are already running when the `MaxErrors` threshold is reached are allowed to complete, but some of these automations may fail as well. If you need to ensure that there won't be more failed automations than the specified `MaxErrors`, set `MaxConcurrency` to 1 so the automations proceed one at a time.  
Type: String  
Required: No

RuntimeParameters  
Required parameters for the secondary runbook. The mapping uses the following format: \$1"parameter1" : "value1", "parameter2" : "value2" \$1  
Type: Map  
Required: No

Tags  
Optional metadata that you assign to a resource. You can specify a maximum of five tags for an automation.  
Type: MapList  
Required: No

TargetLocations  
A location is a combination of AWS Regions and/or AWS accounts where you want to run the automation. A minimum number of 1 item must be specified and a maximum number of 100 items can be specified. When specifying a value for this parameter, outputs aren't returned to the parent automation. If needed, you must make subsequent calls to API operations to retrieve the output from child automations.  
Type: MapList  
Required: No

TargetMaps  
A list of key-value mappings of document parameters to target resources. Both `Targets` and `TargetMaps` can't be specified together.   
Type: MapList  
Required: No

TargetParameterName  
The name of the parameter used as the target resource for the rate-controlled automation. Required if you specify `Targets`.  
Type: String  
Required: No

Targets  
A list of key-value mappings to target resources. Required if you specify `TargetParameterName`.  
Type: MapList  
Required: NoOutput

Output  
The output generated by the secondary automation. You can reference the output by using the following format: *Secondary\$1Automation\$1Step\$1Name*.Output  
Type: StringList  
Here is an example:  

```
- name: launchNewWindowsInstance
  action: 'aws:executeAutomation'
  onFailure: Abort
  inputs:
    DocumentName: launchWindowsInstance
  nextStep: getNewInstanceRootVolume
- name: getNewInstanceRootVolume
  action: 'aws:executeAwsApi'
  onFailure: Abort
  inputs:
    Service: ec2
    Api: DescribeVolumes
    Filters:
    - Name: attachment.device
      Values:
      - /dev/sda1
    - Name: attachment.instance-id
      Values:
      - '{{launchNewWindowsInstance.Output}}'
  outputs:
  - Name: rootVolumeId
    Selector: '$.Volumes[0].VolumeId'
    Type: String
  nextStep: snapshotRootVolume
- name: snapshotRootVolume
  action: 'aws:executeAutomation'
  onFailure: Abort
  inputs:
    DocumentName: AWS-CreateSnapshot
    RuntimeParameters:
    VolumeId:
    - '{{getNewInstanceRootVolume.rootVolumeId}}'
    Description:
    - 'Initial root snapshot for {{launchNewWindowsInstance.Output}}'
```

ExecutionId  
The ID of the secondary automation.  
Type: String

Status  
The status of the secondary automation.  
Type: String

# `aws:executeAwsApi` – Call and run AWS API operations
<a name="automation-action-executeAwsApi"></a>

Calls and runs AWS API operations. Most API operations are supported, although not all API operations have been tested. Streaming API operations, such as the [GetObject](https://docs.aws.amazon.com/AmazonS3/latest/API/RESTObjectGET.html) operation, aren't supported. If you're not sure if an API operation you want to use is a streaming operation, review the [Boto3](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/index.html) documentation for the service to determine if an API requires streaming inputs or outputs. We regularly update the Boto3 version used by this action. However, following the release of a new Boto3 version it can take up to a few weeks for changes to be reflected in this action. Each `aws:executeAwsApi` action can run up to a maximum duration of 25 seconds. For more examples of how to use this action, see [Additional runbook examples](automation-document-examples.md).

**Note**  
The `aws:executeAwsApi` action supports automatic throttling retry. For more information, see [Configuring automatic retry for throttled operations](automation-throttling-retry.md).

**Inputs**  
Inputs are defined by the API operation that you choose. 

------
#### [ YAML ]

```
action: aws:executeAwsApi
inputs:
  Service: The official namespace of the service
  Api: The API operation or method name
  API operation inputs or parameters: A value
outputs: # These are user-specified outputs
- Name: The name for a user-specified output key
  Selector: A response object specified by using jsonpath format
  Type: The data type
```

------
#### [ JSON ]

```
{
   "action":"aws:executeAwsApi",
   "inputs":{
      "Service":"The official namespace of the service",
      "Api":"The API operation or method name",
      "API operation inputs or parameters":"A value"
   },
   "outputs":[ These are user-specified outputs
      {
         "Name":"The name for a user-specified output key",
         "Selector":"A response object specified by using JSONPath format",
         "Type":"The data type"
      }
   ]
}
```

------

Service  
The AWS service namespace that contains the API operation that you want to run. You can view a list of supported AWS service namespaces in [Available services](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/index.html) of the AWS SDK for Python (Boto3). The namespace can be found in the **Client** section. For example, the namespace for Systems Manager is `ssm`. The namespace for Amazon Elastic Compute Cloud (Amazon EC2) is `ec2`.  
Type: String  
Required: Yes

Api  
The name of the API operation that you want to run. You can view the API operations (also called methods) by choosing a service in the left navigation on the following [Services Reference](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/index.html) page. Choose a method in the **Client** section for the service that you want to invoke. For example, all API operations (methods) for Amazon Relational Database Service (Amazon RDS) are listed on the following page: [Amazon RDS methods](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/rds.html).  
Type: String  
Required: Yes

API operation inputs  
One or more API operation inputs. You can view the available inputs (also called parameters) by choosing a service in the left navigation on the following [Services Reference](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/index.html) page. Choose a method in the **Client** section for the service that you want to invoke. For example, all methods for Amazon RDS are listed on the following page: [Amazon RDS methods](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/rds.html). Choose the [describe\$1db\$1instances](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/rds.html#RDS.Client.describe_db_instances) method and scroll down to see the available parameters, such as **DBInstanceIdentifier**, **Name**, and **Values**.  

```
inputs:
  Service: The official namespace of the service
  Api: The API operation name
  API input 1: A value
  API Input 2: A value
  API Input 3: A value
```

```
"inputs":{
      "Service":"The official namespace of the service",
      "Api":"The API operation name",
      "API input 1":"A value",
      "API Input 2":"A value",
      "API Input 3":"A value"
}
```
Type: Determined by chosen API operation  
Required: Yes

**Outputs**  
Outputs are specified by the user based on the response from the chosen API operation.

Name  
A name for the output.  
Type: String  
Required: Yes

Selector  
The JSONPath to a specific attribute in the response object. You can view the response objects by choosing a service in the left navigation on the following [Services Reference](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/index.html) page. Choose a method in the **Client** section for the service that you want to invoke. For example, all methods for Amazon RDS are listed on the following page: [Amazon RDS methods](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/rds.html). Choose the [describe\$1db\$1instances](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/rds.html#RDS.Client.describe_db_instances) method and scroll down to the **Response Structure** section. **DBInstances** is listed as a response object.  
Type: Integer, Boolean, String, StringList, StringMap, or MapList  
Required: Yes

Type  
The data type for the response element.  
Type: Varies  
Required: Yes

# `aws:executeScript` – Run a script
<a name="automation-action-executeScript"></a>

Runs the Python or PowerShell script provided using the specified runtime and handler. Each `aws:executeScript` action can run up to a maximum duration of 600 seconds (10 minutes). You can limit the timeout by specifying the `timeoutSeconds` parameter for an `aws:executeScript` step.

Use return statements in your function to add outputs to your output payload. For examples of defining outputs for your `aws:executeScript` action, see [Example 2: Scripted runbook](automation-authoring-runbooks-scripted-example.md). You can also send the output from `aws:executeScript` actions in your runbooks to the Amazon CloudWatch Logs log group you specify. For more information, see [Logging Automation action output with CloudWatch Logs](automation-action-logging.md).

If you want to send output from `aws:executeScript` actions to CloudWatch Logs, or if the scripts you specify for `aws:executeScript` actions call AWS API operations, an AWS Identity and Access Management (IAM) service role (or assume role) is always required to run the runbook.

**Note**  
The `aws:executeScript` action does not support automatic throttling retry. If your script makes AWS API calls that might be throttled, you must implement your own retry logic in your script code.

The `aws:executeScript` action contains the following preinstalled PowerShell Core modules:
+ Microsoft.PowerShell.Host
+ Microsoft.PowerShell.Management
+ Microsoft.PowerShell.Security
+ Microsoft.PowerShell.Utility
+ PackageManagement
+ PowerShellGet

To use PowerShell Core modules that aren't preinstalled, your script must install the module with the `-Force` flag, as shown in the following command. The `AWSPowerShell.NetCore` module isn't supported. Replace *ModuleName* with the module you want to install.

```
Install-Module ModuleName -Force
```

To use PowerShell Core cmdlets in your script, we recommend using the `AWS.Tools` modules, as shown in the following commands. Replace each *example resource placeholder* with your own information.
+ Amazon S3 cmdlets.

  ```
  Install-Module AWS.Tools.S3 -Force
  Get-S3Bucket -BucketName amzn-s3-demo-bucket
  ```
+ Amazon EC2 cmdlets.

  ```
  Install-Module AWS.Tools.EC2 -Force
  Get-EC2InstanceStatus -InstanceId instance-id
  ```
+ Common, or service independent AWS Tools for Windows PowerShell cmdlets.

  ```
  Install-Module AWS.Tools.Common -Force
  Get-AWSRegion
  ```

If your script initializes new objects in addition to using PowerShell Core cmdlets, you must also import the module as shown in the following command.

```
Install-Module AWS.Tools.EC2 -Force
Import-Module AWS.Tools.EC2

$tag = New-Object Amazon.EC2.Model.Tag
$tag.Key = "Tag"
$tag.Value = "TagValue"

New-EC2Tag -Resource i-02573cafcfEXAMPLE -Tag $tag
```

For examples of installing and importing `AWS.Tools` modules, and using PowerShell Core cmdlets in runbooks, see [Visual design experience for Automation runbooks](automation-visual-designer.md).

**Input**  
Provide the information required to run your script. Replace each *example resource placeholder* with your own information.

**Note**  
The attachment for a Python script can be a .py file or a .zip file that contains the script. PowerShell scripts must be stored in .zip files.

------
#### [ YAML ]

```
action: "aws:executeScript"
inputs: 
 Runtime: runtime
 Handler: "functionName"
 InputPayload: 
  scriptInput: '{{parameterValue}}'
 Script: |-
   def functionName(events, context):
   ...
 Attachment: "scriptAttachment.zip"
```

------
#### [ JSON ]

```
{
    "action": "aws:executeScript",
    "inputs": {
        "Runtime": "runtime",
        "Handler": "functionName",
        "InputPayload": {
            "scriptInput": "{{parameterValue}}"
        },
        "Attachment": "scriptAttachment.zip"
    }
}
```

------

Runtime  
The runtime language to be used for running the provided script. `aws:executeScript` supports the runtimes in the following table.      
[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/systems-manager/latest/userguide/automation-action-executeScript.html)
Type: String  
Required: Yes  
For python runtimes, the environment provides 512MB of memory and 512MB of disk space. For PowerShell runtimes, the environment provides 1024MB of memory and 512MB of disk space.

Handler  
The name of your function. You must ensure the function defined in the handler has two parameters, `events` and `context`. The PowerShell runtime does not support this parameter.  
Type: String  
Required: Yes (Python) \$1 Not supported (PowerShell)

InputPayload  
A JSON or YAML object that will be passed to the first parameter of the handler. This can be used to pass input data to the script.  
Type: String  
Required: No  

```
description: Tag an instance
schemaVersion: '0.3'
assumeRole: '{{AutomationAssumeRole}}'
parameters:
    AutomationAssumeRole:
        type: String
        description: '(Required) The Amazon Resource Name (ARN) of the IAM role that allows Automation to perform the actions on your behalf. If no role is specified, Systems Manager Automation uses your IAM permissions to operate this runbook.'
    InstanceId:
        type: String
        description: (Required) The ID of the EC2 instance you want to tag.
mainSteps:
  - name: tagInstance
    action: 'aws:executeScript'
    inputs:
        Runtime: "python3.11"
        Handler: tagInstance
        InputPayload:
            instanceId: '{{InstanceId}}'
        Script: |-
          def tagInstance(events,context):
            import boto3

            #Initialize client
            ec2 = boto3.client('ec2')
            instanceId = events['instanceId']
            tag = {
                "Key": "Env",
                "Value": "ExamplePython"
            }
            print(f"Adding tag {tag} to instance id {instanceId}")
            ec2.create_tags(
                Resources=[instanceId],
                Tags=[tag]
            )
            return tag
    outputs:
      - Type: String
        Name: TagKey
        Selector: $.Payload.Key
outputs:
  - tagInstance.TagKey
```

```
description: Tag an instance
schemaVersion: '0.3'
assumeRole: '{{AutomationAssumeRole}}'
parameters:
  AutomationAssumeRole:
    type: String
    description: (Required) The Amazon Resource Name (ARN) of the IAM role that allows Automation to perform the actions on your behalf. If no role is specified, Systems Manager Automation uses your IAM permissions to operate this runbook.
  InstanceId:
    type: String
    description: (Required) The ID of the EC2 instance you want to tag.
mainSteps:
  - name: tagInstance
    action: aws:executeScript
    isEnd: true
    inputs:
      Runtime: PowerShell 7.4
      InputPayload:
        instanceId: '{{InstanceId}}'
      Script: |-
        Install-Module AWS.Tools.EC2 -Force
        Import-Module AWS.Tools.EC2

        $input = $env:InputPayload | ConvertFrom-Json

        $tag = New-Object Amazon.EC2.Model.Tag
        $tag.Key = "Env"
        $tag.Value = "ExamplePowerShell"

        Write-Information "Adding tag key: $($tag.Key) and value: $($tag.Value) to instance id $($input.instanceId)"
        New-EC2Tag -Resource $input.instanceId -Tag $tag

        return $tag
    outputs:
      - Type: String
        Name: TagKey
        Selector: $.Payload.Key
outputs:
  - tagInstance.TagKey
```

Script  
An embedded script that you want to run during the automation.  
Type: String  
Required: No (Python) \$1 Yes (PowerShell)

Attachment  
The name of a standalone script file or .zip file that can be invoked by the action. Specify the same value as the `Name` of the document attachment file you specify in the `Attachments` request parameter. For more information, see [Attachments](https://docs.aws.amazon.com/systems-manager/latest/APIReference/API_CreateDocument.html#systemsmanager-CreateDocument-request-Attachments) in the *AWS Systems Manager API Reference*. If you're providing a script using an attachment, you must also define a `files` section in the top-level elements of your runbook. For more information, see [Schema version 0.3](documents-schemas-features.md#automation-doc-syntax-examples).  
To invoke a file for Python, use the `filename.method_name` format in `Handler`.   
The attachment for a Python script can be a .py file or a .zip file that contains the script. PowerShell scripts must be stored in .zip files.
When including Python libraries in your attachment, we recommend adding an empty `__init__.py` file in each module directory. This allows you to import the modules from the library in your attachment within your script content. For example: `from library import module`  
Type: String  
Required: NoOutput

Payload  
The JSON representation of the object returned by your function. Up to 100KB is returned. If you output a list, a maximum of 100 items is returned.

## Using attachments with aws:executeScript
<a name="automation-action-executeScript-attachments"></a>

Attachments provide a powerful way to package and reuse complex scripts, multiple modules, and external dependencies with your `aws:executeScript` actions. Use attachments when you need to:
+ Package multiple Python modules or PowerShell scripts together.
+ Reuse the same script logic across multiple runbooks.
+ Include external libraries or dependencies with your scripts.
+ Keep your runbook definition clean by separating complex script logic.
+ Share script packages across teams or automation workflows.

### Attachment structure and packaging
<a name="automation-action-executeScript-attachment-structure"></a>

You can attach either single files or zip packages containing multiple files. The structure depends on your use case:

**Single file attachments**  
For simple scripts, you can attach a single `.py` file (Python) or a `.zip` file containing a single PowerShell script.

**Multi-module packages**  
For complex automation that requires multiple modules, create a zip package with the following recommended structure:

```
my-automation-package.zip
├── main.py                    # Entry point script
├── utils/
│   ├── __init__.py           # Required for Python module imports
│   ├── helper_functions.py   # Utility functions
│   └── aws_operations.py     # AWS-specific operations
├── config/
│   ├── __init__.py
│   └── settings.py           # Configuration settings
└── requirements.txt          # Optional: document dependencies
```

**Important**  
For Python packages, you must include an empty `__init__.py` file in each directory that contains Python modules. This allows you to import modules using standard Python import syntax like `from utils import helper_functions`.

**PowerShell package structure**  
PowerShell attachments must be packaged in zip files with the following structure:

```
my-powershell-package.zip
├── Main.ps1                  # Entry point script
├── Modules/
│   ├── HelperFunctions.ps1   # Utility functions
│   └── AWSOperations.ps1     # AWS-specific operations
└── Config/
    └── Settings.ps1          # Configuration settings
```

### Creating runbooks with attachments
<a name="automation-action-executeScript-attachment-workflow"></a>

Follow these steps to create runbooks that use attachments:

1. **Upload your attachment to Amazon S3**

   Upload your script file or zip package to an S3 bucket that your automation role can access. Note the S3 URI for use in the next step.

   ```
   aws s3 cp my-automation-package.zip s3://my-automation-bucket/scripts/
   ```

1. **Calculate the attachment checksum**

   Calculate the SHA-256 checksum of your attachment file for security verification:

   ```
   # Linux/macOS
   shasum -a 256 my-automation-package.zip
   
   # Windows PowerShell
   Get-FileHash -Algorithm SHA256 my-automation-package.zip
   ```

1. **Define the files section in your runbook**

   Add a `files` section at the top level of your runbook to reference your attachment:

   ```
   files:
     my-automation-package.zip:
       checksums:
         sha256: "your-calculated-checksum-here"
   ```

1. **Reference the attachment in your executeScript step**

   Use the `Attachment` parameter to reference your uploaded file:

   ```
   - name: runMyScript
     action: aws:executeScript
     inputs:
       Runtime: python3.11
       Handler: main.process_data
       Attachment: my-automation-package.zip
       InputPayload:
         inputData: "{{InputParameter}}"
   ```

## aws:executeScript attachment examples
<a name="automation-action-executeScript-examples"></a>

The following examples demonstrate different ways to use attachments with the `aws:executeScript` action.

### Example 1: Single file attachment
<a name="automation-action-executeScript-single-file-example"></a>

This example shows how to use a single Python file as an attachment to process EC2 instance data.

**Attachment file: process\$1instance.py**  
Create a Python file with the following content:

```
import boto3
import json

def process_instance_data(events, context):
    """Process EC2 instance data and return formatted results."""
    try:
        instance_id = events.get('instanceId')
        if not instance_id:
            raise ValueError("instanceId is required")
        
        ec2 = boto3.client('ec2')
        
        # Get instance details
        response = ec2.describe_instances(InstanceIds=[instance_id])
        instance = response['Reservations'][0]['Instances'][0]
        
        # Format the response
        result = {
            'instanceId': instance_id,
            'instanceType': instance['InstanceType'],
            'state': instance['State']['Name'],
            'availabilityZone': instance['Placement']['AvailabilityZone'],
            'tags': {tag['Key']: tag['Value'] for tag in instance.get('Tags', [])}
        }
        
        print(f"Successfully processed instance {instance_id}")
        return result
        
    except Exception as e:
        print(f"Error processing instance: {str(e)}")
        raise
```

**Complete runbook**  
Here's the complete runbook that uses the single file attachment:

```
description: Process EC2 instance data using single file attachment
schemaVersion: '0.3'
assumeRole: '{{AutomationAssumeRole}}'
parameters:
  AutomationAssumeRole:
    type: String
    description: (Required) IAM role for automation execution
  InstanceId:
    type: String
    description: (Required) EC2 instance ID to process

files:
  process_instance.py:
    checksums:
      sha256: "abc123def456..."

mainSteps:
  - name: processInstance
    action: aws:executeScript
    inputs:
      Runtime: python3.11
      Handler: process_instance.process_instance_data
      Attachment: process_instance.py
      InputPayload:
        instanceId: '{{InstanceId}}'
    outputs:
      - Type: StringMap
        Name: InstanceData
        Selector: $.Payload

outputs:
  - processInstance.InstanceData
```

### Example 2: Multi-module package
<a name="automation-action-executeScript-multi-module-example"></a>

This example demonstrates using a zip package containing multiple Python modules for complex S3 bucket operations.

**Package structure**  
Create a zip package with the following structure:

```
s3-operations.zip
├── main.py
├── utils/
│   ├── __init__.py
│   ├── s3_helper.py
│   └── validation.py
└── config/
    ├── __init__.py
    └── settings.py
```

**main.py (entry point)**  
The main script that orchestrates the operations:

```
from utils.s3_helper import S3Operations
from utils.validation import validate_bucket_name
from config.settings import get_default_settings

def cleanup_s3_bucket(events, context):
    """Clean up S3 bucket based on specified criteria."""
    try:
        bucket_name = events.get('bucketName')
        max_age_days = events.get('maxAgeDays', 30)
        
        # Validate inputs
        if not validate_bucket_name(bucket_name):
            raise ValueError(f"Invalid bucket name: {bucket_name}")
        
        # Initialize S3 operations
        s3_ops = S3Operations()
        settings = get_default_settings()
        
        # Perform cleanup
        deleted_objects = s3_ops.delete_old_objects(
            bucket_name, 
            max_age_days,
            settings['dry_run']
        )
        
        result = {
            'bucketName': bucket_name,
            'deletedCount': len(deleted_objects),
            'deletedObjects': deleted_objects[:10],  # Return first 10 for brevity
            'dryRun': settings['dry_run']
        }
        
        print(f"Cleanup completed for bucket {bucket_name}")
        return result
        
    except Exception as e:
        print(f"Error during S3 cleanup: {str(e)}")
        raise
```

## Troubleshooting aws:executeScript attachments
<a name="automation-action-executeScript-troubleshooting"></a>

Use the following guidance to resolve common issues with `aws:executeScript` attachments:

**Module import errors**  
If you receive import errors when using multi-module packages:
+ Ensure you have included an empty `__init__.py` file in each directory containing Python modules.
+ Verify that your import statements match the actual file and directory structure in your zip package.
+ Use relative imports (e.g., `from .utils import helper`) or absolute imports (e.g., `from utils import helper`) consistently.

**Attachment not found errors**  
If your automation fails to find the attachment:
+ Verify that the `Attachment` parameter value exactly matches the key in your `files` section.
+ Check that your S3 bucket path and file name are correct in the `files` section.
+ Ensure your automation role has `s3:GetObject` permission for the attachment S3 location.
+ Verify that the checksum in your runbook matches the actual file checksum.

**Handler function errors**  
If you receive handler-related errors:
+ For Python: Use the format `filename.function_name` in the `Handler` parameter (e.g., `main.process_data`).
+ Ensure your handler function accepts exactly two parameters: `events` and `context`.
+ For PowerShell: Do not specify a `Handler` parameter; the script runs directly.

**Script execution failures**  
If your script fails during execution:
+ Check the automation execution history for detailed error messages and stack traces.
+ Use `print()` statements (Python) or `Write-Information` (PowerShell) to add debugging output.
+ Verify that all required AWS permissions are granted to your automation role.
+ Test your script logic locally before packaging it as an attachment.

**Exit codes and error handling**  
To properly handle errors and return exit codes:
+ In Python: Use `raise Exception("error message")` to indicate script failure.
+ In PowerShell: Use `throw "error message"` or `Write-Error` to indicate failure.
+ Return structured data from your functions to provide detailed success/failure information.
+ Use try-catch blocks to handle exceptions gracefully and provide meaningful error messages.

# `aws:executeStateMachine` – Run an AWS Step Functions state machine
<a name="automation-action-executeStateMachine"></a>

Runs an AWS Step Functions state machine.

**Note**  
The `aws:executeStateMachine` action supports automatic throttling retry. For more information, see [Configuring automatic retry for throttled operations](automation-throttling-retry.md).

**Input**

This action supports most parameters for the Step Functions [StartExecution](https://docs.aws.amazon.com/step-functions/latest/apireference/API_StartExecution.html) API operation.

**Required AWS Identity and Access Management (IAM) permissions**
+ `states:DescribeExecution`
+ `states:StartExecution`
+ `states:StopExecution`

------
#### [ YAML ]

```
name: executeTheStateMachine
action: aws:executeStateMachine
inputs:
  stateMachineArn: StateMachine_ARN
  input: '{"parameters":"values"}'
  name: name
```

------
#### [ JSON ]

```
{
    "name": "executeTheStateMachine",
    "action": "aws:executeStateMachine",
    "inputs": {
        "stateMachineArn": "StateMachine_ARN",
        "input": "{\"parameters\":\"values\"}",
        "name": "name"
    }
}
```

------

stateMachineArn  
The Amazon Resource Name (ARN) of the Step Functions state machine.  
Type: String  
Required: Yes

name  
The name of the execution.  
Type: String  
Required: No

input  
A string that contains the JSON input data for the execution.  
Type: String  
Required: No

**Outputs**  
The following outputs are predefined for this action.

executionArn  
The ARN of the execution.  
Type: String

input  
The string that contains the JSON input data of the execution. Length constraints apply to the payload size, and are expressed as bytes in UTF-8 encoding..  
Type: String

name  
The name of the execution.  
Type: String

output  
The JSON output data of the execution. Length constraints apply to the payload size, and are expressed as bytes in UTF-8 encoding.  
Type: String

startDate  
The date the execution is started.  
Type: String

stateMachineArn  
The ARN of the executed stated machine.  
Type: String

status  
The current status of the execution.  
Type: String

stopDate  
If the execution has already ended, the date the execution stopped.  
Type: String

# `aws:invokeWebhook` – Invoke an Automation webhook integration
<a name="invoke-webhook"></a>

Invokes the specified Automation webhook integration. For information about creating Automation integrations, see [Creating webhook integrations for Automation](creating-webhook-integrations.md).

**Note**  
The `aws:invokeWebhook` action supports automatic throttling retry. For more information, see [Configuring automatic retry for throttled operations](automation-throttling-retry.md).

**Note**  
To use the `aws:invokeWebhook` action, your user or service role must allow the following actions:  
ssm:GetParameter
kms:Decrypt
Permission for the AWS Key Management Service (AWS KMS) `Decrypt` operation is only required if you use a customer managed key to encrypt the parameter for your integration.

**Input**  
Provide the information for the Automation integration you want to invoke.

------
#### [ YAML ]

```
action: "aws:invokeWebhook"
inputs: 
 IntegrationName: "exampleIntegration"
 Body: "Request body"
```

------
#### [ JSON ]

```
{
    "action": "aws:invokeWebhook",
    "inputs": {
        "IntegrationName": "exampleIntegration",
        "Body": "Request body"
    }
}
```

------

IntegrationName  
The name of the Automation integration. For example, `exampleIntegration`. The integration you specify must already exist.  
Type: String  
Required: Yes

Body  
The payload you want to send when your webhook integration is invoked.  
Type: String  
Required: NoOutput

Response  
The text received from the webhook provider response.

ResponseCode  
The HTTP status code received from the webhook provider response.

# `aws:invokeLambdaFunction` – Invoke an AWS Lambda function
<a name="automation-action-lamb"></a>

Invokes the specified AWS Lambda function.

**Note**  
Each `aws:invokeLambdaFunction` action can run up to a maximum duration of 300 seconds (5 minutes). You can limit the timeout by specifying the `timeoutSeconds` parameter for an `aws:invokeLambdaFunction` step.

**Note**  
The `aws:invokeLambdaFunction` action supports automatic throttling retry. For more information, see [Configuring automatic retry for throttled operations](automation-throttling-retry.md).

**Input**  
This action supports most invoked parameters for the Lambda service. For more information, see [Invoke](https://docs.aws.amazon.com/lambda/latest/dg/API_Invoke.html).

------
#### [ YAML ]

```
name: invokeMyLambdaFunction
action: aws:invokeLambdaFunction
maxAttempts: 3
timeoutSeconds: 120
onFailure: Abort
inputs:
  FunctionName: MyLambdaFunction
```

------
#### [ JSON ]

```
{
    "name": "invokeMyLambdaFunction",
    "action": "aws:invokeLambdaFunction",
    "maxAttempts": 3,
    "timeoutSeconds": 120,
    "onFailure": "Abort",
    "inputs": {
        "FunctionName": "MyLambdaFunction"
    }
}
```

------

FunctionName  
The name of the Lambda function. This function must exist.  
Type: String  
Required: Yes

Qualifier  
The function version or alias name.  
Type: String  
Required: No

InvocationType  
The invocation type. The default value is `RequestResponse`.  
Type: String  
Valid values: `Event` \$1 `RequestResponse` \$1 `DryRun`  
Required: No

LogType  
If the default value is `Tail`, the invocation type must be `RequestResponse`. Lambda returns the last 4 KB of log data produced by your Lambda function, base64-encoded.  
Type: String  
Valid values: `None` \$1 `Tail`  
Required: No

ClientContext  
The client-specific information.  
Required: No

InputPayload  
A YAML or JSON object that is passed to the first parameter of the handler. You can use this input to pass data to the function. This input provides more flexibility and support than the legacy `Payload` input. If you define both `InputPayload` and `Payload` for the action, `InputPayload` takes precedence and the `Payload` value is not used.  
Type: StringMap  
Required: No

Payload  
A JSON string that's passed to the first parameter of the handler. This can be used to pass input data to the function. We recommend using `InputPayload` input for added functionality.  
Type: String  
Required: NoOutput

StatusCode  
The HTTP status code.

FunctionError  
If present, it indicates that an error occurred while executing the function. Error details are included in the response payload.

LogResult  
The base64-encoded logs for the Lambda function invocation. Logs are present only if the invocation type is `RequestResponse`, and the logs were requested.

Payload  
The JSON representation of the object returned by the Lambda function. Payload is present only if the invocation type is `RequestResponse`.

The following is a portion from the `AWS-PatchInstanceWithRollback` runbook demonstrating how to reference outputs from the `aws:invokeLambdaFunction` action.

------
#### [ YAML ]

```
- name: IdentifyRootVolume
  action: aws:invokeLambdaFunction
  inputs:
    FunctionName: "IdentifyRootVolumeLambda-{{automation:EXECUTION_ID}}"
    Payload: '{"InstanceId": "{{InstanceId}}"}'
- name: PrePatchSnapshot
  action: aws:executeAutomation
  inputs:
    DocumentName: "AWS-CreateSnapshot"
    RuntimeParameters:
      VolumeId: "{{IdentifyRootVolume.Payload}}"
      Description: "ApplyPatchBaseline restoration case contingency"
```

------
#### [ JSON ]

```
{
    "name": "IdentifyRootVolume",
    "action": "aws:invokeLambdaFunction",
    "inputs": {
      "FunctionName": "IdentifyRootVolumeLambda-{{automation:EXECUTION_ID}}",
      "Payload": "{\"InstanceId\": \"{{InstanceId}}\"}"
    }
  },
  {
    "name": "PrePatchSnapshot",
    "action": "aws:executeAutomation",
    "inputs": {
      "DocumentName": "AWS-CreateSnapshot",
      "RuntimeParameters": {
        "VolumeId": "{{IdentifyRootVolume.Payload}}",
        "Description": "ApplyPatchBaseline restoration case contingency"
      }
    }
  }
```

------

# `aws:loop` – Iterate over steps in an automation
<a name="automation-action-loop"></a>

This action iterates over a subset of steps in an automation runbook. You can choose a `do while` or `for each` style loop. To construct a `do while` loop, use the `LoopCondition` input parameter. To construct a `for each` loop, use the `Iterators` and `IteratorDataType` input parameters. When using an `aws:loop` action, only specify either the `Iterators` or `LoopCondition` input parameter. The maximum number of iterations is 100.

The `onCancel` property can only be used for steps defined within a loop. The `onCancel` property isn't supported for the `aws:loop` action. The `onFailure` property can be used for an `aws:loop` action, however it will only be used if an unexpected error occurs causing the step to fail. If you define `onFailure` properties for the steps within a loop, the `aws:loop` action inherits those properties and reacts accordingly when a failure occurs.

**Examples**  
The following are examples of how to construct the different types of loop actions.

------
#### [ do while ]

```
name: RepeatMyLambdaFunctionUntilOutputIsReturned
action: aws:loop
inputs:
    Steps:
    - name: invokeMyLambda
        action: aws:invokeLambdaFunction
        inputs:
        FunctionName: LambdaFunctionName
        outputs:
        - Name: ShouldRetry
            Selector: $.Retry
            Type: Boolean
    LoopCondition:
        Variable: "{{ invokeMyLambda.ShouldRetry }}"
        BooleanEquals: true
    MaxIterations: 3
```

------
#### [ for each ]

```
name: stopAllInstancesWithWaitTime
action: aws:loop
inputs:
    Iterators: "{{ DescribeInstancesStep.InstanceIds }}"
    IteratorDataType: "String"
    Steps:
    - name: stopOneInstance
        action: aws:changeInstanceState
        inputs:
        InstanceIds:
            - "{{stopAllInstancesWithWaitTime.CurrentIteratorValue}}"
        CheckStateOnly: false
        DesiredState: stopped
    - name: wait10Seconds
        action: aws:sleep
        inputs:
        Duration: PT10S
```

------

**Input**  
The input is as follows.

Iterators  
The list of items for the steps to iterate over. The maximum number of iterators is 100.  
Type: StringList  
Required: No

IteratorDataType  
An optional parameter to specify the data type of the `Iterators`. A value for this parameter can be provided along with the `Iterators` input parameter. If you don’t specify a value for this parameter and `Iterators`, then you must specify a value for the `LoopCondition` parameter.  
Type: String  
Valid values: Boolean \$1 Integer \$1 String \$1 StringMap  
Default: String  
Required: No

LoopCondition  
Consists of a `Variable` and an operator condition to evaluate. If you don’t specify a value for this parameter, then you must specify values for the `Iterators` and `IteratorDataType` parameters. You can use complex operator evaluations by using a combination of `And`, `Not`, and `Or` operators. The condition is evaluated after the steps in the loop complete. If the condition is `true` and the `MaxIterations` value has not been reached, the steps in the loop run again. The operator conditions are as follows:  

**String operations**
+ StringEquals
+ EqualsIgnoreCase
+ StartsWith
+ EndsWith
+ Contains

**Numeric operations**
+ NumericEquals
+ NumericGreater
+ NumericLesser
+ NumericGreaterOrEquals
+ NumericLesser
+ NumericLesserOrEquals

**Boolean operation**
+ BooleanEquals
Type: StringMap  
Required: No

MaxIterations  
The maximum number of times the steps in the loop run. Once the value specified for this input is reached, the loop stops running even if the `LoopCondition` is still `true` or if there are objects remaining in the `Iterators` parameter.  
Type: Integer  
Valid values: 1 - 100  
Required: No

Steps  
The list of steps to run in the loop. These function like a nested runbook. Within these steps you can access the current iterator value for a `for each` loop using the syntax `{{loopStepName.CurrentIteratorValue}}`. You can also access an integer value of the current iteration for both loop types using the syntax `{{loopStepName.CurrentIteration}}`.  
Type: List of steps  
Required: YesOutput

CurrentIteration  
The current loop iteration as an integer. Iteration values start at 1.  
Type: Integer

CurrentIteratorValue  
The value of the current iterator as a string. This output is only present in `for each` loops.  
Type: String

# `aws:pause` – Pause an automation
<a name="automation-action-pause"></a>

This action pauses the automation. Once paused, the automation status is *Waiting*. To continue the automation, use the [SendAutomationSignal](https://docs.aws.amazon.com/systems-manager/latest/APIReference/API_SendAutomationSignal.html) API operation with the `Resume` signal type. We recommend using the `aws:sleep` or `aws:approve` action for more granular control of your workflows.

**Note**  
The default timeout for this action is 7 days (604800 seconds) and the maximum value is 30 days (2592000 seconds). You can limit or extend the timeout by specifying the `timeoutSeconds` parameter for an `aws:pause` step.

**Input**  
The input is as follows.

------
#### [ YAML ]

```
name: pauseThis
action: aws:pause
timeoutSeconds: 1209600
inputs: {}
```

------
#### [ JSON ]

```
{
    "name": "pauseThis",
    "action": "aws:pause",
    "timeoutSeconds": "1209600",
    "inputs": {}
}
```

------Output

None  


# `aws:runCommand` – Run a command on a managed instance
<a name="automation-action-runcommand"></a>

Runs the specified commands.

**Note**  
Automation only supports *output* of one AWS Systems Manager Run Command action. A runbook can include multiple Run Command actions, but output is supported for only one action at a time.

**Input**  
This action supports most send command parameters. For more information, see [SendCommand](https://docs.aws.amazon.com/systems-manager/latest/APIReference/API_SendCommand.html).

------
#### [ YAML ]

```
- name: checkMembership
  action: 'aws:runCommand'
  inputs:
    DocumentName: AWS-RunPowerShellScript
    InstanceIds:
      - '{{InstanceIds}}'
    Parameters:
      commands:
        - (Get-WmiObject -Class Win32_ComputerSystem).PartOfDomain
```

------
#### [ JSON ]

```
{
    "name": "checkMembership",
    "action": "aws:runCommand",
    "inputs": {
        "DocumentName": "AWS-RunPowerShellScript",
        "InstanceIds": [
            "{{InstanceIds}}"
        ],
        "Parameters": {
            "commands": [
                "(Get-WmiObject -Class Win32_ComputerSystem).PartOfDomain"
            ]
        }
    }
}
```

------

DocumentName  
If the Command type document is owned by you or AWS, specify the name of the document. If you're using a document shared with you by a different AWS account, specify the Amazon Resource Name (ARN) of the document. For more information about using shared documents, see [Using shared SSM documents](documents-ssm-sharing.md#using-shared-documents).  
Type: String  
Required: Yes

InstanceIds  
The instance IDs where you want the command to run. You can specify a maximum of 50 IDs.   
You can also use the pseudo parameter `{{RESOURCE_ID}}` in place of instance IDs to run the command on all instances in the target group. For more information about pseudo parameters, see [Using pseudo parameters when registering maintenance window tasks](maintenance-window-tasks-pseudo-parameters.md).  
Another alternative is to send commands to a fleet of instances by using the `Targets` parameter. The `Targets` parameter accepts Amazon Elastic Compute Cloud (Amazon EC2) tags. For more information about how to use the `Targets` parameter, see [Run commands at scale](send-commands-multiple.md).  
Type: StringList  
Required: No (If you don't specify InstanceIds or use the `{{RESOURCE_ID}}` pseudo parameter, then you must specify the `Targets` parameter.)

Targets  
An array of search criteria that targets instances by using a Key,Value combination that you specify. `Targets` is required if you don't provide one or more instance IDs in the call. For more information about how to use the `Targets` parameter, see [Run commands at scale](send-commands-multiple.md).  
Type: MapList (The schema of the map in the list must match the object.) For information, see [Target](https://docs.aws.amazon.com/systems-manager/latest/APIReference/API_Target.html) in the *AWS Systems Manager API Reference*.  
Required: No (If you don't specify `Targets`, then you must specify InstanceIds or use the `{{RESOURCE_ID}}` pseudo parameter.)  
Following is an example.  

```
- name: checkMembership
  action: aws:runCommand
  inputs:
    DocumentName: AWS-RunPowerShellScript
    Targets:
      - Key: tag:Stage
        Values:
          - Gamma
          - Beta
      - Key: tag-key
        Values:
          - Suite
    Parameters:
      commands:
        - (Get-WmiObject -Class Win32_ComputerSystem).PartOfDomain
```

```
{
    "name": "checkMembership",
    "action": "aws:runCommand",
    "inputs": {
        "DocumentName": "AWS-RunPowerShellScript",
        "Targets": [                   
            {
                "Key": "tag:Stage",
                "Values": [
                    "Gamma", "Beta"
                ]
            },
            {
                "Key": "tag:Application",
                "Values": [
                    "Suite"
                ]
            }
        ],
        "Parameters": {
            "commands": [
                "(Get-WmiObject -Class Win32_ComputerSystem).PartOfDomain"
            ]
        }
    }
}
```

Parameters  
The required and optional parameters specified in the document.  
Type: Map  
Required: No

CloudWatchOutputConfig  
Configuration options for sending command output to Amazon CloudWatch Logs. For more information about sending command output to CloudWatch Logs, see [Configuring Amazon CloudWatch Logs for Run Command](sysman-rc-setting-up-cwlogs.md).  
Type: StringMap (The schema of the map must match the object. For more information, see [CloudWatchOutputConfig](https://docs.aws.amazon.com/systems-manager/latest/APIReference/API_CloudWatchOutputConfig.html) in the *AWS Systems Manager API Reference*).  
Required: No  
Following is an example.  

```
- name: checkMembership
  action: aws:runCommand
  inputs:
    DocumentName: AWS-RunPowerShellScript
    InstanceIds:
      - "{{InstanceIds}}"
    Parameters:
      commands:
        - "(Get-WmiObject -Class Win32_ComputerSystem).PartOfDomain"
    CloudWatchOutputConfig:
      CloudWatchLogGroupName: CloudWatchGroupForSSMAutomationService
      CloudWatchOutputEnabled: true
```

```
{
    "name": "checkMembership",
    "action": "aws:runCommand",
    "inputs": {
        "DocumentName": "AWS-RunPowerShellScript",
        "InstanceIds": [
            "{{InstanceIds}}"
        ],
        "Parameters": {
            "commands": [
                "(Get-WmiObject -Class Win32_ComputerSystem).PartOfDomain"
            ]
        },
        "CloudWatchOutputConfig" : { 
                "CloudWatchLogGroupName": "CloudWatchGroupForSSMAutomationService",
                "CloudWatchOutputEnabled": true
        }
    }
}
```

Comment  
User-defined information about the command.  
Type: String  
Required: No

DocumentHash  
The hash for the document.  
Type: String  
Required: No

DocumentHashType  
The type of the hash.  
Type: String  
Valid values: `Sha256` \$1 `Sha1`  
Required: No

NotificationConfig  
The configurations for sending notifications.  
Required: No

OutputS3BucketName  
The name of the S3 bucket for command output responses. Your managed node must have permissions for the S3 bucket to successfully log output.  
Type: String  
Required: No

OutputS3KeyPrefix  
The prefix.  
Type: String  
Required: No

ServiceRoleArn  
The ARN of the AWS Identity and Access Management (IAM) role.  
Type: String  
Required: No

TimeoutSeconds  
The amount of time in seconds to wait for a command to deliver to the AWS Systems Manager SSM Agent on an instance. If the command isn't received by the SSM Agent on the instance before the value specified is reached, then the status of the command changes to `Delivery Timed Out`.  
Type: Integer  
Required: No  
Valid values: 30-2592000Output

CommandId  
The ID of the command.

Status  
The status of the command.

ResponseCode  
The response code of the command. If the document you run has more than 1 step, a value isn't returned for this output.

Output  
The output of the command. If you target a tag or multiple instances with your command, no output value is returned. You can use the `GetCommandInvocation` and `ListCommandInvocations` API operations to retrieve output for individual instances.

# `aws:runInstances` – Launch an Amazon EC2 instance
<a name="automation-action-runinstance"></a>

Launches a new Amazon Elastic Compute Cloud (Amazon EC2) instance.

**Note**  
The `aws:runInstances` action supports automatic throttling retry. For more information, see [Configuring automatic retry for throttled operations](automation-throttling-retry.md).

**Input**  
The action supports most API parameters. For more information, see the [RunInstances](https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_RunInstances.html) API documentation.

------
#### [ YAML ]

```
name: launchInstance
action: aws:runInstances
maxAttempts: 3
timeoutSeconds: 1200
onFailure: Abort
inputs:
  ImageId: ami-12345678
  InstanceType: t2.micro
  MinInstanceCount: 1
  MaxInstanceCount: 1
  IamInstanceProfileName: myRunCmdRole
  TagSpecifications:
  - ResourceType: instance
    Tags:
    - Key: LaunchedBy
      Value: SSMAutomation
    - Key: Category
      Value: HighAvailabilityFleetHost
```

------
#### [ JSON ]

```
{
   "name":"launchInstance",
   "action":"aws:runInstances",
   "maxAttempts":3,
   "timeoutSeconds":1200,
   "onFailure":"Abort",
   "inputs":{
      "ImageId":"ami-12345678",
      "InstanceType":"t2.micro",
      "MinInstanceCount":1,
      "MaxInstanceCount":1,
      "IamInstanceProfileName":"myRunCmdRole",
      "TagSpecifications":[
         {
            "ResourceType":"instance",
            "Tags":[
               {
                  "Key":"LaunchedBy",
                  "Value":"SSMAutomation"
               },
               {
                  "Key":"Category",
                  "Value":"HighAvailabilityFleetHost"
               }
            ]
         }
      ]
   }
}
```

------

AdditionalInfo  
Reserved.  
Type: String  
Required: No

BlockDeviceMappings  
The block devices for the instance.  
Type: MapList  
Required: No

ClientToken  
The identifier to ensure idempotency of the request.  
Type: String  
Required: No

DisableApiTermination  
Turns on or turns off instance API termination.  
Type: Boolean  
Required: No

EbsOptimized  
Turns on or turns off Amazon Elastic Block Store (Amazon EBS) optimization.  
Type: Boolean  
Required: No

IamInstanceProfileArn  
The Amazon Resource Name (ARN) of the AWS Identity and Access Management (IAM) instance profile for the instance.  
Type: String  
Required: No

IamInstanceProfileName  
The name of the IAM instance profile for the instance.  
Type: String  
Required: No

ImageId  
The ID of the Amazon Machine Image (AMI).  
Type: String  
Required: Yes

InstanceInitiatedShutdownBehavior  
Indicates whether the instance stops or terminates on system shutdown.  
Type: String  
Required: No

InstanceType  
The instance type.  
If an instance type value isn't provided, the m1.small instance type is used.
Type: String  
Required: No

KernelId  
The ID of the kernel.  
Type: String  
Required: No

KeyName  
The name of the key pair.  
Type: String  
Required: No

MaxInstanceCount  
The maximum number of instances to be launched.  
Type: String  
Required: No

MetadataOptions  
The metadata options for the instance. For more information, see [InstanceMetadataOptionsRequest](https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_InstanceMetadataOptionsRequest.html).  
Type: StringMap  
Required: No

MinInstanceCount  
The minimum number of instances to be launched.  
Type: String  
Required: No

Monitoring  
Turns on or turns off detailed monitoring.  
Type: Boolean  
Required: No

NetworkInterfaces  
The network interfaces.  
Type: MapList  
Required: No

Placement  
The placement for the instance.  
Type: StringMap  
Required: No

PrivateIpAddress  
The primary IPv4 address.  
Type: String  
Required: No

RamdiskId  
The ID of the RAM disk.  
Type: String  
Required: No

SecurityGroupIds  
The IDs of the security groups for the instance.  
Type: StringList  
Required: No

SecurityGroups  
The names of the security groups for the instance.  
Type: StringList  
Required: No

SubnetId  
The subnet ID.  
Type: String  
Required: No

TagSpecifications  
The tags to apply to the resources during launch. You can only tag instances and volumes at launch. The specified tags are applied to all instances or volumes that are created during launch. To tag an instance after it has been launched, use the [`aws:createTags` – Create tags for AWS resources](automation-action-createtag.md) action.  
Type: MapList (For more information, see [TagSpecification](https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_TagSpecification.html).)  
Required: No

UserData  
A script provided as a string literal value. If a literal value is entered, then it must be Base64-encoded.  
Type: String  
Required: NoOutput

InstanceIds  
The IDs of the instances.

InstanceStates  
The current state of the instance.

# `aws:sleep` – Delay an automation
<a name="automation-action-sleep"></a>

Delays an automation for a specified amount of time. This action uses the International Organization for Standardization (ISO) 8601 date and time format. For more information about this date and time format, see [ISO 8601](https://www.iso.org/iso-8601-date-and-time-format.html).

**Input**  
You can delay an automation for a specified duration. 

------
#### [ YAML ]

```
name: sleep
action: aws:sleep
inputs:
  Duration: PT10M
```

------
#### [ JSON ]

```
{
   "name":"sleep",
   "action":"aws:sleep",
   "inputs":{
      "Duration":"PT10M"
   }
}
```

------

You can also delay an automation until a specified date and time. If the specified date and time has passed, the action proceeds immediately. 

------
#### [ YAML ]

```
name: sleep
action: aws:sleep
inputs:
  Timestamp: '2020-01-01T01:00:00Z'
```

------
#### [ JSON ]

```
{
    "name": "sleep",
    "action": "aws:sleep",
    "inputs": {
        "Timestamp": "2020-01-01T01:00:00Z"
    }
}
```

------

**Note**  
Automation supports a maximum delay of 604799 seconds (7 days).

Duration  
An ISO 8601 duration. You can't specify a negative duration.   
Type: String  
Required: No

Timestamp  
An ISO 8601 timestamp. If you don't specify a value for this parameter, then you must specify a value for the `Duration` parameter.   
Type: String  
Required: NoOutput

None  


# `aws:updateVariable` – Updates a value for a runbook variable
<a name="automation-action-update-variable"></a>

This action updates a value for a runbook variable. The data type of the value must match the data type of the variable you want to update. Data type conversions aren't supported. The `onCancel` property isn't supported for the `aws:updateVariable` action.

**Input**  
The input is as follows.

------
#### [ YAML ]

```
name: updateStringList
action: aws:updateVariable
inputs:
    Name: variable:variable name
    Value:
    - "1"
    - "2"
```

------
#### [ JSON ]

```
{
    "name": "updateStringList",
    "action": "aws:updateVariable",
    "inputs": {
        "Name": "variable:variable name",
        "Value": ["1","2"]
    }
}
```

------

Name  
The name of the variable whose value you want to update. You must use the format `variable:variable name`  
Type: String  
Required: Yes

Value  
The new value to assign to the variable. The value must match the data type of the variable. Data type conversions aren't supported.  
Type: Boolean \$1 Integer \$1 MapList \$1 String \$1 StringList \$1 StringMap  
Required: Yes  
Constraints:  
+ MapList can contain a maximum number of 200 items.
+ Key lengths can be a minimum length of 1 and a maximum length of 50.
+ StringList can be a minimum number of 0 items and a maximum number of 50 items.
+ String lengths can be a minimum length of 1 and a maximum length of 512.Output

None  


# `aws:waitForAwsResourceProperty` – Wait on an AWS resource property
<a name="automation-action-waitForAwsResourceProperty"></a>

The `aws:waitForAwsResourceProperty` action allows your automation to wait for a specific resource state or event state before continuing the automation. For more examples of how to use this action, see [Additional runbook examples](automation-document-examples.md).

**Note**  
The default timeout value for this action is 3600 seconds (one hour). You can limit or extend the timeout by specifying the `timeoutSeconds` parameter for an `aws:waitForAwsResourceProperty` step. For more information and examples of how to use this action, see [Handling timeouts in runbooks](automation-handling-timeouts.md).

**Note**  
The `aws:waitForAwsResourceProperty` action supports automatic throttling retry. For more information, see [Configuring automatic retry for throttled operations](automation-throttling-retry.md).

**Input**  
Inputs are defined by the API operation that you choose.

------
#### [ YAML ]

```
action: aws:waitForAwsResourceProperty
inputs:
  Service: The official namespace of the service
  Api: The API operation or method name
  API operation inputs or parameters: A value
  PropertySelector: Response object
  DesiredValues:
  - Desired property value
```

------
#### [ JSON ]

```
{
  "action": "aws:waitForAwsResourceProperty",
  "inputs": {
    "Service":"The official namespace of the service",
    "Api":"The API operation or method name",
    "API operation inputs or parameters":"A value",
    "PropertySelector": "Response object",
    "DesiredValues": [
      "Desired property value"
    ]
  }
}
```

------

Service  
The AWS service namespace that contains the API operation that you want to run. For example, the namespace for AWS Systems Manager is `ssm`. The namespace for Amazon Elastic Compute Cloud (Amazon EC2) is `ec2`. You can view a list of supported AWS service namespaces in the [Available Services](https://docs.aws.amazon.com/cli/latest/reference/#available-services) section of the *AWS CLI Command Reference*.  
Type: String  
Required: Yes

Api  
The name of the API operation that you want to run. You can view the API operations (also called methods) by choosing a service in the left navigation on the following [Services Reference](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/index.html) page. Choose a method in the **Client** section for the service that you want to invoke. For example, all API operations (methods) for Amazon Relational Database Service (Amazon RDS) are listed on the following page: [Amazon RDS methods](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/rds.html).  
Type: String  
Required: Yes

API operation inputs  
One or more API operation inputs. You can view the available inputs (also called parameters) by choosing a service in the left navigation on the following [Services Reference](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/index.html) page. Choose a method in the **Client** section for the service that you want to invoke. For example, all methods for Amazon RDS are listed on the following page: [Amazon RDS methods](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/rds.html). Choose the [describe\$1db\$1instances](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/rds.html#RDS.Client.describe_db_instances) method and scroll down to see the available parameters, such as **DBInstanceIdentifier**, **Name**, and **Values**.  

```
inputs:
  Service: The official namespace of the service
  Api: The API operation name
  API input 1: A value
  API Input 2: A value
  API Input 3: A value
```

```
"inputs":{
      "Service":"The official namespace of the service",
      "Api":"The API operation name",
      "API input 1":"A value",
      "API Input 2":"A value",
      "API Input 3":"A value"
}
```
Type: Determined by chosen API operation  
Required: Yes

PropertySelector  
The JSONPath to a specific attribute in the response object. You can view the response objects by choosing a service in the left navigation on the following [Services Reference](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/index.html) page. Choose a method in the **Client** section for the service that you want to invoke. For example, all methods for Amazon RDS are listed on the following page: [Amazon RDS methods](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/rds.html). Choose the [describe\$1db\$1instances](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/rds.html#RDS.Client.describe_db_instances) method and scroll down to the **Response Structure** section. **DBInstances** is listed as a response object.  
Type: String  
Required: Yes

DesiredValues  
The expected status or state on which to continue the automation.  
Type: MapList, StringList  
Required: Yes

# Automation system variables
<a name="automation-variables"></a>

AWS Systems Manager Automation runbooks use the following variables. For an example of how these variables are used, view the JSON source of the `AWS-UpdateWindowsAmi` runbook. 

**To view the JSON source of the `AWS-UpdateWindowsAmi` runbook**

1. Open the AWS Systems Manager console at [https://console.aws.amazon.com/systems-manager/](https://console.aws.amazon.com/systems-manager/).

1. In the navigation pane, choose **Documents**.

1. In the document list, use either the Search bar or the numbers to the right of the Search bar to choose the runbook `AWS-UpdateWindowsAmi`.

1. Choose the **Content** tab. 

**System variables**  
Automation runbooks support the following system variables.


****  

| Variable | Details | 
| --- | --- | 
|  `global:ACCOUNT_ID`  |  The AWS account ID of the user or role in which Automation runs.  | 
|  `global:DATE`  |  The date (at run time) in the format yyyy-MM-dd.  | 
|  `global:DATE_TIME`  |  The date and time (at run time) in the format yyyy-MM-dd\$1HH.mm.ss.  | 
|  `global:AWS_PARTITION`  |  The partition that the resource is in. For standard AWS Regions, the partition is `aws`. For resources in other partitions, the partition is `aws-partitionname`. For example, the partition for resources in the AWS GovCloud (US-West) Region is `aws-us-gov`.  | 
|  `global:REGION`  |  The Region that the runbook is run in. For example, us-east-2.  | 

**Automation variables**  
Automation runbooks support the following automation variables.


****  

| Variable | Details | 
| --- | --- | 
|  `automation:EXECUTION_ID`  |  The unique identifier assigned to the current automation. For example, `1a2b3c-1a2b3c-1a2b3c-1a2b3c1a2b3c1a2b3c`.  | 

**Topics**
+ [Terminology](#automation-terms)
+ [Supported scenarios](#automation-variables-support)
+ [Unsupported scenarios](#automation-variables-unsupported)

## Terminology
<a name="automation-terms"></a>

The following terms describe how variables and parameters are resolved.


****  

| Term | Definition | Example | 
| --- | --- | --- | 
|  Constant ARN  |  A valid Amazon Resource Name (ARN) without variables.  |  `arn:aws:iam::123456789012:role/roleName`  | 
|  Runbook parameter  |  A parameter defined at the runbook level (for example, `instanceId`). The parameter is used in a basic string replace. Its value is supplied at Start Execution time.  |  <pre>{ <br />   "description": "Create Image Demo",<br />   "version": "0.3",<br />   "assumeRole": "Your_Automation_Assume_Role_ARN",<br />   "parameters":{ <br />      "instanceId": { <br />         "type": "String",<br />         "description": "Instance to create image from"<br />   }<br />}</pre>  | 
|  System variable  |  A general variable substituted into the runbook when any part of the runbook is evaluated.  |  <pre>"activities": [ <br />   { <br />      "id": "copyImage",<br />      "activityType": "AWS-CopyImage",<br />      "maxAttempts": 1,<br />      "onFailure": "Continue",<br />      "inputs": { <br />         "ImageName": "{{imageName}}",<br />         "SourceImageId": "{{sourceImageId}}",<br />         "SourceRegion": "{{sourceRegion}}",<br />         "Encrypted": true,<br />         "ImageDescription": "Test CopyImage Description created on {{global:DATE}}"<br />      }<br />   }<br />]</pre>  | 
|  Automation variable  |  A variable relating to the automation substituted into the runbook when any part of the runbook is evaluated.  |  <pre>{ <br />   "name": "runFixedCmds",<br />   "action": "aws:runCommand",<br />   "maxAttempts": 1,<br />   "onFailure": "Continue",<br />   "inputs": { <br />      "DocumentName": "AWS-RunPowerShellScript",<br />      "InstanceIds": [ <br />         "{{LaunchInstance.InstanceIds}}"<br />      ],<br />      "Parameters": { <br />         "commands": [ <br />            "dir",<br />            "date",<br />            "“{{outputFormat}}” -f “left”,”right”,”{{global:DATE}}”,”{{automation:EXECUTION_ID}}”<br />         ]<br />      }<br />   }<br />}</pre>  | 
|  Systems Manager Parameter  |  A variable defined within AWS Systems Manager Parameter Store. It can't be directly referenced in step input. Permissions might be required to access the parameter.  |  <pre><br />description: Launch new Windows test instance<br />schemaVersion: '0.3'<br />assumeRole: '{{AutomationAssumeRole}}'<br />parameters:<br />  AutomationAssumeRole:<br />    type: String<br />    default: ''<br />    description: >-<br />      (Required) The ARN of the role that allows Automation to perform the<br />      actions on your behalf. If no role is specified, Systems Manager<br />      Automation uses your IAM permissions to run this runbook.<br />  LatestAmi:<br />    type: String<br />    default: >-<br />      {{ssm:/aws/service/ami-windows-latest/Windows_Server-2016-English-Full-Base}}<br />    description: The latest Windows Server 2016 AMI queried from the public parameter.<br />mainSteps:<br />  - name: launchInstance<br />    action: 'aws:runInstances'<br />    maxAttempts: 3<br />    timeoutSeconds: 1200<br />    onFailure: Abort<br />    inputs:<br />      ImageId: '{{LatestAmi}}'<br />...</pre>  | 

## Supported scenarios
<a name="automation-variables-support"></a>


****  

| Scenario | Comments | Example | 
| --- | --- | --- | 
|  Constant ARN `assumeRole` at creation.  |  An authorization check is performed to verify that the calling user is permitted to pass the given `assumeRole`.  |  <pre>{<br />  "description": "Test all Automation resolvable parameters",<br />  "schemaVersion": "0.3",<br />  "assumeRole": "arn:aws:iam::123456789012:role/roleName",<br />  "parameters": { <br />  ...</pre>  | 
|  Runbook parameter supplied for `AssumeRole` when the automation is started.  |  Must be defined in the parameter list of the runbook.  |  <pre>{<br />  "description": "Test all Automation resolvable parameters",<br />  "schemaVersion": "0.3",<br />  "assumeRole": "{{dynamicARN}}",<br />  "parameters": {<br /> ...</pre>  | 
|  Value supplied for runbook parameter at start.  |  Customer supplies the value to use for a parameter. Any inputs supplied at start time need to be defined in the parameter list of the runbook.  |  <pre>...<br />"parameters": {<br />    "amiId": {<br />      "type": "String",<br />      "default": "ami-12345678",<br />      "description": "list of commands to run as part of first step"<br />    },<br />...</pre> Inputs to Start Automation Execution include : `{"amiId" : ["ami-12345678"] }`  | 
|  Systems Manager Parameter referenced within runbook content.  |  The variable exists within the customer's account, or is a publicly accessibly parameter, and the `AssumeRole` for the runbook has access to the variable. A check is performed at create time to confirm the `AssumeRole` has access. The parameter can't be directly referenced in step input.  |  <pre><br />...<br />parameters:<br />    LatestAmi:<br />    type: String<br />    default: >-<br />      {{ssm:/aws/service/ami-windows-latest/Windows_Server-2016-English-Full-Base}}<br />    description: The latest Windows Server 2016 AMI queried from the public parameter.<br />mainSteps:<br />  - name: launchInstance<br />    action: 'aws:runInstances'<br />    maxAttempts: 3<br />    timeoutSeconds: 1200<br />    onFailure: Abort<br />    inputs:<br />      ImageId: '{{LatestAmi}}'<br />...</pre>  | 
|  System variable referenced within step definition  |  A system variable is substituted into the runbook when the automation is started. The value injected into the runbook is relative to when the substitution occurs. That is, the value of a time variable injected at step 1 is different from the value injected at step 3 because of the time it takes to run the steps between. System variables don't need to be set in the parameter list of the runbook.  |  <pre>...<br />  "mainSteps": [<br />    {<br />      "name": "RunSomeCommands",<br />      "action": "aws:runCommand",<br />      "maxAttempts": 1,<br />      "onFailure": "Continue",<br />      "inputs": {<br />        "DocumentName": "AWS:RunPowerShell",<br />        "InstanceIds": ["{{LaunchInstance.InstanceIds}}"],<br />        "Parameters": {<br />            "commands" : [<br />                "echo {The time is now {{global:DATE_TIME}}}"<br />            ]<br />        }<br />    }<br />}, ... </pre>  | 
|  Automation variable referenced within step definition.  |  Automation variables don't need to be set in the parameter list of the runbook. The only supported Automation variable is **automation:EXECUTION\$1ID**.  |  <pre>...<br />"mainSteps": [<br />    {<br />      "name": "invokeLambdaFunction",<br />      "action": "aws:invokeLambdaFunction",<br />      "maxAttempts": 1,<br />      "onFailure": "Continue",<br />      "inputs": {<br />        "FunctionName": "Hello-World-LambdaFunction",<br /><br />"Payload" : "{ "executionId" : "{{automation:EXECUTION_ID}}" }"<br />      }<br />    }<br />... </pre>  | 
|  Refer to output from previous step within next step definition.  |  This is parameter redirection. The output of a previous step is referenced using the syntax `{{stepName.OutputName}}`. This syntax can't be used by the customer for runbook parameters. This is resolved when the referring step runs. The parameter isn't listed in the parameters of the runbook.  |  <pre>...<br />"mainSteps": [<br />    {<br />      "name": "LaunchInstance",<br />      "action": "aws:runInstances",<br />      "maxAttempts": 1,<br />      "onFailure": "Continue",<br />      "inputs": {<br />        "ImageId": "{{amiId}}",<br />        "MinInstanceCount": 1,<br />        "MaxInstanceCount": 2<br />      }<br />    },<br />    {<br />      "name":"changeState",<br />      "action": "aws:changeInstanceState",<br />      "maxAttempts": 1,<br />      "onFailure": "Continue",<br />      "inputs": {<br />        "InstanceIds": ["{{LaunchInstance.InstanceIds}}"],<br />        "DesiredState": "terminated"<br />      }<br />    }<br /><br />... </pre>  | 

## Unsupported scenarios
<a name="automation-variables-unsupported"></a>


****  

| Scenario | Comment | Example | 
| --- | --- | --- | 
|  Systems Manager Parameter supplied for `assumeRole` at create  |  Not supported.  |  <pre>...<br /><br />{<br />  "description": "Test all Automation resolvable parameters",<br />  "schemaVersion": "0.3",<br />  "assumeRole": "{{ssm:administratorRoleARN}}",<br />  "parameters": {<br /><br />... </pre>  | 
|  Systems Manager Parameter directly referenced in step input.  |  Returns `InvalidDocumentContent` exception at create time.  |  <pre><br />...<br />mainSteps:<br />  - name: launchInstance<br />    action: 'aws:runInstances'<br />    maxAttempts: 3<br />    timeoutSeconds: 1200<br />    onFailure: Abort<br />    inputs:<br />      ImageId: '{{ssm:/aws/service/ami-windows-latest/Windows_Server-2016-English-Full-Base}}'<br />...</pre>  | 
|  Variable step definition  |  The definition of a step in the runbook is constructed by variables.  |  <pre>...<br /><br />"mainSteps": [<br />    {<br />      "name": "LaunchInstance",<br />      "action": "aws:runInstances",<br />      "{{attemptModel}}": 1,<br />      "onFailure": "Continue",<br />      "inputs": {<br />        "ImageId": "ami-12345678",<br />        "MinInstanceCount": 1,<br />        "MaxInstanceCount": 2<br />      }<br /><br />...<br /><br />User supplies input : { "attemptModel" : "minAttempts" } </pre>  | 
|  Cross referencing runbook parameters  |  The user supplies an input parameter at start time, which is a reference to another parameter in the runbook.  |  <pre>...<br />"parameters": {<br />    "amiId": {<br />      "type": "String",<br />      "default": "ami-7f2e6015",<br />      "description": "list of commands to run as part of first step"<br />    },<br />    "alternateAmiId": {<br />      "type": "String",<br />      "description": "The alternate AMI to try if this first fails".<br /><br />"default" : "{{amiId}}"<br />    },<br /><br />... </pre>  | 
|  Multi-level expansion  |  The runbook defines a variable that evaluates to the name of a variable. This sits within the variable delimiters (that is *\$1\$1 \$1\$1*) and is expanded to the value of that variable/parameter.  |  <pre>...<br />  "parameters": {<br />    "firstParameter": {<br />      "type": "String",<br />      "default": "param2",<br />      "description": "The parameter to reference"<br />    },<br />    "secondParameter": {<br />      "type": "String",<br />      "default" : "echo {Hello world}",<br />      "description": "What to run"<br />    }<br />  },<br />  "mainSteps": [{<br />      "name": "runFixedCmds",<br />      "action": "aws:runCommand",<br />      "maxAttempts": 1,<br />      "onFailure": "Continue",<br />      "inputs": {<br />        "DocumentName": "AWS-RunPowerShellScript",<br /><br />"InstanceIds" : "{{LaunchInstance.InstanceIds}}",<br />        "Parameters": {<br />          "commands": [ "{{ {{firstParameter}} }}"]<br /><br />}<br /><br />...<br /><br />Note: The customer intention here would be to run a command of "echo {Hello world}" </pre>  | 
|  Referencing output from a runbook step that is a different variable type  |  The user references the output from a preceding runbook step within a subsequent step. The output is a variable type that doesn't meet the requirements of the action in the subsequent step.  |  <pre>...<br />mainSteps:<br />- name: getImageId<br />  action: aws:executeAwsApi<br />  inputs:<br />    Service: ec2<br />    Api: DescribeImages<br />    Filters:  <br />    - Name: "name"<br />      Values: <br />      - "{{ImageName}}"<br />  outputs:<br />  - Name: ImageIdList<br />    Selector: "$.Images"<br />    Type: "StringList"<br />- name: copyMyImages<br />  action: aws:copyImage<br />  maxAttempts: 3<br />  onFailure: Abort<br />  inputs:<br />    SourceImageId: {{getImageId.ImageIdList}}<br />    SourceRegion: ap-northeast-2<br />    ImageName: Encrypted Copies of LAMP base AMI in ap-northeast-2<br />    Encrypted: true <br />... <br />Note: You must provide the type required by the Automation action. <br />In this case, aws:copyImage requires a "String" type variable but the preceding step outputs a "StringList" type variable.<br />                                        </pre>  | 

# Creating your own runbooks
<a name="automation-documents"></a>

An Automation runbook defines the *actions* that Systems Manager performs on your managed instances and other AWS resources when an automation runs. Automation is a tool in AWS Systems Manager. A runbook contains one or more steps that run in sequential order. Each step is built around a single action. Output from one step can be used as input in a later step. 

The process of running these actions and their steps is called the *automation*.

Action types supported for runbooks let you automate a wide variety of operations in your AWS environment. For example, using the `executeScript` action type, you can embed a python or PowerShell script directly in your runbook. (When you create a custom runbook, you can add your script inline, or attach it from an S3 bucket or from your local machine.) You can automate management of your AWS CloudFormation resources by using the `createStack` and `deleteStack` action types. In addition, using the `executeAwsApi` action type, a step can run *any *API operation in any AWS service, including creating or deleting AWS resources, starting other processes, initiating notifications, and many more. 

For a list of all 20 supported action types for Automation, see [Systems Manager Automation actions reference](automation-actions.md).

AWS Systems Manager Automation provides several runbooks with pre-defined steps that you can use to perform common tasks like restarting one or more Amazon Elastic Compute Cloud (Amazon EC2) instances or creating an Amazon Machine Image (AMI). You can also create your own runbooks and share them with other AWS accounts, or make them public for all Automation users.

Runbooks are written using YAML or JSON. Using the **Document Builder** in the Systems Manager Automation console, however, you can create a runbook without having to author in native JSON or YAML.

**Important**  
If you run an automation workflow that invokes other services by using an AWS Identity and Access Management (IAM) service role, be aware that the service role must be configured with permission to invoke those services. This requirement applies to all AWS Automation runbooks (`AWS-*` runbooks) such as the `AWS-ConfigureS3BucketLogging`, `AWS-CreateDynamoDBBackup`, and `AWS-RestartEC2Instance` runbooks, to name a few. This requirement also applies to any custom Automation runbooks you create that invoke other AWS services by using actions that call other services. For example, if you use the `aws:executeAwsApi`, `aws:createStack`, or `aws:copyImage` actions, configure the service role with permission to invoke those services. You can give permissions to other AWS services by adding an IAM inline policy to the role. For more information, see [(Optional) Add an Automation inline policy or customer managed policy to invoke other AWS services](automation-setup-iam.md#add-inline-policy).

For information about the actions that you can specify in a runbook, see [Systems Manager Automation actions reference](automation-actions.md).

For information about using the AWS Toolkit for Visual Studio Code to create runbooks, see [Working with Systems Manager Automation documents](https://docs.aws.amazon.com/toolkit-for-vscode/latest/userguide/systems-manager-automation-docs.html) in the *AWS Toolkit for Visual Studio Code User Guide*.

For information about using the visual designer to create a custom runbook, see [Visual design experience for Automation runbooks](automation-visual-designer.md). 

**Contents**
+ [Visual design experience for Automation runbooks](automation-visual-designer.md)
  + [Overview of the visual design experience interface](visual-designer-interface-overview.md)
    + [Actions browser](visual-designer-interface-overview.md#visual-designer-actions)
    + [Canvas](visual-designer-interface-overview.md#visual-designer-canvas)
    + [Form](visual-designer-interface-overview.md#visual-designer-form)
    + [Keyboard shortcuts](visual-designer-interface-overview.md#visual-designer-keyboard-shortcuts)
  + [Using the visual design experience](visual-designer-use.md)
    + [Create a runbook workflow](visual-designer-use.md#visual-designer-create-runbook-workflow)
    + [Design a runbook](visual-designer-use.md#visual-designer-build)
    + [Update your runbook](visual-designer-use.md#visual-designer-update-runbook)
    + [Export your runbook](visual-designer-use.md#visual-designer-export-runbook)
  + [Configuring inputs and outputs for your actions](visual-designer-action-inputs-outputs.md)
    + [Provide input data for an action](visual-designer-action-inputs-outputs.md#providing-input)
    + [Define output data for an action](visual-designer-action-inputs-outputs.md#defining-output)
  + [Error handling with the visual design experience](visual-designer-error-handling.md)
    + [Retry action on error](visual-designer-error-handling.md#retry-actions)
    + [Timeouts](visual-designer-error-handling.md#timeout-seconds)
    + [Failed actions](visual-designer-error-handling.md#failure-actions)
    + [Canceled actions](visual-designer-error-handling.md#cancel-actions)
    + [Critical actions](visual-designer-error-handling.md#critical-actions)
    + [Ending actions](visual-designer-error-handling.md#end-actions)
  + [Tutorial: Create a runbook using the visual design experience](visual-designer-tutorial.md)
    + [Step 1: Navigate to the visual design experience](visual-designer-tutorial.md#navigate-console)
    + [Step 2: Create a workflow](visual-designer-tutorial.md#create-workflow)
    + [Step 3: Review the auto-generated code](visual-designer-tutorial.md#view-generated-code)
    + [Step 4: Run your new runbook](visual-designer-tutorial.md#use-tutorial-runbook)
    + [Step 5: Clean up](visual-designer-tutorial.md#cleanup-tutorial-runbook)
+ [Authoring Automation runbooks](automation-authoring-runbooks.md)
  + [Identify your use case](automation-authoring-runbooks.md#automation-authoring-runbooks-use-case)
  + [Set up your development environment](automation-authoring-runbooks.md#automation-authoring-runbooks-environment)
  + [Develop runbook content](automation-authoring-runbooks.md#automation-authoring-runbooks-developing-content)
  + [Example 1: Creating parent-child runbooks](automation-authoring-runbooks-parent-child-example.md)
    + [Create the child runbook](automation-authoring-runbooks-parent-child-example.md#automation-authoring-runbooks-child-runbook)
    + [Create the parent runbook](automation-authoring-runbooks-parent-child-example.md#automation-authoring-runbooks-parent-runbook)
  + [Example 2: Scripted runbook](automation-authoring-runbooks-scripted-example.md)
  + [Additional runbook examples](automation-document-examples.md)
    + [Deploy VPC architecture and Microsoft Active Directory domain controllers](automation-document-architecture-deployment-example.md)
    + [Restore a root volume from the latest snapshot](automation-document-instance-recovery-example.md)
    + [Create an AMI and cross-Region copy](automation-document-backup-maintenance-example.md)
+ [Creating input parameters that populate AWS resources](populating-input-parameters.md)
+ [Using Document Builder to create runbooks](automation-document-builder.md)
  + [Create a runbook using Document Builder](automation-document-builder.md#create-runbook)
  + [Create a runbook that runs scripts](automation-document-builder.md#create-runbook-scripts)
+ [Using scripts in runbooks](automation-document-script-considerations.md)
  + [Permissions for using runbooks](automation-document-script-considerations.md#script-permissions)
  + [Adding scripts to runbooks](automation-document-script-considerations.md#adding-scripts)
  + [Script constraints for runbooks](automation-document-script-considerations.md#script-constraints)
+ [Using conditional statements in runbooks](automation-branch-condition.md)
  + [Working with the `aws:branch` action](automation-branch-condition.md#branch-action-explained)
    + [Creating an `aws:branch` step in a runbook](automation-branch-condition.md#create-branch-action)
      + [About creating the output variable](automation-branch-condition.md#branch-action-output)
    + [Example `aws:branch` runbooks](automation-branch-condition.md#branch-runbook-examples)
    + [Creating complex branching automations with operators](automation-branch-condition.md#branch-operators)
  + [Examples of how to use conditional options](automation-branch-condition.md#conditional-examples)
+ [Using action outputs as inputs](automation-action-outputs-inputs.md)
  + [Using JSONPath in runbooks](automation-action-outputs-inputs.md#automation-action-json-path)
+ [Creating webhook integrations for Automation](creating-webhook-integrations.md)
  + [Creating integrations (console)](creating-webhook-integrations.md#creating-integrations-console)
  + [Creating integrations (command line)](creating-webhook-integrations.md#creating-integrations-commandline)
  + [Creating webhooks for integrations](creating-webhook-integrations.md#creating-webhooks)
+ [Handling timeouts in runbooks](automation-handling-timeouts.md)

# Visual design experience for Automation runbooks
<a name="automation-visual-designer"></a>

AWS Systems Manager Automation provides a low-code visual design experience that helps you create automation runbooks. The visual design experience provides a drag-and-drop interface with the option to add your own code so you can create and edit runbooks more easily. With the visual design experience, you can do the following:
+ Control conditional statements.
+ Control how input and output is filtered or transformed for each action.
+ Configure error handling.
+ Prototype new runbooks.
+ Use your prototype runbooks as the starting point for local development with the AWS Toolkit for Visual Studio Code.

When you create or edit a runbook, you can access the visual design experience from the [Automation console](https://console.aws.amazon.com/systems-manager/automation/home?region=us-east-1#/). As you create a runbook, the visual design experience validates your work and auto-generates code. You can review the generated code, or export it for local development. When you're finished, you can save your runbook, run it, and examine the results in the Systems Manager Automation console. 

**Topics**
+ [Interface overview](visual-designer-interface-overview.md)
+ [Using the visual design experience](visual-designer-use.md)
+ [Configure inputs and outputs](visual-designer-action-inputs-outputs.md)
+ [Error handling with the visual design experience](visual-designer-error-handling.md)
+ [Tutorial: Create a runbook using the visual design experience](visual-designer-tutorial.md)

# Overview of the visual design experience interface
<a name="visual-designer-interface-overview"></a>

The visual design experience for Systems Manager Automation is a low-code visual workflow designer that helps you create automation runbooks.

Get to know the visual design experience with an overview of the interface components:

![\[Visual design experience components\]](http://docs.aws.amazon.com/systems-manager/latest/userguide/images/visual_designer_overview.png)

+ The **Actions** browser contains the **Actions**, **AWS APIs**, and **Runbooks** tabs.
+ The *canvas* is where you drag and drop actions into your workflow graph, change the order of actions, and select actions to configure or view.
+ The **Form** panel is where you can view and edit the properties of any action that you selected on the canvas. Select the **Content** toggle to view the YAML or JSON for your runbook, with the currently selected action highlighted. 

**Info** links open a panel with contextual information when you need help. These panels also include links to related topics in the Systems Manager Automation documentation. 

## Actions browser
<a name="visual-designer-actions"></a>

From the **Actions** browser, you can select actions to drag and drop into your workflow graph. You can search all actions using the search field at the top of the **Actions** browser. The **Actions** browser contains the following tabs:
+ The **Actions** tab provides a list of automation actions that you can drag and drop into your runbook's workflow graph in the canvas.
+ The **AWS APIs** tab provides a list of AWS APIs that you can drag and drop into your runbook's workflow graph in the canvas.
+ The **Runbooks** tab provides several ready-to-use, reusable runbooks as building blocks that you can use for a variety of use cases. For example, you can use runbooks to perform common remediation tasks on Amazon EC2 instances in your workflow without having to re-create the same actions.

![\[Visual design experience actions browser\]](http://docs.aws.amazon.com/systems-manager/latest/userguide/images/visual_designer_actions_multi_view.png)


## Canvas
<a name="visual-designer-canvas"></a>

After you choose an action to add to your automation, drag it to the canvas and drop it into your workflow graph. You can also drag and drop actions to move them to different places in your runbook's workflow. If your workflow is complex, you might not be able to view all of it in the canvas panel. Use the controls at the top of the canvas to zoom in or out. To view different parts of a workflow, you can drag the workflow graph in the canvas. 

Drag an action from the **Actions** browser, and drop it into your runbook's workflow graph. A line shows where it will be placed in your workflow. To change the order of an action, you can drag it to a different place in your workflow. The new action has been added to your workflow, and its code is auto-generated.

![\[Visual design experience canvas\]](http://docs.aws.amazon.com/systems-manager/latest/userguide/images/visual_designer_canvas.png)


## Form
<a name="visual-designer-form"></a>

After you add an action to your runbook workflow, you can configure it to meet your use case. Choose the action that you want to configure, and you will see its parameters and options in the **Form** panel. You can also see the YAML or JSON code by choosing the **Content** toggle. The code associated with the action you have selected is highlighted.

![\[Visual design experience form panel\]](http://docs.aws.amazon.com/systems-manager/latest/userguide/images/visual_designer_form.png)


![\[Visual design experience content panel\]](http://docs.aws.amazon.com/systems-manager/latest/userguide/images/visual_designer_content.png)


## Keyboard shortcuts
<a name="visual-designer-keyboard-shortcuts"></a>

The visual design experience supports the keyboard shortcuts shown in the following table.


| Keyboard shortcut | Function | 
| --- | --- | 
| Ctrl\$1Z | Undo the last operation. | 
| Ctrl\$1Shift\$1Z | Redo the last operation. | 
| Alt\$1C | Center the workflow in the canvas. | 
| Backspace | Remove all selected states. | 
| Delete | Remove all selected states. | 
| Ctrl\$1D | Duplicate the selected state. | 

# Using the visual design experience
<a name="visual-designer-use"></a>

Learn to create, edit and run runbook workflows using the visual design experience. After your workflow is ready, you can save it or export it. You can also use the visual design experience for rapid prototyping. 

## Create a runbook workflow
<a name="visual-designer-create-runbook-workflow"></a>

1. Sign in to the [Systems Manager Automation console](https://console.aws.amazon.com/systems-manager/automation/home?region=us-east-1#/).

1. Choose **Create runbook**.

1. In the **Name** box, enter a name for your runbook, for example, `MyNewRunbook`.

1. Next to the **Design** and **Code** toggle, select the pencil icon and enter a name for your runbook.

You can now design a workflow for your new runbook.

## Design a runbook
<a name="visual-designer-build"></a>

 To design a runbook workflow using the visual design experience, you drag an automation action from the **Actions** browser into the canvas, placing it where you want it in your runbook's workflow. You can also re-order actions in your workflow by dragging them to a different location. As you drag an action onto the canvas, a line appears wherever you can drop the action in your workflow. After an action is dropped onto the canvas, its code is auto-generated and added inside your runbook's content.

If you know the name of the action you want to add, use the search box at the top of the **Actions** browser to find the action.

After you drop an action onto the canvas, configure it using the **Form** panel on the right. This panel contains the **General**, **Inputs**, **Outputs**, and **Configuration** tabs for each automation action or API action that you place on the canvas. For example, the **General** tab consists of the following sections:
+ The **Step name** identifies the step. Specify a unique value for the step name.
+ The **Description** helps you describe what the action is doing in your runbook's workflow.

The **Inputs** tab contains fields that vary based on the action. For example, the `aws:executeScript` automation action consists of the following sections:
+ The **Runtime** is the language to use for running the provided script.
+ The **Handler** is the name of your function. You must ensure that the function defined in the handler has two parameters: `events` and `context`. The PowerShell runtime doesn't support this parameter. 
+ The **Script** is an embedded script that you want to run during the workflow.
+ (Optional) The **Attachment** is for standalone scripts or .zip files that can be invoked by the action. This parameter is required for JSON runbooks.

The **Outputs** tab helps you specify the values that you want to output from an action. You can reference output values in later actions of your workflow, or generate output from actions for logging purposes. Not all actions will have an **Outputs** tab because not all actions support outputs. For example, the `aws:pause` action doesn't support outputs. For actions that do support outputs, the **Outputs** tab consists of the following sections:
+ The **Name** is the name to be used for the output value. You can reference outputs in later actions of your workflow.
+ The **Selector** is a JSONPath expression string beginning with `"$."` that is used to select one or more components within a JSON element.
+ The **Type** is the data type for the output value. For example, a `String` or `Integer` data type.

The **Configuration** tab contains properties and options that all automation actions can use. The action consists of the following sections:
+ The **Max attempts** property is the number of times an action retries if it fails.
+ The **Timeout seconds** property specifies the timeout value for an action.
+ The **Is critical** property determines if the action failure stops the entire automation.
+ The **Next step** property determines which action the automation goes to next in the runbook.
+ The **On failure** property determines which action the automation goes to next in the runbook if the action fails.
+ The **On cancel** property determines which action the automation goes to next in the runbook if the action is canceled by a user.

To delete an action, you can use backspace, the toolbar above the canvas, or right-click and choose **Delete action**.

As your workflow grows, it might not fit in the canvas. To help make the workflow fit in the canvas, try one of the following options: 
+ Use the controls on the side panels to resize or close the panels.
+ Use the toolbar at the top of the canvas to zoom the workflow graph in or out.

## Update your runbook
<a name="visual-designer-update-runbook"></a>

You can update an existing runbook workflow by creating a new version of your runbook. Updates to your runbooks can be made by using the visual design experience, or by editing the code directly. To update an existing runbook, use the following procedure:

1. Sign in to the [Systems Manager Automation console](https://console.aws.amazon.com/systems-manager/automation/home?region=us-east-1#/).

1. Choose the runbook that you want to update.

1. Choose **Create new version**.

1. The visual design experience has two panes: A code pane and a visual workflow pane. Choose **Design** in the visual workflow pane to edit your workflow with the visual design experience. When you're done, choose **Create new version** to save your changes and exit.

1. (Optional) Use the code pane to edit the runbook content in YAML or JSON.

## Export your runbook
<a name="visual-designer-export-runbook"></a>

To export your runbook's workflow YAML or JSON code, and also a graph of your workflow, use the following procedure: 

1. Choose your runbook in the **Documents** console.

1. Choose **Create new version**.

1. In the **Actions** dropdown, choose whether you want to export the graph or runbook, and which format you prefer.

# Configuring inputs and outputs for your actions
<a name="visual-designer-action-inputs-outputs"></a>

Each automation action responds based on input that it receives. In most cases, you then pass output to the subsequent actions. In the visual design experience, you can configure an action's input and output data in the **Inputs** and **Outputs** tabs of the **Form** panel.

For detailed information about how to define and use output for automation actions, see [Using action outputs as inputs](automation-action-outputs-inputs.md). 

## Provide input data for an action
<a name="providing-input"></a>

Each automation action has one or more inputs that you must provide a value for. The value you provide for an action's input is determined by the data type and format that's accepted by the action. For example, the `aws:sleep` actions requires an ISO 8601 formatted string value for the `Duration` input.

Generally, you use actions in your runbook's workflow that return output that you want to use in subsequent actions. It's important to make sure your input values are correct to avoid errors in your runbook's workflow. Input values are also important because they determine whether the action returns the expected output. For example, when using the `aws:executeAwsApi` action, you want to make sure that you're providing the right value for the API operation.

## Define output data for an action
<a name="defining-output"></a>

Some automation actions return output after performing their defined operations. Actions that return output either have predefined outputs, or allow you to define the outputs yourself. For example, the `aws:createImage` action has predefined outputs that return an `ImageId` and `ImageState`. Comparatively, with the `aws:executeAwsApi` action, you can define the outputs you that want from the specified API operation. As a result, you can return one or more values from a single API operation to use in subsequent actions.

Defining your own outputs for an automation action requires that you specify a name of the output, the data type, and the output value. To continue using the `aws:executeAwsApi` action as an example, let's say you're calling the `DescribeInstances` API operation from Amazon EC2. In this example, you want to return, or output, the `State` of an Amazon EC2 instance and branch your runbook's workflow based on the output. You choose to name the output **InstanceState**, and use the **String** data type. 

The process to define the actual value of the output differs, depending on the action. For example, if you're using the `aws:executeScript` action, you must use `return` statements in your functions to provide data to your outputs. With other actions like `aws:executeAwsApi`, `aws:waitForAwsResourceProperty`, and `aws:assertAwsResourceProperty`, a `Selector` is required. The `Selector`, or `PropertySelector` as some actions refer to it, is a JSONPath string that is used to process the JSON response from an API operation. It's important to understand how the JSON response object from an API operation is structured so you can select the correct value for your output. Using the `DescribeInstances` API operation mentioned earlier, see the following example JSON response:

```
{
  "reservationSet": {
    "item": {
      "reservationId": "r-1234567890abcdef0",
      "ownerId": 123456789012,
      "groupSet": "",
      "instancesSet": {
        "item": {
          "instanceId": "i-1234567890abcdef0",
          "imageId": "ami-bff32ccc",
          "instanceState": {
            "code": 16,
            "name": "running"
          },
          "privateDnsName": "ip-192-168-1-88.eu-west-1.compute.internal",
          "dnsName": "ec2-54-194-252-215.eu-west-1.compute.amazonaws.com",
          "reason": "",
          "keyName": "my_keypair",
          "amiLaunchIndex": 0,
          "productCodes": "",
          "instanceType": "t2.micro",
          "launchTime": "2018-05-08T16:46:19.000Z",
          "placement": {
            "availabilityZone": "eu-west-1c",
            "groupName": "",
            "tenancy": "default"
          },
          "monitoring": {
            "state": "disabled"
          },
          "subnetId": "subnet-56f5f000",
          "vpcId": "vpc-11112222",
          "privateIpAddress": "192.168.1.88",
          "ipAddress": "54.194.252.215",
          "sourceDestCheck": true,
          "groupSet": {
            "item": {
              "groupId": "sg-e4076000",
              "groupName": "SecurityGroup1"
            }
          },
          "architecture": "x86_64",
          "rootDeviceType": "ebs",
          "rootDeviceName": "/dev/xvda",
          "blockDeviceMapping": {
            "item": {
              "deviceName": "/dev/xvda",
              "ebs": {
                "volumeId": "vol-1234567890abcdef0",
                "status": "attached",
                "attachTime": "2015-12-22T10:44:09.000Z",
                "deleteOnTermination": true
              }
            }
          },
          "virtualizationType": "hvm",
          "clientToken": "xMcwG14507example",
          "tagSet": {
            "item": {
              "key": "Name",
              "value": "Server_1"
            }
          },
          "hypervisor": "xen",
          "networkInterfaceSet": {
            "item": {
              "networkInterfaceId": "eni-551ba000",
              "subnetId": "subnet-56f5f000",
              "vpcId": "vpc-11112222",
              "description": "Primary network interface",
              "ownerId": 123456789012,
              "status": "in-use",
              "macAddress": "02:dd:2c:5e:01:69",
              "privateIpAddress": "192.168.1.88",
              "privateDnsName": "ip-192-168-1-88.eu-west-1.compute.internal",
              "sourceDestCheck": true,
              "groupSet": {
                "item": {
                  "groupId": "sg-e4076000",
                  "groupName": "SecurityGroup1"
                }
              },
              "attachment": {
                "attachmentId": "eni-attach-39697adc",
                "deviceIndex": 0,
                "status": "attached",
                "attachTime": "2018-05-08T16:46:19.000Z",
                "deleteOnTermination": true
              },
              "association": {
                "publicIp": "54.194.252.215",
                "publicDnsName": "ec2-54-194-252-215.eu-west-1.compute.amazonaws.com",
                "ipOwnerId": "amazon"
              },
              "privateIpAddressesSet": {
                "item": {
                  "privateIpAddress": "192.168.1.88",
                  "privateDnsName": "ip-192-168-1-88.eu-west-1.compute.internal",
                  "primary": true,
                  "association": {
                    "publicIp": "54.194.252.215",
                    "publicDnsName": "ec2-54-194-252-215.eu-west-1.compute.amazonaws.com",
                    "ipOwnerId": "amazon"
                  }
                }
              },
              "ipv6AddressesSet": {
                "item": {
                  "ipv6Address": "2001:db8:1234:1a2b::123"
                }
              }
            }
          },
          "iamInstanceProfile": {
            "arn": "arn:aws:iam::123456789012:instance-profile/AdminRole",
            "id": "ABCAJEDNCAA64SSD123AB"
          },
          "ebsOptimized": false,
          "cpuOptions": {
            "coreCount": 1,
            "threadsPerCore": 1
          }
        }
      }
    }
  }
}
```

In the JSON response object, the instance `State` is nested in an `Instances` object, which is nested in the `Reservations` object. To return the value of the instance `State`, use the following string for the `Selector` so the value can be used in our output: **\$1.Reservations[0].Instances[0].State.Name**.

To reference an output value in subsequent actions of your runbook's workflow, the following format is used: `{{ StepName.NameOfOutput }}`. For example, **\$1\$1 GetInstanceState.InstanceState \$1\$1**. In the visual design experience, you can choose output values to use in subsequent actions using the dropdown for the input. When using outputs in subsequent actions, the data type of the output must match the data type for the input. In this example, the `InstanceState` output is a `String`. Therefore, to use the value in a subsequent action's input, the input must accept a `String`.

# Error handling with the visual design experience
<a name="visual-designer-error-handling"></a>

By default, when an action reports an error, Automation stops the runbook's workflow entirely. This is because the default value for the `onFailure` property on all actions is `Abort`. You can configure how Automation handles errors in your runbook's workflow. Even if you have configured error handling, some errors might still cause an automation to fail. For more information, see [Troubleshooting Systems Manager Automation](automation-troubleshooting.md). In the visual design experience, you configure error handling in the **Configuration** panel.

![\[Error handling options\]](http://docs.aws.amazon.com/systems-manager/latest/userguide/images/visual_designer_error_handling.png)


## Retry action on error
<a name="retry-actions"></a>

To retry an action in case of an error, specify a value for the **Max attempts** property. The default value is 1. If you specify a value greater than 1, the action isn't considered to have failed until all of the retry attempts have failed.

## Timeouts
<a name="timeout-seconds"></a>

You can configure a timeout for actions to set the maximum number of seconds your action can run before it fails. To configure a timeout, enter the number of seconds that your action should wait before the action fails in the **Timeout seconds** property. If the timeout is reached and the action has a value of `Max attempts` that is greater than 1, the step isn't considered to have timed out until the retries complete.

## Failed actions
<a name="failure-actions"></a>

By default, when an action fails, Automation stops the runbook's workflow entirely. You can modify this behavior by specifying an alternative value for the **On failure** property of the actions in your runbook. If you want the workflow to continue to the next step in the runbook, choose **Continue**. If you want the workflow to jump to a different subsequent step in the runbook, choose **Step** and then enter the name of the step.

## Canceled actions
<a name="cancel-actions"></a>

By default, when an action is canceled by a user, Automation stops the runbook's workflow entirely. You can modify this behavior by specifying an alternative value for the **On cancel** property of the actions in your runbook. If you want the workflow to jump to a different subsequent step in the runbook, choose **Step** and then enter the name of the step.

## Critical actions
<a name="critical-actions"></a>

You can designate an action as *critical*, meaning it determines the overall reporting status of your automation. If a step with this designation fails, Automation reports the final status as `Failed` regardless of the success of other actions. To configure an action as critical, leave the default value as **True** for the **Is critical** property.

## Ending actions
<a name="end-actions"></a>

The **Is end** property stops an automation at the end of the specified action. The default value for this property is `false`. If you configure this property for an action, the automation stops whether the action succeeds or fails. This property is most often used with `aws:branch` actions to handle unexpected or undefined input values. The following example shows a runbook that is expecting an instance state of either `running`, `stopping`, or `stopped`. If an instance is in a different state, the automation ends.

![\[Visual design experience is end example\]](http://docs.aws.amazon.com/systems-manager/latest/userguide/images/visual_designer_is_end_example.png)


# Tutorial: Create a runbook using the visual design experience
<a name="visual-designer-tutorial"></a>

In this tutorial, you will learn the basics of working with the visual design experience provided by Systems Manager Automation. In the visual design experience, you can create a runbook that uses multiple actions. You use the drag and drop feature to arrange actions on the canvas. You also search for, select, and configure these actions. Then, you can view the auto-generated YAML code for your runbook's workflow, exit the visual design experience, run the runbook, and review the execution details.

This tutorial also shows you how to update the runbook and view the new version. At the end of the tutorial, you perform a clean-up step and delete your runbook.

After you complete this tutorial, you'll know how to use the visual design experience to create a runbook. You'll also know how to update, run, and delete your runbook.

**Note**  
Before you start this tutorial, make sure to complete [Setting up Automation](automation-setup.md).

**Topics**
+ [Step 1: Navigate to the visual design experience](#navigate-console)
+ [Step 2: Create a workflow](#create-workflow)
+ [Step 3: Review the auto-generated code](#view-generated-code)
+ [Step 4: Run your new runbook](#use-tutorial-runbook)
+ [Step 5: Clean up](#cleanup-tutorial-runbook)

## Step 1: Navigate to the visual design experience
<a name="navigate-console"></a>

1. Sign in to the [Systems Manager Automation console](https://console.aws.amazon.com/systems-manager/automation/home?region=us-east-1#/).

1. Choose **Create automation runbook**.

## Step 2: Create a workflow
<a name="create-workflow"></a>

In the visual design experience, a workflow is a graphical representation of your runbook on the canvas. You can use the visual design experience to define, configure, and examine the individual actions of your runbook.

**To create a workflow**

1. Next to the **Design** and **Code** toggle, select the pencil icon and enter a name for your runbook. For this tutorial, enter **VisualDesignExperienceTutorial**.  
![\[Visual design experience name your runbook\]](http://docs.aws.amazon.com/systems-manager/latest/userguide/images/visual_designer_tutorial_name.png)

1. In the **Document attributes** section of the **Form** panel, expand the **Input parameters** dropdown, and select **Add a parameter**.

   1. In the **Parameter name** field, enter **InstanceId**.

   1. In the **Type** dropdown, choose **AWS::EC2::Instance**.

   1. Select the **Required** toggle.  
![\[Create a parameter for your runbook\]](http://docs.aws.amazon.com/systems-manager/latest/userguide/images/visual_designer_actions_tutorial_parameter.png)

1. In the **AWS APIs** browser, enter **DescribeInstances** in the search bar.

1. Drag an **Amazon EC2 – DescribeInstances** action to the empty canvas.

1. For **Step name**, enter a value. For this tutorial, you can use the name **GetInstanceState**.  
![\[Choose an Amazon EC2 describe instances API action.\]](http://docs.aws.amazon.com/systems-manager/latest/userguide/images/visual_designer_tutorial_api_action.png)

   1. Expand the **Additional inputs** dropdown, and in the **Input name** field, enter **InstanceIds**.

   1. Choose the **Inputs** tab.

   1. In the **Input value** field, choose the **InstanceId** document input. This references the value of the input parameter that you created at the beginning of the procedure. Since the **InstanceIds** input for the `DescribeInstances` action accepts `StringList` values, you must wrap the **InstanceId** input in square brackets. The YAML for the **Input value** should match the following: **['\$1\$1 InstanceId \$1\$1']**.

   1. In the **Outputs** tab, select **Add an output** and enter **InstanceState** in the **Name** field.

   1. In the **Selector** field, enter **\$1.Reservations[0].Instances[0].State.Name**.

   1. In the **Type** dropdown, choose **String**.

1. Drag a **Branch** action from the **Actions** browser, and drop it below the **`GetInstanceState`** step. 

1. For **Step name**, enter a value. For this tutorial, use the name `BranchOnInstanceState`.

   To define the branching logic, do the following:

   1. Choose the **`Branch`** state on the canvas. Then, under **Inputs** and **Choices**, select the pencil icon to edit **Rule \$11**.

   1. Choose **Add conditions**.

   1. In the **Conditions for rule \$11** dialog box, choose the **GetInstanceState.InstanceState** step output from the **Variable** dropdown.

   1. For **Operator**, choose **is equal to**.

   1. For **Value**, choose **String** from the dropdown list. Enter **stopped**.  
![\[Define a condition for a branch action.\]](http://docs.aws.amazon.com/systems-manager/latest/userguide/images/visual_designer_tutorial_condition.png)

   1. Select **Save conditions**.

   1. Choose **Add new choice rule**.

   1. Choose **Add conditions** for **Rule \$12**.

   1. In the **Conditions for rule \$12** dialog box, choose the **GetInstanceState.InstanceState** step output from the **Variable** dropdown.

   1. For **Operator**, choose **is equal to**.

   1. For **Value**, choose **String** from the dropdown list. Enter **stopping**.

   1. Select **Save conditions**.

   1. Choose **Add new choice rule**.

   1. For **Rule \$13**, choose **Add conditions**.

   1. In the **Conditions for rule \$13** dialog box, choose the **GetInstanceState.InstanceState** step output from the **Variable** dropdown.

   1. For **Operator**, choose **is equal to**.

   1. For **Value**, choose **String** from the dropdown list. Enter **running**.

   1. Select **Save conditions**.

   1. In the **Default rule**, choose **Go to end** for the **Default step**.

1. Drag a **Change an instance state** action to the empty **Drag action here** box under the **\$1\$1 GetInstanceState.InstanceState \$1\$1 == "stopped"** condition.

   1. For the **Step name**, enter **StartInstance**.

   1. In the **Inputs** tab, under **Instance IDs**, choose the **InstanceId** document input value from the dropdown.

   1. For the **Desired state**, specify **`running`**.

1. Drag a **Wait on AWS resource** action to the empty **Drag action here** box under the **\$1\$1 GetInstanceState.InstanceState \$1\$1 == "stopping"** condition.

1. For **Step name**, enter a value. For this tutorial, use the name `WaitForInstanceStop`.

   1. For the **Service** field, choose **Amazon EC2**.

   1. For the **API** field, choose **DescribeInstances**.

   1. For the **Property selector** field, enter **\$1.Reservations[0].Instances[0].State.Name**.

   1. For the **Desired values** parameter, enter **`["stopped"]`**.

   1. In the **Configuration** tab of the **WaitForInstanceStop** action, choose **StartInstance** from the **Next step** dropdown.

1. Drag a **Run command on instances** action to the empty **Drag action here** box under the **\$1\$1 GetInstanceState.InstanceState \$1\$1 == "running"** condition.

1. For the **Step name**, enter **SayHello**.

   1. In the **Inputs** tab, enter **AWS-RunShellScript** for the **Document name** parameter.

   1. For **InstanceIds**, choose the **InstanceId** document input value from the dropdown.

   1. Expand the **Additional inputs** dropdown, and in the **Input name** dropdown, choose **Parameters**.

   1. In the **Input value** field, enter **`{"commands": "echo 'Hello World'"}`**.

1. Review the completed runbook in the canvas and select **Create runbook** to save the tutorial runbook.  
![\[Review and create the runbook.\]](http://docs.aws.amazon.com/systems-manager/latest/userguide/images/visual_designer_tutorial_complete.png)

## Step 3: Review the auto-generated code
<a name="view-generated-code"></a>

As you drag and drop actions from the **Actions** browser onto the canvas, the visual design experience automatically composes the YAML or JSON content of your runbook in real-time. You can view and edit this code. To view the auto-generated code, select **Code** for the **Design** and **Code** toggle.

## Step 4: Run your new runbook
<a name="use-tutorial-runbook"></a>

After creating your runbook, you can run the automation.

**To run your new automation runbook**

1. Open the AWS Systems Manager console at [https://console.aws.amazon.com/systems-manager/](https://console.aws.amazon.com/systems-manager/).

1. In the navigation pane, choose **Automation**, and then choose **Execute automation**.

1. In the **Automation document** list, choose a runbook. Choose one or more options in the **Document categories** pane to filter SSM documents according to their purpose. To view a runbook that you own, choose the **Owned by me** tab. To view a runbook that is shared with your account, choose the **Shared with me** tab. To view all runbooks, choose the **All documents** tab.
**Note**  
You can view information about a runbook by choosing the runbook name.

1. In the **Document details** section, verify that **Document version** is set to the version that you want to run. The system includes the following version options: 
   + **Default version at runtime** – Choose this option if the Automation runbook is updated periodically and a new default version is assigned.
   + **Latest version at runtime** – Choose this option if the Automation runbook is updated periodically, and you want to run the version that was most recently updated.
   + **1 (Default)** – Choose this option to run the first version of the document, which is the default.

1. Choose **Next**.

1. In the **Execute automation runbook** section, choose **Simple execution**.

1. In the **Input parameters** section, specify the required inputs. Optionally, you can choose an IAM service role from the **AutomationAssumeRole** list.

1. (Optional) Choose an Amazon CloudWatch alarm to apply to your automation for monitoring. To attach a CloudWatch alarm to your automation, the IAM principal that starts the automation must have permission for the `iam:createServiceLinkedRole` action. For more information about CloudWatch alarms, see [Using Amazon CloudWatch alarms](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/AlarmThatSendsEmail.html). If your alarm activates, the automation is stopped. If you use AWS CloudTrail, you will see the API call in your trail. 

1. Choose **Execute**. 

## Step 5: Clean up
<a name="cleanup-tutorial-runbook"></a>

**To delete your runbook**

1. Open the AWS Systems Manager console at [https://console.aws.amazon.com/systems-manager/](https://console.aws.amazon.com/systems-manager/).

1. In the navigation pane, choose **Documents**.

1. Select the **Owned by me** tab.

1. Locate the **VisualDesignExperienceTutorial** runbook.

1. Select the button on the document card page, and then choose **Delete document** from the **Actions** dropdown.

# Authoring Automation runbooks
<a name="automation-authoring-runbooks"></a>

Each runbook in Automation, a tool in AWS Systems Manager, defines an automation. Automation runbooks define the actions that are performed during an automation. In the runbook content, you define the input parameters, outputs, and actions that Systems Manager performs on your managed instances and AWS resources. 

Automation includes several pre-defined runbooks that you can use to perform common tasks like restarting one or more Amazon Elastic Compute Cloud (Amazon EC2) instances or creating an Amazon Machine Image (AMI). However, your use cases might extend beyond the capabilities of the pre-defined runbooks. If this is the case, you can create your own runbooks and modify them to your needs.

A runbook consists of automation actions, parameters for those actions, and input parameters that you specify. A runbook's content is written in either YAML or JSON. If you're not familiar with either YAML or JSON, we recommend using the visual designer, or learning more about either markup language before attempting to author your own runbook. For more information about the visual designer, see [Visual design experience for Automation runbooks](automation-visual-designer.md).

The following sections will help you author your first runbook.

## Identify your use case
<a name="automation-authoring-runbooks-use-case"></a>

The first step in authoring a runbook is identifying your use case. For example, you scheduled the `AWS-CreateImage` runbook to run daily on all of your production Amazon EC2 instances. At the end of the month, you decide you have more images than are necessary for recovery points. Going forward, you want to automatically delete the oldest AMI of an Amazon EC2 instance when a new AMI is created. To accomplish this, you create a new runbook that does the following:

1. Runs the `aws:createImage` action and specifies the instance ID in the image description.

1. Runs the `aws:waitForAwsResourceProperty` action to poll the state of the image until it's `available`.

1. After the image state is `available`, the `aws:executeScript` action runs a custom Python script that gathers the IDs of all images associated with your Amazon EC2 instance. The script does this by filtering, using the instance ID in the image description you specified at creation. Then, the script sorts the list of image IDs based on the `creationDate` of the image and outputs the ID of the oldest AMI.

1. Lastly, the `aws:deleteImage` action runs to delete the oldest AMI using the ID from the output of the previous step.

In this scenario, you were already using the `AWS-CreateImage` runbook but found that your use case required greater flexibility. This is a common situation because there can be overlap between runbooks and automation actions. As a result, you might have to adjust which runbooks or actions you use to address your use case.

For example, the `aws:executeScript` and `aws:invokeLambdaFunction` actions both allow you to run custom scripts as part of your automation. To choose between them, you might prefer `aws:invokeLambdaFunction` because of the additional supported runtime languages. However, you might prefer `aws:executeScript` because it allows you to author your script content directly in YAML runbooks and provide script content as attachments for JSON runbooks. You might also consider `aws:executeScript` to be simpler in terms of AWS Identity and Access Management (IAM) setup. Because it uses the permissions provided in the `AutomationAssumeRole`, `aws:executeScript` doesn't require an additional AWS Lambda function execution role.

In any given scenario, one action might provide more flexibility, or added functionality, over another. Therefore, we recommend that you review the available input parameters for the runbook or action you want to use to determine which best fits your use case and preferences.

## Set up your development environment
<a name="automation-authoring-runbooks-environment"></a>

After you've identified your use case and the pre-defined runbooks or automation actions you want to use in your runbook, it's time to set up your development environment for the content of your runbook. To develop your runbook content, we recommend using the AWS Toolkit for Visual Studio Code instead of the Systems Manager Documents console. 

The Toolkit for VS Code is an open-source extension for Visual Studio Code (VS Code) that offers more features than the Systems Manager Documents console. Helpful features include schema validation for both YAML and JSON, snippets for automation action types, and auto-complete support for various options in both YAML and JSON. 

For more information about installing the Toolkit for VS Code, see [Installing the AWS Toolkit for Visual Studio Code](https://docs.aws.amazon.com/toolkit-for-vscode/latest/userguide/setup-toolkit.html). For more information about using the Toolkit for VS Code to develop runbooks, see [Working with Systems Manager Automation documents](https://docs.aws.amazon.com/toolkit-for-vscode/latest/userguide/systems-manager-automation-docs.html) in the *AWS Toolkit for Visual Studio Code User Guide*.

## Develop runbook content
<a name="automation-authoring-runbooks-developing-content"></a>

With your use case identified and environment set up, you're ready to develop the content for your runbook. Your use case and preferences will largely dictate the automation actions or runbooks you use in your runbook content. Some actions support only a subset of input parameters when compared to another action that allows you to accomplish a similar task. Other actions have specific outputs, such as `aws:createImage`, where some actions allow you to define your own outputs, such as `aws:executeAwsApi`. 

If you're unsure how to use a particular action in your runbook, we recommend reviewing the corresponding entry for the action in the [Systems Manager Automation actions reference](automation-actions.md). We also recommend reviewing the content of pre-defined runbooks to see real-world examples of how these actions are used. For more examples of real-world applications of runbooks, see [Additional runbook examples](automation-document-examples.md).

To demonstrate the differences in simplicity and flexibility that runbook content provides, the following tutorials provide an example of how to patch groups of Amazon EC2 instances in stages:
+ [Example 1: Creating parent-child runbooks](automation-authoring-runbooks-parent-child-example.md) – In this example, two runbooks are used in a parent-child relationship. The parent runbook initiates a rate control automation of the child runbook. 
+ [Example 2: Scripted runbook](automation-authoring-runbooks-scripted-example.md) – This example demonstrates how you can accomplish the same tasks of Example 1 by condensing the content into a single runbook and using scripts in your runbook.

# Example 1: Creating parent-child runbooks
<a name="automation-authoring-runbooks-parent-child-example"></a>

The following example demonstrates how to create two runbooks that patch tagged groups of Amazon Elastic Compute Cloud (Amazon EC2) instances in stages. These runbooks are used in a parent-child relationship with the parent runbook used to initiate a rate control automation of the child runbook. For more information about rate control automations, see [Run automated operations at scale](running-automations-scale.md). For more information about the automation actions used in this example, see the [Systems Manager Automation actions reference](automation-actions.md).

## Create the child runbook
<a name="automation-authoring-runbooks-child-runbook"></a>

This example runbook addresses the following scenario. Emily is a Systems Engineer at AnyCompany Consultants, LLC. She needs to configure patching for groups of Amazon Elastic Compute Cloud (Amazon EC2) instances that host primary and secondary databases. Applications access these databases 24 hours a day, so one of the database instances must always be available. 

She decides that patching the instances in stages is the best approach. The primary group of database instances will be patched first, followed by the secondary group of database instances. Also, to avoid incurring additional costs by leaving instances running that were previously stopped, Emily wants the patched instances to be returned to their original state before the patching occurred. 

Emily identifies the primary and secondary groups of database instances by the tags associated with the instances. She decides to create a parent runbook that starts a rate control automation of a child runbook. By doing that, she can target the tags associated with the primary and secondary groups of database instances and manage the concurrency of the child automations. After reviewing the available Systems Manager (SSM) documents for patching, she chooses the `AWS-RunPatchBaseline` document. By using this SSM document, her colleagues can review the associated patch compliance information after the patching operation completes.

To start creating her runbook content, Emily reviews the available automation actions and begins authoring the content for the child runbook as follows:

1. First, she provides values for the schema and description of the runbook, and defines the input parameters for the child runbook.

   By using the `AutomationAssumeRole` parameter, Emily and her colleagues can use an existing IAM role that allows Automation to perform the actions in the runbook on their behalf. Emily uses the `InstanceId` parameter to determine the instance that should be patched. Optionally, the `Operation`, `RebootOption`, and `SnapshotId` parameters can be used to provide values to document parameters for `AWS-RunPatchBaseline`. To prevent invalid values from being provided to those document parameters, she defines the `allowedValues` as needed.

------
#### [ YAML ]

   ```
   schemaVersion: '0.3'
   description: 'An example of an Automation runbook that patches groups of Amazon EC2 instances in stages.'
   assumeRole: '{{AutomationAssumeRole}}'
   parameters:
     AutomationAssumeRole:
       type: String
       description: >-
         '(Optional) The Amazon Resource Name (ARN) of the IAM role that allows Automation to perform the
         actions on your behalf. If no role is specified, Systems Manager
         Automation uses your IAM permissions to operate this runbook.'
       default: ''
     InstanceId:
       type: String
       description: >-
         '(Required) The instance you want to patch.'
     SnapshotId:
       type: String
       description: '(Optional) The snapshot ID to use to retrieve a patch baseline snapshot.'
       default: ''
     RebootOption:
       type: String
       description: '(Optional) Reboot behavior after a patch Install operation. If you choose NoReboot and patches are installed, the instance is marked as non-compliant until a subsequent reboot and scan.'
       allowedValues:
         - NoReboot
         - RebootIfNeeded
       default: RebootIfNeeded
     Operation:
       type: String
       description: '(Optional) The update or configuration to perform on the instance. The system checks if patches specified in the patch baseline are installed on the instance. The install operation installs patches missing from the baseline.'
       allowedValues:
         - Install
         - Scan
       default: Install
   ```

------
#### [ JSON ]

   ```
   {
      "schemaVersion":"0.3",
      "description":"An example of an Automation runbook that patches groups of Amazon EC2 instances in stages.",
      "assumeRole":"{{AutomationAssumeRole}}",
      "parameters":{
         "AutomationAssumeRole":{
            "type":"String",
            "description":"(Optional) The Amazon Resource Name (ARN) of the IAM role that allows Automation to perform the actions on your behalf. If no role is specified, Systems Manager Automation uses your IAM permissions to operate this runbook.",
            "default":""
         },
         "InstanceId":{
            "type":"String",
            "description":"(Required) The instance you want to patch."
         },
         "SnapshotId":{
            "type":"String",
            "description":"(Optional) The snapshot ID to use to retrieve a patch baseline snapshot.",
            "default":""
         },
         "RebootOption":{
            "type":"String",
            "description":"(Optional) Reboot behavior after a patch Install operation. If you choose NoReboot and patches are installed, the instance is marked as non-compliant until a subsequent reboot and scan.",
            "allowedValues":[
               "NoReboot",
               "RebootIfNeeded"
            ],
            "default":"RebootIfNeeded"
         },
         "Operation":{
            "type":"String",
            "description":"(Optional) The update or configuration to perform on the instance. The system checks if patches specified in the patch baseline are installed on the instance. The install operation installs patches missing from the baseline.",
            "allowedValues":[
               "Install",
               "Scan"
            ],
            "default":"Install"
         }
      }
   },
   ```

------

1. With the top-level elements defined, Emily proceeds with authoring the actions that make up the `mainSteps` of the runbook. The first step outputs the current state of the target instance specified in the `InstanceId` input parameter using the `aws:executeAwsApi` action. The output of this action is used in later actions.

------
#### [ YAML ]

   ```
   mainSteps:
     - name: getInstanceState
       action: 'aws:executeAwsApi'
       onFailure: Abort
       inputs:
         inputs:
         Service: ec2
         Api: DescribeInstances
         InstanceIds:
           - '{{InstanceId}}'
       outputs:
         - Name: instanceState
           Selector: '$.Reservations[0].Instances[0].State.Name'
           Type: String
       nextStep: branchOnInstanceState
   ```

------
#### [ JSON ]

   ```
   "mainSteps":[
         {
            "name":"getInstanceState",
            "action":"aws:executeAwsApi",
            "onFailure":"Abort",
            "inputs":{
               "inputs":null,
               "Service":"ec2",
               "Api":"DescribeInstances",
               "InstanceIds":[
                  "{{InstanceId}}"
               ]
            },
            "outputs":[
               {
                  "Name":"instanceState",
                  "Selector":"$.Reservations[0].Instances[0].State.Name",
                  "Type":"String"
               }
            ],
            "nextStep":"branchOnInstanceState"
         },
   ```

------

1. Rather than manually starting and keeping track of the original state of every instance that needs to be patched, Emily uses the output from the previous action to branch the automation based on the state of the target instance. This allows the automation to run different steps depending on the conditions defined in the `aws:branch` action and improves the overall efficiency of the automation without manual intervention.

   If the instance state is already `running`, the automation proceeds with patching the instance with the `AWS-RunPatchBaseline` document using the `aws:runCommand` action.

   If the instance state is `stopping`, the automation polls for the instance to reach the `stopped` state using the `aws:waitForAwsResourceProperty` action, starts the instance using the `executeAwsApi` action, and polls for the instance to reach a `running` state before patching the instance.

   If the instance state is `stopped`, the automation starts the instance and polls for the instance to reach a `running` state before patching the instance using the same actions.

------
#### [ YAML ]

   ```
   - name: branchOnInstanceState
       action: 'aws:branch'
       onFailure: Abort
       inputs:
         Choices:
           - NextStep: startInstance
              Variable: '{{getInstanceState.instanceState}}'
              StringEquals: stopped
            - NextStep: verifyInstanceStopped
              Variable: '{{getInstanceState.instanceState}}'
              StringEquals: stopping
            - NextStep: patchInstance
              Variable: '{{getInstanceState.instanceState}}'
              StringEquals: running
       isEnd: true
     - name: startInstance
       action: 'aws:executeAwsApi'
       onFailure: Abort
       inputs:
         Service: ec2
         Api: StartInstances
         InstanceIds:
           - '{{InstanceId}}'
       nextStep: verifyInstanceRunning
     - name: verifyInstanceRunning
       action: 'aws:waitForAwsResourceProperty'
       timeoutSeconds: 120
       inputs:
         Service: ec2
         Api: DescribeInstances
         InstanceIds:
           - '{{InstanceId}}'
         PropertySelector: '$.Reservations[0].Instances[0].State.Name'
         DesiredValues:
           - running
       nextStep: patchInstance
     - name: verifyInstanceStopped
       action: 'aws:waitForAwsResourceProperty'
       timeoutSeconds: 120
       inputs:
         Service: ec2
         Api: DescribeInstances
         InstanceIds:
           - '{{InstanceId}}'
         PropertySelector: '$.Reservations[0].Instances[0].State.Name'
         DesiredValues:
           - stopped
         nextStep: startInstance
     - name: patchInstance
       action: 'aws:runCommand'
       onFailure: Abort
       timeoutSeconds: 5400
       inputs:
         DocumentName: 'AWS-RunPatchBaseline'
         InstanceIds: 
         - '{{InstanceId}}'
         Parameters:
           SnapshotId: '{{SnapshotId}}'
           RebootOption: '{{RebootOption}}'
           Operation: '{{Operation}}'
   ```

------
#### [ JSON ]

   ```
   {
            "name":"branchOnInstanceState",
            "action":"aws:branch",
            "onFailure":"Abort",
            "inputs":{
               "Choices":[
                  {
                     "NextStep":"startInstance",
                     "Variable":"{{getInstanceState.instanceState}}",
                     "StringEquals":"stopped"
                  },
                  {
                     "Or":[
                        {
                           "Variable":"{{getInstanceState.instanceState}}",
                           "StringEquals":"stopping"
                        }
                     ],
                     "NextStep":"verifyInstanceStopped"
                  },
                  {
                     "NextStep":"patchInstance",
                     "Variable":"{{getInstanceState.instanceState}}",
                     "StringEquals":"running"
                  }
               ]
            },
            "isEnd":true
         },
         {
            "name":"startInstance",
            "action":"aws:executeAwsApi",
            "onFailure":"Abort",
            "inputs":{
               "Service":"ec2",
               "Api":"StartInstances",
               "InstanceIds":[
                  "{{InstanceId}}"
               ]
            },
            "nextStep":"verifyInstanceRunning"
         },
         {
            "name":"verifyInstanceRunning",
            "action":"aws:waitForAwsResourceProperty",
            "timeoutSeconds":120,
            "inputs":{
               "Service":"ec2",
               "Api":"DescribeInstances",
               "InstanceIds":[
                  "{{InstanceId}}"
               ],
               "PropertySelector":"$.Reservations[0].Instances[0].State.Name",
               "DesiredValues":[
                  "running"
               ]
            },
            "nextStep":"patchInstance"
         },
         {
            "name":"verifyInstanceStopped",
            "action":"aws:waitForAwsResourceProperty",
            "timeoutSeconds":120,
            "inputs":{
               "Service":"ec2",
               "Api":"DescribeInstances",
               "InstanceIds":[
                  "{{InstanceId}}"
               ],
               "PropertySelector":"$.Reservations[0].Instances[0].State.Name",
               "DesiredValues":[
                  "stopped"
               ],
               "nextStep":"startInstance"
            }
         },
         {
            "name":"patchInstance",
            "action":"aws:runCommand",
            "onFailure":"Abort",
            "timeoutSeconds":5400,
            "inputs":{
               "DocumentName":"AWS-RunPatchBaseline",
               "InstanceIds":[
                  "{{InstanceId}}"
               ],
               "Parameters":{
                  "SnapshotId":"{{SnapshotId}}",
                  "RebootOption":"{{RebootOption}}",
                  "Operation":"{{Operation}}"
               }
            }
         },
   ```

------

1. After the patching operation completes, Emily wants the automation to return the target instance to the same state it was in before the automation started. She does this by again using the output from the first action. The automation branches based on the original state of the target instance using the `aws:branch` action. If the instance was previously in any state other than `running`, the instance is stopped. Otherwise, if the instance state is `running`, the automation ends.

------
#### [ YAML ]

   ```
   - name: branchOnOriginalInstanceState
       action: 'aws:branch'
       onFailure: Abort
       inputs:
         Choices:
           - NextStep: stopInstance
             Not: 
               Variable: '{{getInstanceState.instanceState}}'
               StringEquals: running
       isEnd: true
     - name: stopInstance
       action: 'aws:executeAwsApi'
       onFailure: Abort
       inputs:
         Service: ec2
         Api: StopInstances
         InstanceIds:
           - '{{InstanceId}}'
   ```

------
#### [ JSON ]

   ```
   {
            "name":"branchOnOriginalInstanceState",
            "action":"aws:branch",
            "onFailure":"Abort",
            "inputs":{
               "Choices":[
                  {
                     "NextStep":"stopInstance",
                     "Not":{
                        "Variable":"{{getInstanceState.instanceState}}",
                        "StringEquals":"running"
                     }
                  }
               ]
            },
            "isEnd":true
         },
         {
            "name":"stopInstance",
            "action":"aws:executeAwsApi",
            "onFailure":"Abort",
            "inputs":{
               "Service":"ec2",
               "Api":"StopInstances",
               "InstanceIds":[
                  "{{InstanceId}}"
               ]
            }
         }
      ]
   }
   ```

------

1. Emily reviews the completed child runbook content and creates the runbook in the same AWS account and AWS Region as the target instances. Now she's ready to continue with the creation of the parent runbook's content. The following is the completed child runbook content.

------
#### [ YAML ]

   ```
   schemaVersion: '0.3'
   description: 'An example of an Automation runbook that patches groups of Amazon EC2 instances in stages.'
   assumeRole: '{{AutomationAssumeRole}}'
   parameters:
     AutomationAssumeRole:
       type: String
       description: >-
         '(Optional) The Amazon Resource Name (ARN) of the IAM role that allows Automation to perform the
         actions on your behalf. If no role is specified, Systems Manager
         Automation uses your IAM permissions to operate this runbook.'
       default: ''
     InstanceId:
       type: String
       description: >-
         '(Required) The instance you want to patch.'
     SnapshotId:
       type: String
       description: '(Optional) The snapshot ID to use to retrieve a patch baseline snapshot.'
       default: ''
     RebootOption:
       type: String
       description: '(Optional) Reboot behavior after a patch Install operation. If you choose NoReboot and patches are installed, the instance is marked as non-compliant until a subsequent reboot and scan.'
       allowedValues:
         - NoReboot
         - RebootIfNeeded
       default: RebootIfNeeded
     Operation:
       type: String
       description: '(Optional) The update or configuration to perform on the instance. The system checks if patches specified in the patch baseline are installed on the instance. The install operation installs patches missing from the baseline.'
       allowedValues:
         - Install
         - Scan
       default: Install
   mainSteps:
     - name: getInstanceState
       action: 'aws:executeAwsApi'
       onFailure: Abort
       inputs:
         inputs:
         Service: ec2
         Api: DescribeInstances
         InstanceIds:
           - '{{InstanceId}}'
       outputs:
         - Name: instanceState
           Selector: '$.Reservations[0].Instances[0].State.Name'
           Type: String
       nextStep: branchOnInstanceState
     - name: branchOnInstanceState
       action: 'aws:branch'
       onFailure: Abort
       inputs:
         Choices:
           - NextStep: startInstance
             Variable: '{{getInstanceState.instanceState}}'
             StringEquals: stopped
           - Or:
               - Variable: '{{getInstanceState.instanceState}}'
                 StringEquals: stopping
             NextStep: verifyInstanceStopped
           - NextStep: patchInstance
             Variable: '{{getInstanceState.instanceState}}'
             StringEquals: running
       isEnd: true
     - name: startInstance
       action: 'aws:executeAwsApi'
       onFailure: Abort
       inputs:
         Service: ec2
         Api: StartInstances
         InstanceIds:
           - '{{InstanceId}}'
       nextStep: verifyInstanceRunning
     - name: verifyInstanceRunning
       action: 'aws:waitForAwsResourceProperty'
       timeoutSeconds: 120
       inputs:
         Service: ec2
         Api: DescribeInstances
         InstanceIds:
           - '{{InstanceId}}'
         PropertySelector: '$.Reservations[0].Instances[0].State.Name'
         DesiredValues:
           - running
       nextStep: patchInstance
     - name: verifyInstanceStopped
       action: 'aws:waitForAwsResourceProperty'
       timeoutSeconds: 120
       inputs:
         Service: ec2
         Api: DescribeInstances
         InstanceIds:
           - '{{InstanceId}}'
         PropertySelector: '$.Reservations[0].Instances[0].State.Name'
         DesiredValues:
           - stopped
         nextStep: startInstance
     - name: patchInstance
       action: 'aws:runCommand'
       onFailure: Abort
       timeoutSeconds: 5400
       inputs:
         DocumentName: 'AWS-RunPatchBaseline'
         InstanceIds: 
         - '{{InstanceId}}'
         Parameters:
           SnapshotId: '{{SnapshotId}}'
           RebootOption: '{{RebootOption}}'
           Operation: '{{Operation}}'
     - name: branchOnOriginalInstanceState
       action: 'aws:branch'
       onFailure: Abort
       inputs:
         Choices:
           - NextStep: stopInstance
             Not: 
               Variable: '{{getInstanceState.instanceState}}'
               StringEquals: running
       isEnd: true
     - name: stopInstance
       action: 'aws:executeAwsApi'
       onFailure: Abort
       inputs:
         Service: ec2
         Api: StopInstances
         InstanceIds:
           - '{{InstanceId}}'
   ```

------
#### [ JSON ]

   ```
   {
      "schemaVersion":"0.3",
      "description":"An example of an Automation runbook that patches groups of Amazon EC2 instances in stages.",
      "assumeRole":"{{AutomationAssumeRole}}",
      "parameters":{
         "AutomationAssumeRole":{
            "type":"String",
            "description":"'(Optional) The Amazon Resource Name (ARN) of the IAM role that allows Automation to perform the actions on your behalf. If no role is specified, Systems Manager Automation uses your IAM permissions to operate this runbook.'",
            "default":""
         },
         "InstanceId":{
            "type":"String",
            "description":"'(Required) The instance you want to patch.'"
         },
         "SnapshotId":{
            "type":"String",
            "description":"(Optional) The snapshot ID to use to retrieve a patch baseline snapshot.",
            "default":""
         },
         "RebootOption":{
            "type":"String",
            "description":"(Optional) Reboot behavior after a patch Install operation. If you choose NoReboot and patches are installed, the instance is marked as non-compliant until a subsequent reboot and scan.",
            "allowedValues":[
               "NoReboot",
               "RebootIfNeeded"
            ],
            "default":"RebootIfNeeded"
         },
         "Operation":{
            "type":"String",
            "description":"(Optional) The update or configuration to perform on the instance. The system checks if patches specified in the patch baseline are installed on the instance. The install operation installs patches missing from the baseline.",
            "allowedValues":[
               "Install",
               "Scan"
            ],
            "default":"Install"
         }
      },
      "mainSteps":[
         {
            "name":"getInstanceState",
            "action":"aws:executeAwsApi",
            "onFailure":"Abort",
            "inputs":{
               "inputs":null,
               "Service":"ec2",
               "Api":"DescribeInstances",
               "InstanceIds":[
                  "{{InstanceId}}"
               ]
            },
            "outputs":[
               {
                  "Name":"instanceState",
                  "Selector":"$.Reservations[0].Instances[0].State.Name",
                  "Type":"String"
               }
            ],
            "nextStep":"branchOnInstanceState"
         },
         {
            "name":"branchOnInstanceState",
            "action":"aws:branch",
            "onFailure":"Abort",
            "inputs":{
               "Choices":[
                  {
                     "NextStep":"startInstance",
                     "Variable":"{{getInstanceState.instanceState}}",
                     "StringEquals":"stopped"
                  },
                  {
                     "Or":[
                        {
                           "Variable":"{{getInstanceState.instanceState}}",
                           "StringEquals":"stopping"
                        }
                     ],
                     "NextStep":"verifyInstanceStopped"
                  },
                  {
                     "NextStep":"patchInstance",
                     "Variable":"{{getInstanceState.instanceState}}",
                     "StringEquals":"running"
                  }
               ]
            },
            "isEnd":true
         },
         {
            "name":"startInstance",
            "action":"aws:executeAwsApi",
            "onFailure":"Abort",
            "inputs":{
               "Service":"ec2",
               "Api":"StartInstances",
               "InstanceIds":[
                  "{{InstanceId}}"
               ]
            },
            "nextStep":"verifyInstanceRunning"
         },
         {
            "name":"verifyInstanceRunning",
            "action":"aws:waitForAwsResourceProperty",
            "timeoutSeconds":120,
            "inputs":{
               "Service":"ec2",
               "Api":"DescribeInstances",
               "InstanceIds":[
                  "{{InstanceId}}"
               ],
               "PropertySelector":"$.Reservations[0].Instances[0].State.Name",
               "DesiredValues":[
                  "running"
               ]
            },
            "nextStep":"patchInstance"
         },
         {
            "name":"verifyInstanceStopped",
            "action":"aws:waitForAwsResourceProperty",
            "timeoutSeconds":120,
            "inputs":{
               "Service":"ec2",
               "Api":"DescribeInstances",
               "InstanceIds":[
                  "{{InstanceId}}"
               ],
               "PropertySelector":"$.Reservations[0].Instances[0].State.Name",
               "DesiredValues":[
                  "stopped"
               ],
               "nextStep":"startInstance"
            }
         },
         {
            "name":"patchInstance",
            "action":"aws:runCommand",
            "onFailure":"Abort",
            "timeoutSeconds":5400,
            "inputs":{
               "DocumentName":"AWS-RunPatchBaseline",
               "InstanceIds":[
                  "{{InstanceId}}"
               ],
               "Parameters":{
                  "SnapshotId":"{{SnapshotId}}",
                  "RebootOption":"{{RebootOption}}",
                  "Operation":"{{Operation}}"
               }
            }
         },
         {
            "name":"branchOnOriginalInstanceState",
            "action":"aws:branch",
            "onFailure":"Abort",
            "inputs":{
               "Choices":[
                  {
                     "NextStep":"stopInstance",
                     "Not":{
                        "Variable":"{{getInstanceState.instanceState}}",
                        "StringEquals":"running"
                     }
                  }
               ]
            },
            "isEnd":true
         },
         {
            "name":"stopInstance",
            "action":"aws:executeAwsApi",
            "onFailure":"Abort",
            "inputs":{
               "Service":"ec2",
               "Api":"StopInstances",
               "InstanceIds":[
                  "{{InstanceId}}"
               ]
            }
         }
      ]
   }
   ```

------

For more information about the automation actions used in this example, see the [Systems Manager Automation actions reference](automation-actions.md).

## Create the parent runbook
<a name="automation-authoring-runbooks-parent-runbook"></a>

This example runbook continues the scenario described in the previous section. Now that Emily has created the child runbook, she begins authoring the content for the parent runbook as follows:

1. First, she provides values for the schema and description of the runbook, and defines the input parameters for the parent runbook.

   By using the `AutomationAssumeRole` parameter, Emily and her colleagues can use an existing IAM role that allows Automation to perform the actions in the runbook on their behalf. Emily uses the `PatchGroupPrimaryKey` and `PatchGroupPrimaryValue` parameters to specify the tag associated with the primary group of database instances that will be patched. She uses the `PatchGroupSecondaryKey` and `PatchGroupSecondaryValue` parameters to specify the tag associated with the secondary group of database instances that will be patched.

------
#### [ YAML ]

   ```
   description: 'An example of an Automation runbook that patches groups of Amazon EC2 instances in stages.'
   schemaVersion: '0.3'
   assumeRole: '{{AutomationAssumeRole}}'
   parameters:
     AutomationAssumeRole:
       type: String
       description: '(Optional) The Amazon Resource Name (ARN) of the IAM role that allows Automation to perform the actions on your behalf. If no role is specified, Systems Manager Automation uses your IAM permissions to operate this runbook.'
       default: ''
     PatchGroupPrimaryKey:
       type: String
       description: '(Required) The key of the tag for the primary group of instances you want to patch.''
     PatchGroupPrimaryValue:
       type: String
       description: '(Required) The value of the tag for the primary group of instances you want to patch.'
     PatchGroupSecondaryKey:
       type: String
       description: '(Required) The key of the tag for the secondary group of instances you want to patch.'
     PatchGroupSecondaryValue:
       type: String
       description: '(Required) The value of the tag for the secondary group of instances you want to patch.'
   ```

------
#### [ JSON ]

   ```
   {
      "schemaVersion": "0.3",
      "description": "An example of an Automation runbook that patches groups of Amazon EC2 instances in stages.",
      "assumeRole": "{{AutomationAssumeRole}}",
      "parameters": {
         "AutomationAssumeRole": {
            "type": "String",
            "description": "(Optional) The Amazon Resource Name (ARN) of the IAM role that allows Automation to perform the actions on your behalf. If no role is specified, Systems Manager Automation uses your IAM permissions to operate this runbook.",
            "default": ""
         },
         "PatchGroupPrimaryKey": {
            "type": "String",
            "description": "(Required) The key of the tag for the primary group of instances you want to patch."
         },
         "PatchGroupPrimaryValue": {
            "type": "String",
            "description": "(Required) The value of the tag for the primary group of instances you want to patch."
         },
         "PatchGroupSecondaryKey": {
            "type": "String",
            "description": "(Required) The key of the tag for the secondary group of instances you want to patch."
         },
         "PatchGroupSecondaryValue": {
            "type": "String",
            "description": "(Required) The value of the tag for the secondary group of instances you want to patch."
         }
      }
   },
   ```

------

1. With the top-level elements defined, Emily proceeds with authoring the actions that make up the `mainSteps` of the runbook. 

   The first action starts a rate control automation using the child runbook she just created that targets instances associated with the tag specified in the `PatchGroupPrimaryKey` and `PatchGroupPrimaryValue` input parameters. She uses the values provided to the input parameters to specify the key and value of the tag associated with the primary group of database instances she wants to patch.

   After the first automation completes, the second action starts another rate control automation using the child runbook that targets instances associated with the tag specified in the `PatchGroupSecondaryKey` and `PatchGroupSecondaryValue` input parameters. She uses the values provided to the input parameters to specify the key and value of the tag associated with the secondary group of database instances she wants to patch.

------
#### [ YAML ]

   ```
   mainSteps:
     - name: patchPrimaryTargets
       action: 'aws:executeAutomation'
       onFailure: Abort
       timeoutSeconds: 7200
       inputs:
         DocumentName: RunbookTutorialChildAutomation
         Targets:
           - Key: 'tag:{{PatchGroupPrimaryKey}}'
             Values:
               - '{{PatchGroupPrimaryValue}}'
         TargetParameterName: 'InstanceId'
     - name: patchSecondaryTargets
       action: 'aws:executeAutomation'
       onFailure: Abort
       timeoutSeconds: 7200
       inputs:
         DocumentName: RunbookTutorialChildAutomation
         Targets:
           - Key: 'tag:{{PatchGroupSecondaryKey}}'
             Values:
               - '{{PatchGroupSecondaryValue}}'
         TargetParameterName: 'InstanceId'
   ```

------
#### [ JSON ]

   ```
   "mainSteps":[
         {
            "name":"patchPrimaryTargets",
            "action":"aws:executeAutomation",
            "onFailure":"Abort",
            "timeoutSeconds":7200,
            "inputs":{
               "DocumentName":"RunbookTutorialChildAutomation",
               "Targets":[
                  {
                     "Key":"tag:{{PatchGroupPrimaryKey}}",
                     "Values":[
                        "{{PatchGroupPrimaryValue}}"
                     ]
                  }
               ],
               "TargetParameterName":"InstanceId"
            }
         },
         {
            "name":"patchSecondaryTargets",
            "action":"aws:executeAutomation",
            "onFailure":"Abort",
            "timeoutSeconds":7200,
            "inputs":{
               "DocumentName":"RunbookTutorialChildAutomation",
               "Targets":[
                  {
                     "Key":"tag:{{PatchGroupSecondaryKey}}",
                     "Values":[
                        "{{PatchGroupSecondaryValue}}"
                     ]
                  }
               ],
               "TargetParameterName":"InstanceId"
            }
         }
      ]
   }
   ```

------

1. Emily reviews the completed parent runbook content and creates the runbook in the same AWS account and AWS Region as the target instances. Now, she is ready to test her runbooks to make sure the automation operates as desired before implementing them into her production environment. The following is the completed parent runbook content.

------
#### [ YAML ]

   ```
   description: An example of an Automation runbook that patches groups of Amazon EC2 instances in stages.
   schemaVersion: '0.3'
   assumeRole: '{{AutomationAssumeRole}}'
   parameters:
     AutomationAssumeRole:
       type: String
       description: '(Optional) The Amazon Resource Name (ARN) of the IAM role that allows Automation to perform the actions on your behalf. If no role is specified, Systems Manager Automation uses your IAM permissions to operate this runbook.'
       default: ''
     PatchGroupPrimaryKey:
       type: String
       description: (Required) The key of the tag for the primary group of instances you want to patch.
     PatchGroupPrimaryValue:
       type: String
       description: '(Required) The value of the tag for the primary group of instances you want to patch. '
     PatchGroupSecondaryKey:
       type: String
       description: (Required) The key of the tag for the secondary group of instances you want to patch.
     PatchGroupSecondaryValue:
       type: String
       description: '(Required) The value of the tag for the secondary group of instances you want to patch.  '
   mainSteps:
     - name: patchPrimaryTargets
       action: 'aws:executeAutomation'
       onFailure: Abort
       timeoutSeconds: 7200
       inputs:
         DocumentName: RunbookTutorialChildAutomation
         Targets:
           - Key: 'tag:{{PatchGroupPrimaryKey}}'
             Values:
               - '{{PatchGroupPrimaryValue}}'
         TargetParameterName: 'InstanceId'
     - name: patchSecondaryTargets
       action: 'aws:executeAutomation'
       onFailure: Abort
       timeoutSeconds: 7200
       inputs:
         DocumentName: RunbookTutorialChildAutomation
         Targets:
           - Key: 'tag:{{PatchGroupSecondaryKey}}'
             Values:
               - '{{PatchGroupSecondaryValue}}'
         TargetParameterName: 'InstanceId'
   ```

------
#### [ JSON ]

   ```
   {
      "description":"An example of an Automation runbook that patches groups of Amazon EC2 instances in stages.",
      "schemaVersion":"0.3",
      "assumeRole":"{{AutomationAssumeRole}}",
      "parameters":{
         "AutomationAssumeRole":{
            "type":"String",
            "description":"(Optional) The Amazon Resource Name (ARN) of the IAM role that allows Automation to perform the actions on your behalf. If no role is specified, Systems Manager Automation uses your IAM permissions to operate this runbook.",
            "default":""
         },
         "PatchGroupPrimaryKey":{
            "type":"String",
            "description":"(Required) The key of the tag for the primary group of instances you want to patch."
         },
         "PatchGroupPrimaryValue":{
            "type":"String",
            "description":"(Required) The value of the tag for the primary group of instances you want to patch. "
         },
         "PatchGroupSecondaryKey":{
            "type":"String",
            "description":"(Required) The key of the tag for the secondary group of instances you want to patch."
         },
         "PatchGroupSecondaryValue":{
            "type":"String",
            "description":"(Required) The value of the tag for the secondary group of instances you want to patch.  "
         }
      },
      "mainSteps":[
         {
            "name":"patchPrimaryTargets",
            "action":"aws:executeAutomation",
            "onFailure":"Abort",
            "timeoutSeconds":7200,
            "inputs":{
               "DocumentName":"RunbookTutorialChildAutomation",
               "Targets":[
                  {
                     "Key":"tag:{{PatchGroupPrimaryKey}}",
                     "Values":[
                        "{{PatchGroupPrimaryValue}}"
                     ]
                  }
               ],
               "TargetParameterName":"InstanceId"
            }
         },
         {
            "name":"patchSecondaryTargets",
            "action":"aws:executeAutomation",
            "onFailure":"Abort",
            "timeoutSeconds":7200,
            "inputs":{
               "DocumentName":"RunbookTutorialChildAutomation",
               "Targets":[
                  {
                     "Key":"tag:{{PatchGroupSecondaryKey}}",
                     "Values":[
                        "{{PatchGroupSecondaryValue}}"
                     ]
                  }
               ],
               "TargetParameterName":"InstanceId"
            }
         }
      ]
   }
   ```

------

For more information about the automation actions used in this example, see the [Systems Manager Automation actions reference](automation-actions.md).

# Example 2: Scripted runbook
<a name="automation-authoring-runbooks-scripted-example"></a>

This example runbook addresses the following scenario. Emily is a Systems Engineer at AnyCompany Consultants, LLC. She previously created two runbooks that are used in a parent-child relationship to patch groups of Amazon Elastic Compute Cloud (Amazon EC2) instances that host primary and secondary databases. Applications access these databases 24 hours a day, so one of the database instances must always be available. 

Based on this requirement, she built a solution that patches the instances in stages using the `AWS-RunPatchBaseline` Systems Manager (SSM) document. By using this SSM document, her colleagues can review the associated patch compliance information after the patching operation completes. 

The primary group of database instances are patched first, followed by the secondary group of database instances. Also, to avoid incurring additional costs by leaving instances running that were previously stopped, Emily made sure that the automation returned the patched instances to their original state before the patching occurred. Emily used tags that are associated with the primary and secondary groups of database instances to identify which instances should be patched in her desired order.

Her existing automated solution works, but she wants to improve her solution if possible. To help with the maintenance of the runbook content and to ease troubleshooting efforts, she would like to condense the automation into a single runbook and simplify the number of input parameters. Also, she would like to avoid creating multiple child automations. 

After Emily reviews the available automation actions, she determines that she can improve her solution by using the `aws:executeScript` action to run her custom Python scripts. She now begins authoring the content for the runbook as follows:

1. First, she provides values for the schema and description of the runbook, and defines the input parameters for the parent runbook.

   By using the `AutomationAssumeRole` parameter, Emily and her colleagues can use an existing IAM role that allows Automation to perform the actions in the runbook on their behalf. Unlike [Example 1](automation-authoring-runbooks-parent-child-example.md), the `AutomationAssumeRole` parameter is now required rather than optional. Because this runbook includes `aws:executeScript` actions, an AWS Identity and Access Management (IAM) service role (or assume role) is always required. This requirement is necessary because some of the Python scripts specified for the actions call AWS API operations.

   Emily uses the `PrimaryPatchGroupTag` and `SecondaryPatchGroupTag` parameters to specify the tags associated with the primary and secondary group of database instances that will be patched. To simplify the required input parameters, she decides to use `StringMap` parameters rather than using multiple `String` parameters as she used in the Example 1 runbook. Optionally, the `Operation`, `RebootOption`, and `SnapshotId` parameters can be used to provide values to document parameters for `AWS-RunPatchBaseline`. To prevent invalid values from being provided to those document parameters, she defines the `allowedValues` as needed.

------
#### [ YAML ]

   ```
   description: 'An example of an Automation runbook that patches groups of Amazon EC2 instances in stages.'
   schemaVersion: '0.3'
   assumeRole: '{{AutomationAssumeRole}}'
   parameters:
     AutomationAssumeRole:
       type: String
       description: '(Required) The Amazon Resource Name (ARN) of the IAM role that allows Automation to perform the actions on your behalf. If no role is specified, Systems Manager Automation uses your IAM permissions to operate this runbook.'
     PrimaryPatchGroupTag:
       type: StringMap
       description: '(Required) The tag for the primary group of instances you want to patch. Specify a key-value pair. Example: {"key" : "value"}'
     SecondaryPatchGroupTag:
       type: StringMap
       description: '(Required) The tag for the secondary group of instances you want to patch. Specify a key-value pair. Example: {"key" : "value"}'
     SnapshotId:
       type: String
       description: '(Optional) The snapshot ID to use to retrieve a patch baseline snapshot.'
       default: ''
     RebootOption:
       type: String
       description: '(Optional) Reboot behavior after a patch Install operation. If you choose NoReboot and patches are installed, the instance is marked as non-compliant until a subsequent reboot and scan.'
       allowedValues:
         - NoReboot
         - RebootIfNeeded
       default: RebootIfNeeded
     Operation:
       type: String
       description: '(Optional) The update or configuration to perform on the instance. The system checks if patches specified in the patch baseline are installed on the instance. The install operation installs patches missing from the baseline.'
       allowedValues:
         - Install
         - Scan
       default: Install
   ```

------
#### [ JSON ]

   ```
   {
      "description":"An example of an Automation runbook that patches groups of Amazon EC2 instances in stages.",
      "schemaVersion":"0.3",
      "assumeRole":"{{AutomationAssumeRole}}",
      "parameters":{
         "AutomationAssumeRole":{
            "type":"String",
            "description":"(Required) The Amazon Resource Name (ARN) of the IAM role that allows Automation to perform the actions on your behalf. If no role is specified, Systems Manager Automation uses your IAM permissions to operate this runbook."
         },
         "PrimaryPatchGroupTag":{
            "type":"StringMap",
            "description":"(Required) The tag for the primary group of instances you want to patch. Specify a key-value pair. Example: {\"key\" : \"value\"}"
         },
         "SecondaryPatchGroupTag":{
            "type":"StringMap",
            "description":"(Required) The tag for the secondary group of instances you want to patch. Specify a key-value pair. Example: {\"key\" : \"value\"}"
         },
         "SnapshotId":{
            "type":"String",
            "description":"(Optional) The snapshot ID to use to retrieve a patch baseline snapshot.",
            "default":""
         },
         "RebootOption":{
            "type":"String",
            "description":"(Optional) Reboot behavior after a patch Install operation. If you choose NoReboot and patches are installed, the instance is marked as non-compliant until a subsequent reboot and scan.",
            "allowedValues":[
               "NoReboot",
               "RebootIfNeeded"
            ],
            "default":"RebootIfNeeded"
         },
         "Operation":{
            "type":"String",
            "description":"(Optional) The update or configuration to perform on the instance. The system checks if patches specified in the patch baseline are installed on the instance. The install operation installs patches missing from the baseline.",
            "allowedValues":[
               "Install",
               "Scan"
            ],
            "default":"Install"
         }
      }
   },
   ```

------

1. With the top-level elements defined, Emily proceeds with authoring the actions that make up the `mainSteps` of the runbook. The first step gathers the IDs of all instances associated with the tag specified in the `PrimaryPatchGroupTag` parameter and outputs a `StringMap` parameter containing the instance ID and the current state of the instance. The output of this action is used in later actions. 

   Note that the `script` input parameter isn't supported for JSON runbooks. JSON runbooks must provide script content using the `attachment` input parameter.

------
#### [ YAML ]

   ```
   mainSteps:
     - name: getPrimaryInstanceState
       action: 'aws:executeScript'
       timeoutSeconds: 120
       onFailure: Abort
       inputs:
         Runtime: python3.11
         Handler: getInstanceStates
         InputPayload:
           primaryTag: '{{PrimaryPatchGroupTag}}'
         Script: |-
           def getInstanceStates(events,context):
             import boto3
   
             #Initialize client
             ec2 = boto3.client('ec2')
             tag = events['primaryTag']
             tagKey, tagValue = list(tag.items())[0]
             instanceQuery = ec2.describe_instances(
             Filters=[
                 {
                     "Name": "tag:" + tagKey,
                     "Values": [tagValue]
                 }]
             )
             if not instanceQuery['Reservations']:
                 noInstancesForTagString = "No instances found for specified tag."
                 return({ 'noInstancesFound' : noInstancesForTagString })
             else:
                 queryResponse = instanceQuery['Reservations']
                 originalInstanceStates = {}
                 for results in queryResponse:
                     instanceSet = results['Instances']
                     for instance in instanceSet:
                         instanceId = instance['InstanceId']
                         originalInstanceStates[instanceId] = instance['State']['Name']
                 return originalInstanceStates
       outputs:
         - Name: originalInstanceStates
           Selector: $.Payload
           Type: StringMap
       nextStep: verifyPrimaryInstancesRunning
   ```

------
#### [ JSON ]

   ```
   "mainSteps":[
         {
            "name":"getPrimaryInstanceState",
            "action":"aws:executeScript",
            "timeoutSeconds":120,
            "onFailure":"Abort",
            "inputs":{
               "Runtime":"python3.11",
               "Handler":"getInstanceStates",
               "InputPayload":{
                  "primaryTag":"{{PrimaryPatchGroupTag}}"
               },
               "Script":"..."
            },
            "outputs":[
               {
                  "Name":"originalInstanceStates",
                  "Selector":"$.Payload",
                  "Type":"StringMap"
               }
            ],
            "nextStep":"verifyPrimaryInstancesRunning"
         },
   ```

------

1. Emily uses the output from the previous action in another `aws:executeScript` action to verify all instances associated with the tag specified in the `PrimaryPatchGroupTag` parameter are in a `running` state.

   If the instance state is already `running` or `shutting-down`, the script continues to loop through the remaining instances.

   If the instance state is `stopping`, the script polls for the instance to reach the `stopped` state and starts the instance.

   If the instance state is `stopped`, the script starts the instance.

------
#### [ YAML ]

   ```
   - name: verifyPrimaryInstancesRunning
       action: 'aws:executeScript'
       timeoutSeconds: 600
       onFailure: Abort
       inputs:
         Runtime: python3.11
         Handler: verifyInstancesRunning
         InputPayload:
           targetInstances: '{{getPrimaryInstanceState.originalInstanceStates}}'
         Script: |-
           def verifyInstancesRunning(events,context):
             import boto3
   
             #Initialize client
             ec2 = boto3.client('ec2')
             instanceDict = events['targetInstances']
             for instance in instanceDict:
               if instanceDict[instance] == 'stopped':
                   print("The target instance " + instance + " is stopped. The instance will now be started.")
                   ec2.start_instances(
                       InstanceIds=[instance]
                       )
               elif instanceDict[instance] == 'stopping':
                   print("The target instance " + instance + " is stopping. Polling for instance to reach stopped state.")
                   while instanceDict[instance] != 'stopped':
                       poll = ec2.get_waiter('instance_stopped')
                       poll.wait(
                           InstanceIds=[instance]
                       )
                   ec2.start_instances(
                       InstanceIds=[instance]
                   )
               else:
                 pass
       nextStep: waitForPrimaryRunningInstances
   ```

------
#### [ JSON ]

   ```
   {
            "name":"verifyPrimaryInstancesRunning",
            "action":"aws:executeScript",
            "timeoutSeconds":600,
            "onFailure":"Abort",
            "inputs":{
               "Runtime":"python3.11",
               "Handler":"verifyInstancesRunning",
               "InputPayload":{
                  "targetInstances":"{{getPrimaryInstanceState.originalInstanceStates}}"
               },
               "Script":"..."
            },
            "nextStep":"waitForPrimaryRunningInstances"
         },
   ```

------

1. Emily verifies that all instances associated with the tag specified in the `PrimaryPatchGroupTag` parameter were started or already in a `running` state. Then she uses another script to verify that all instances, including those that were started in the previous action, have reached the `running` state.

------
#### [ YAML ]

   ```
   - name: waitForPrimaryRunningInstances
       action: 'aws:executeScript'
       timeoutSeconds: 300
       onFailure: Abort
       inputs:
         Runtime: python3.11
         Handler: waitForRunningInstances
         InputPayload:
           targetInstances: '{{getPrimaryInstanceState.originalInstanceStates}}'
         Script: |-
           def waitForRunningInstances(events,context):
             import boto3
   
             #Initialize client
             ec2 = boto3.client('ec2')
             instanceDict = events['targetInstances']
             for instance in instanceDict:
                 poll = ec2.get_waiter('instance_running')
                 poll.wait(
                     InstanceIds=[instance]
                 )
       nextStep: returnPrimaryTagKey
   ```

------
#### [ JSON ]

   ```
   {
            "name":"waitForPrimaryRunningInstances",
            "action":"aws:executeScript",
            "timeoutSeconds":300,
            "onFailure":"Abort",
            "inputs":{
               "Runtime":"python3.11",
               "Handler":"waitForRunningInstances",
               "InputPayload":{
                  "targetInstances":"{{getPrimaryInstanceState.originalInstanceStates}}"
               },
               "Script":"..."
            },
            "nextStep":"returnPrimaryTagKey"
         },
   ```

------

1. Emily uses two more scripts to return individual `String` values of the key and value of the tag specified in the `PrimaryPatchGroupTag` parameter. The values returned by these actions allows her to provide values directly to the `Targets` parameter for the `AWS-RunPatchBaseline` document. The automation then proceeds with patching the instance with the `AWS-RunPatchBaseline` document using the `aws:runCommand` action.

------
#### [ YAML ]

   ```
   - name: returnPrimaryTagKey
       action: 'aws:executeScript'
       timeoutSeconds: 120
       onFailure: Abort
       inputs:
         Runtime: python3.11
         Handler: returnTagValues
         InputPayload:
           primaryTag: '{{PrimaryPatchGroupTag}}'
         Script: |-
           def returnTagValues(events,context):
             tag = events['primaryTag']
             tagKey = list(tag)[0]
             stringKey = "tag:" + tagKey
             return {'tagKey' : stringKey}
       outputs:
         - Name: Payload
           Selector: $.Payload
           Type: StringMap
         - Name: primaryPatchGroupKey
           Selector: $.Payload.tagKey
           Type: String
       nextStep: returnPrimaryTagValue
     - name: returnPrimaryTagValue
       action: 'aws:executeScript'
       timeoutSeconds: 120
       onFailure: Abort
       inputs:
         Runtime: python3.11
         Handler: returnTagValues
         InputPayload:
           primaryTag: '{{PrimaryPatchGroupTag}}'
         Script: |-
           def returnTagValues(events,context):
             tag = events['primaryTag']
             tagKey = list(tag)[0]
             tagValue = tag[tagKey]
             return {'tagValue' : tagValue}
       outputs:
         - Name: Payload
           Selector: $.Payload
           Type: StringMap
         - Name: primaryPatchGroupValue
           Selector: $.Payload.tagValue
           Type: String
       nextStep: patchPrimaryInstances
     - name: patchPrimaryInstances
       action: 'aws:runCommand'
       onFailure: Abort
       timeoutSeconds: 7200
       inputs:
         DocumentName: AWS-RunPatchBaseline
         Parameters:
           SnapshotId: '{{SnapshotId}}'
           RebootOption: '{{RebootOption}}'
           Operation: '{{Operation}}'
         Targets:
           - Key: '{{returnPrimaryTagKey.primaryPatchGroupKey}}'
             Values:
               - '{{returnPrimaryTagValue.primaryPatchGroupValue}}'
         MaxConcurrency: 10%
         MaxErrors: 10%
       nextStep: returnPrimaryToOriginalState
   ```

------
#### [ JSON ]

   ```
   {
            "name":"returnPrimaryTagKey",
            "action":"aws:executeScript",
            "timeoutSeconds":120,
            "onFailure":"Abort",
            "inputs":{
               "Runtime":"python3.11",
               "Handler":"returnTagValues",
               "InputPayload":{
                  "primaryTag":"{{PrimaryPatchGroupTag}}"
               },
               "Script":"..."
            },
            "outputs":[
               {
                  "Name":"Payload",
                  "Selector":"$.Payload",
                  "Type":"StringMap"
               },
               {
                  "Name":"primaryPatchGroupKey",
                  "Selector":"$.Payload.tagKey",
                  "Type":"String"
               }
            ],
            "nextStep":"returnPrimaryTagValue"
         },
         {
            "name":"returnPrimaryTagValue",
            "action":"aws:executeScript",
            "timeoutSeconds":120,
            "onFailure":"Abort",
            "inputs":{
               "Runtime":"python3.11",
               "Handler":"returnTagValues",
               "InputPayload":{
                  "primaryTag":"{{PrimaryPatchGroupTag}}"
               },
               "Script":"..."
            },
            "outputs":[
               {
                  "Name":"Payload",
                  "Selector":"$.Payload",
                  "Type":"StringMap"
               },
               {
                  "Name":"primaryPatchGroupValue",
                  "Selector":"$.Payload.tagValue",
                  "Type":"String"
               }
            ],
            "nextStep":"patchPrimaryInstances"
         },
         {
            "name":"patchPrimaryInstances",
            "action":"aws:runCommand",
            "onFailure":"Abort",
            "timeoutSeconds":7200,
            "inputs":{
               "DocumentName":"AWS-RunPatchBaseline",
               "Parameters":{
                  "SnapshotId":"{{SnapshotId}}",
                  "RebootOption":"{{RebootOption}}",
                  "Operation":"{{Operation}}"
               },
               "Targets":[
                  {
                     "Key":"{{returnPrimaryTagKey.primaryPatchGroupKey}}",
                     "Values":[
                        "{{returnPrimaryTagValue.primaryPatchGroupValue}}"
                     ]
                  }
               ],
               "MaxConcurrency":"10%",
               "MaxErrors":"10%"
            },
            "nextStep":"returnPrimaryToOriginalState"
         },
   ```

------

1. After the patching operation completes, Emily wants the automation to return the target instances associated with the tag specified in the `PrimaryPatchGroupTag` parameter to the same state they were before the automation started. She does this by again using the output from the first action in a script. Based on the original state of the target instance, if the instance was previously in any state other than `running`, the instance is stopped. Otherwise, if the instance state is `running`, the script continues to loop through the remaining instances.

------
#### [ YAML ]

   ```
   - name: returnPrimaryToOriginalState
       action: 'aws:executeScript'
       timeoutSeconds: 600
       onFailure: Abort
       inputs:
         Runtime: python3.11
         Handler: returnToOriginalState
         InputPayload:
           targetInstances: '{{getPrimaryInstanceState.originalInstanceStates}}'
         Script: |-
           def returnToOriginalState(events,context):
             import boto3
   
             #Initialize client
             ec2 = boto3.client('ec2')
             instanceDict = events['targetInstances']
             for instance in instanceDict:
               if instanceDict[instance] == 'stopped' or instanceDict[instance] == 'stopping':
                   ec2.stop_instances(
                       InstanceIds=[instance]
                       )
               else:
                 pass
       nextStep: getSecondaryInstanceState
   ```

------
#### [ JSON ]

   ```
   {
            "name":"returnPrimaryToOriginalState",
            "action":"aws:executeScript",
            "timeoutSeconds":600,
            "onFailure":"Abort",
            "inputs":{
               "Runtime":"python3.11",
               "Handler":"returnToOriginalState",
               "InputPayload":{
                  "targetInstances":"{{getPrimaryInstanceState.originalInstanceStates}}"
               },
               "Script":"..."
            },
            "nextStep":"getSecondaryInstanceState"
         },
   ```

------

1. The patching operation is completed for the instances associated with the tag specified in the `PrimaryPatchGroupTag` parameter. Now Emily duplicates all of the previous actions in her runbook content to target the instances associated with the tag specified in the `SecondaryPatchGroupTag` parameter.

------
#### [ YAML ]

   ```
   - name: getSecondaryInstanceState
       action: 'aws:executeScript'
       timeoutSeconds: 120
       onFailure: Abort
       inputs:
         Runtime: python3.11
         Handler: getInstanceStates
         InputPayload:
           secondaryTag: '{{SecondaryPatchGroupTag}}'
         Script: |-
           def getInstanceStates(events,context):
             import boto3
   
             #Initialize client
             ec2 = boto3.client('ec2')
             tag = events['secondaryTag']
             tagKey, tagValue = list(tag.items())[0]
             instanceQuery = ec2.describe_instances(
             Filters=[
                 {
                     "Name": "tag:" + tagKey,
                     "Values": [tagValue]
                 }]
             )
             if not instanceQuery['Reservations']:
                 noInstancesForTagString = "No instances found for specified tag."
                 return({ 'noInstancesFound' : noInstancesForTagString })
             else:
                 queryResponse = instanceQuery['Reservations']
                 originalInstanceStates = {}
                 for results in queryResponse:
                     instanceSet = results['Instances']
                     for instance in instanceSet:
                         instanceId = instance['InstanceId']
                         originalInstanceStates[instanceId] = instance['State']['Name']
                 return originalInstanceStates
       outputs:
         - Name: originalInstanceStates
           Selector: $.Payload
           Type: StringMap
       nextStep: verifySecondaryInstancesRunning
     - name: verifySecondaryInstancesRunning
       action: 'aws:executeScript'
       timeoutSeconds: 600
       onFailure: Abort
       inputs:
         Runtime: python3.11
         Handler: verifyInstancesRunning
         InputPayload:
           targetInstances: '{{getSecondaryInstanceState.originalInstanceStates}}'
         Script: |-
           def verifyInstancesRunning(events,context):
             import boto3
   
             #Initialize client
             ec2 = boto3.client('ec2')
             instanceDict = events['targetInstances']
             for instance in instanceDict:
               if instanceDict[instance] == 'stopped':
                   print("The target instance " + instance + " is stopped. The instance will now be started.")
                   ec2.start_instances(
                       InstanceIds=[instance]
                       )
               elif instanceDict[instance] == 'stopping':
                   print("The target instance " + instance + " is stopping. Polling for instance to reach stopped state.")
                   while instanceDict[instance] != 'stopped':
                       poll = ec2.get_waiter('instance_stopped')
                       poll.wait(
                           InstanceIds=[instance]
                       )
                   ec2.start_instances(
                       InstanceIds=[instance]
                   )
               else:
                 pass
       nextStep: waitForSecondaryRunningInstances
     - name: waitForSecondaryRunningInstances
       action: 'aws:executeScript'
       timeoutSeconds: 300
       onFailure: Abort
       inputs:
         Runtime: python3.11
         Handler: waitForRunningInstances
         InputPayload:
           targetInstances: '{{getSecondaryInstanceState.originalInstanceStates}}'
         Script: |-
           def waitForRunningInstances(events,context):
             import boto3
   
             #Initialize client
             ec2 = boto3.client('ec2')
             instanceDict = events['targetInstances']
             for instance in instanceDict:
                 poll = ec2.get_waiter('instance_running')
                 poll.wait(
                     InstanceIds=[instance]
                 )
       nextStep: returnSecondaryTagKey
     - name: returnSecondaryTagKey
       action: 'aws:executeScript'
       timeoutSeconds: 120
       onFailure: Abort
       inputs:
         Runtime: python3.11
         Handler: returnTagValues
         InputPayload:
           secondaryTag: '{{SecondaryPatchGroupTag}}'
         Script: |-
           def returnTagValues(events,context):
             tag = events['secondaryTag']
             tagKey = list(tag)[0]
             stringKey = "tag:" + tagKey
             return {'tagKey' : stringKey}
       outputs:
         - Name: Payload
           Selector: $.Payload
           Type: StringMap
         - Name: secondaryPatchGroupKey
           Selector: $.Payload.tagKey
           Type: String
       nextStep: returnSecondaryTagValue
     - name: returnSecondaryTagValue
       action: 'aws:executeScript'
       timeoutSeconds: 120
       onFailure: Abort
       inputs:
         Runtime: python3.11
         Handler: returnTagValues
         InputPayload:
           secondaryTag: '{{SecondaryPatchGroupTag}}'
         Script: |-
           def returnTagValues(events,context):
             tag = events['secondaryTag']
             tagKey = list(tag)[0]
             tagValue = tag[tagKey]
             return {'tagValue' : tagValue}
       outputs:
         - Name: Payload
           Selector: $.Payload
           Type: StringMap
         - Name: secondaryPatchGroupValue
           Selector: $.Payload.tagValue
           Type: String
       nextStep: patchSecondaryInstances
     - name: patchSecondaryInstances
       action: 'aws:runCommand'
       onFailure: Abort
       timeoutSeconds: 7200
       inputs:
         DocumentName: AWS-RunPatchBaseline
         Parameters:
           SnapshotId: '{{SnapshotId}}'
           RebootOption: '{{RebootOption}}'
           Operation: '{{Operation}}'
         Targets:
           - Key: '{{returnSecondaryTagKey.secondaryPatchGroupKey}}'
             Values:
             - '{{returnSecondaryTagValue.secondaryPatchGroupValue}}'
         MaxConcurrency: 10%
         MaxErrors: 10%
       nextStep: returnSecondaryToOriginalState
     - name: returnSecondaryToOriginalState
       action: 'aws:executeScript'
       timeoutSeconds: 600
       onFailure: Abort
       inputs:
         Runtime: python3.11
         Handler: returnToOriginalState
         InputPayload:
           targetInstances: '{{getSecondaryInstanceState.originalInstanceStates}}'
         Script: |-
           def returnToOriginalState(events,context):
             import boto3
   
             #Initialize client
             ec2 = boto3.client('ec2')
             instanceDict = events['targetInstances']
             for instance in instanceDict:
               if instanceDict[instance] == 'stopped' or instanceDict[instance] == 'stopping':
                   ec2.stop_instances(
                       InstanceIds=[instance]
                       )
               else:
                 pass
   ```

------
#### [ JSON ]

   ```
   {
            "name":"getSecondaryInstanceState",
            "action":"aws:executeScript",
            "timeoutSeconds":120,
            "onFailure":"Abort",
            "inputs":{
               "Runtime":"python3.11",
               "Handler":"getInstanceStates",
               "InputPayload":{
                  "secondaryTag":"{{SecondaryPatchGroupTag}}"
               },
               "Script":"..."
            },
            "outputs":[
               {
                  "Name":"originalInstanceStates",
                  "Selector":"$.Payload",
                  "Type":"StringMap"
               }
            ],
            "nextStep":"verifySecondaryInstancesRunning"
         },
         {
            "name":"verifySecondaryInstancesRunning",
            "action":"aws:executeScript",
            "timeoutSeconds":600,
            "onFailure":"Abort",
            "inputs":{
               "Runtime":"python3.11",
               "Handler":"verifyInstancesRunning",
               "InputPayload":{
                  "targetInstances":"{{getSecondaryInstanceState.originalInstanceStates}}"
               },
               "Script":"..."
            },
            "nextStep":"waitForSecondaryRunningInstances"
         },
         {
            "name":"waitForSecondaryRunningInstances",
            "action":"aws:executeScript",
            "timeoutSeconds":300,
            "onFailure":"Abort",
            "inputs":{
               "Runtime":"python3.11",
               "Handler":"waitForRunningInstances",
               "InputPayload":{
                  "targetInstances":"{{getSecondaryInstanceState.originalInstanceStates}}"
               },
               "Script":"..."
            },
            "nextStep":"returnSecondaryTagKey"
         },
         {
            "name":"returnSecondaryTagKey",
            "action":"aws:executeScript",
            "timeoutSeconds":120,
            "onFailure":"Abort",
            "inputs":{
               "Runtime":"python3.11",
               "Handler":"returnTagValues",
               "InputPayload":{
                  "secondaryTag":"{{SecondaryPatchGroupTag}}"
               },
               "Script":"..."
            },
            "outputs":[
               {
                  "Name":"Payload",
                  "Selector":"$.Payload",
                  "Type":"StringMap"
               },
               {
                  "Name":"secondaryPatchGroupKey",
                  "Selector":"$.Payload.tagKey",
                  "Type":"String"
               }
            ],
            "nextStep":"returnSecondaryTagValue"
         },
         {
            "name":"returnSecondaryTagValue",
            "action":"aws:executeScript",
            "timeoutSeconds":120,
            "onFailure":"Abort",
            "inputs":{
               "Runtime":"python3.11",
               "Handler":"returnTagValues",
               "InputPayload":{
                  "secondaryTag":"{{SecondaryPatchGroupTag}}"
               },
               "Script":"..."
            },
            "outputs":[
               {
                  "Name":"Payload",
                  "Selector":"$.Payload",
                  "Type":"StringMap"
               },
               {
                  "Name":"secondaryPatchGroupValue",
                  "Selector":"$.Payload.tagValue",
                  "Type":"String"
               }
            ],
            "nextStep":"patchSecondaryInstances"
         },
         {
            "name":"patchSecondaryInstances",
            "action":"aws:runCommand",
            "onFailure":"Abort",
            "timeoutSeconds":7200,
            "inputs":{
               "DocumentName":"AWS-RunPatchBaseline",
               "Parameters":{
                  "SnapshotId":"{{SnapshotId}}",
                  "RebootOption":"{{RebootOption}}",
                  "Operation":"{{Operation}}"
               },
               "Targets":[
                  {
                     "Key":"{{returnSecondaryTagKey.secondaryPatchGroupKey}}",
                     "Values":[
                        "{{returnSecondaryTagValue.secondaryPatchGroupValue}}"
                     ]
                  }
               ],
               "MaxConcurrency":"10%",
               "MaxErrors":"10%"
            },
            "nextStep":"returnSecondaryToOriginalState"
         },
         {
            "name":"returnSecondaryToOriginalState",
            "action":"aws:executeScript",
            "timeoutSeconds":600,
            "onFailure":"Abort",
            "inputs":{
               "Runtime":"python3.11",
               "Handler":"returnToOriginalState",
               "InputPayload":{
                  "targetInstances":"{{getSecondaryInstanceState.originalInstanceStates}}"
               },
               "Script":"..."
            }
         }
      ]
   }
   ```

------

1. Emily reviews the completed scripted runbook content and creates the runbook in the same AWS account and AWS Region as the target instances. Now she's ready to test her runbook to make sure the automation operates as desired before implementing it into her production environment. The following is the completed scripted runbook content.

------
#### [ YAML ]

   ```
   description: An example of an Automation runbook that patches groups of Amazon EC2 instances in stages.
   schemaVersion: '0.3'
   assumeRole: '{{AutomationAssumeRole}}'
   parameters:
     AutomationAssumeRole:
       type: String
       description: '(Required) The Amazon Resource Name (ARN) of the IAM role that allows Automation to perform the actions on your behalf. If no role is specified, Systems Manager Automation uses your IAM permissions to operate this runbook.'
     PrimaryPatchGroupTag:
       type: StringMap
       description: '(Required) The tag for the primary group of instances you want to patch. Specify a key-value pair. Example: {"key" : "value"}'
     SecondaryPatchGroupTag:
       type: StringMap
       description: '(Required) The tag for the secondary group of instances you want to patch. Specify a key-value pair. Example: {"key" : "value"}'
     SnapshotId:
       type: String
       description: '(Optional) The snapshot ID to use to retrieve a patch baseline snapshot.'
       default: ''
     RebootOption:
       type: String
       description: '(Optional) Reboot behavior after a patch Install operation. If you choose NoReboot and patches are installed, the instance is marked as non-compliant until a subsequent reboot and scan.'
       allowedValues:
         - NoReboot
         - RebootIfNeeded
       default: RebootIfNeeded
     Operation:
       type: String
       description: '(Optional) The update or configuration to perform on the instance. The system checks if patches specified in the patch baseline are installed on the instance. The install operation installs patches missing from the baseline.'
       allowedValues:
         - Install
         - Scan
       default: Install
   mainSteps:
     - name: getPrimaryInstanceState
       action: 'aws:executeScript'
       timeoutSeconds: 120
       onFailure: Abort
       inputs:
         Runtime: python3.11
         Handler: getInstanceStates
         InputPayload:
           primaryTag: '{{PrimaryPatchGroupTag}}'
         Script: |-
           def getInstanceStates(events,context):
             import boto3
   
             #Initialize client
             ec2 = boto3.client('ec2')
             tag = events['primaryTag']
             tagKey, tagValue = list(tag.items())[0]
             instanceQuery = ec2.describe_instances(
             Filters=[
                 {
                     "Name": "tag:" + tagKey,
                     "Values": [tagValue]
                 }]
             )
             if not instanceQuery['Reservations']:
                 noInstancesForTagString = "No instances found for specified tag."
                 return({ 'noInstancesFound' : noInstancesForTagString })
             else:
                 queryResponse = instanceQuery['Reservations']
                 originalInstanceStates = {}
                 for results in queryResponse:
                     instanceSet = results['Instances']
                     for instance in instanceSet:
                         instanceId = instance['InstanceId']
                         originalInstanceStates[instanceId] = instance['State']['Name']
                 return originalInstanceStates
       outputs:
         - Name: originalInstanceStates
           Selector: $.Payload
           Type: StringMap
       nextStep: verifyPrimaryInstancesRunning
     - name: verifyPrimaryInstancesRunning
       action: 'aws:executeScript'
       timeoutSeconds: 600
       onFailure: Abort
       inputs:
         Runtime: python3.11
         Handler: verifyInstancesRunning
         InputPayload:
           targetInstances: '{{getPrimaryInstanceState.originalInstanceStates}}'
         Script: |-
           def verifyInstancesRunning(events,context):
             import boto3
   
             #Initialize client
             ec2 = boto3.client('ec2')
             instanceDict = events['targetInstances']
             for instance in instanceDict:
               if instanceDict[instance] == 'stopped':
                   print("The target instance " + instance + " is stopped. The instance will now be started.")
                   ec2.start_instances(
                       InstanceIds=[instance]
                       )
               elif instanceDict[instance] == 'stopping':
                   print("The target instance " + instance + " is stopping. Polling for instance to reach stopped state.")
                   while instanceDict[instance] != 'stopped':
                       poll = ec2.get_waiter('instance_stopped')
                       poll.wait(
                           InstanceIds=[instance]
                       )
                   ec2.start_instances(
                       InstanceIds=[instance]
                   )
               else:
                 pass
       nextStep: waitForPrimaryRunningInstances
     - name: waitForPrimaryRunningInstances
       action: 'aws:executeScript'
       timeoutSeconds: 300
       onFailure: Abort
       inputs:
         Runtime: python3.11
         Handler: waitForRunningInstances
         InputPayload:
           targetInstances: '{{getPrimaryInstanceState.originalInstanceStates}}'
         Script: |-
           def waitForRunningInstances(events,context):
             import boto3
   
             #Initialize client
             ec2 = boto3.client('ec2')
             instanceDict = events['targetInstances']
             for instance in instanceDict:
                 poll = ec2.get_waiter('instance_running')
                 poll.wait(
                     InstanceIds=[instance]
                 )
       nextStep: returnPrimaryTagKey
     - name: returnPrimaryTagKey
       action: 'aws:executeScript'
       timeoutSeconds: 120
       onFailure: Abort
       inputs:
         Runtime: python3.11
         Handler: returnTagValues
         InputPayload:
           primaryTag: '{{PrimaryPatchGroupTag}}'
         Script: |-
           def returnTagValues(events,context):
             tag = events['primaryTag']
             tagKey = list(tag)[0]
             stringKey = "tag:" + tagKey
             return {'tagKey' : stringKey}
       outputs:
         - Name: Payload
           Selector: $.Payload
           Type: StringMap
         - Name: primaryPatchGroupKey
           Selector: $.Payload.tagKey
           Type: String
       nextStep: returnPrimaryTagValue
     - name: returnPrimaryTagValue
       action: 'aws:executeScript'
       timeoutSeconds: 120
       onFailure: Abort
       inputs:
         Runtime: python3.11
         Handler: returnTagValues
         InputPayload:
           primaryTag: '{{PrimaryPatchGroupTag}}'
         Script: |-
           def returnTagValues(events,context):
             tag = events['primaryTag']
             tagKey = list(tag)[0]
             tagValue = tag[tagKey]
             return {'tagValue' : tagValue}
       outputs:
         - Name: Payload
           Selector: $.Payload
           Type: StringMap
         - Name: primaryPatchGroupValue
           Selector: $.Payload.tagValue
           Type: String
       nextStep: patchPrimaryInstances
     - name: patchPrimaryInstances
       action: 'aws:runCommand'
       onFailure: Abort
       timeoutSeconds: 7200
       inputs:
         DocumentName: AWS-RunPatchBaseline
         Parameters:
           SnapshotId: '{{SnapshotId}}'
           RebootOption: '{{RebootOption}}'
           Operation: '{{Operation}}'
         Targets:
           - Key: '{{returnPrimaryTagKey.primaryPatchGroupKey}}'
             Values:
               - '{{returnPrimaryTagValue.primaryPatchGroupValue}}'
         MaxConcurrency: 10%
         MaxErrors: 10%
       nextStep: returnPrimaryToOriginalState
     - name: returnPrimaryToOriginalState
       action: 'aws:executeScript'
       timeoutSeconds: 600
       onFailure: Abort
       inputs:
         Runtime: python3.11
         Handler: returnToOriginalState
         InputPayload:
           targetInstances: '{{getPrimaryInstanceState.originalInstanceStates}}'
         Script: |-
           def returnToOriginalState(events,context):
             import boto3
   
             #Initialize client
             ec2 = boto3.client('ec2')
             instanceDict = events['targetInstances']
             for instance in instanceDict:
               if instanceDict[instance] == 'stopped' or instanceDict[instance] == 'stopping':
                   ec2.stop_instances(
                       InstanceIds=[instance]
                       )
               else:
                 pass
       nextStep: getSecondaryInstanceState
     - name: getSecondaryInstanceState
       action: 'aws:executeScript'
       timeoutSeconds: 120
       onFailure: Abort
       inputs:
         Runtime: python3.11
         Handler: getInstanceStates
         InputPayload:
           secondaryTag: '{{SecondaryPatchGroupTag}}'
         Script: |-
           def getInstanceStates(events,context):
             import boto3
   
             #Initialize client
             ec2 = boto3.client('ec2')
             tag = events['secondaryTag']
             tagKey, tagValue = list(tag.items())[0]
             instanceQuery = ec2.describe_instances(
             Filters=[
                 {
                     "Name": "tag:" + tagKey,
                     "Values": [tagValue]
                 }]
             )
             if not instanceQuery['Reservations']:
                 noInstancesForTagString = "No instances found for specified tag."
                 return({ 'noInstancesFound' : noInstancesForTagString })
             else:
                 queryResponse = instanceQuery['Reservations']
                 originalInstanceStates = {}
                 for results in queryResponse:
                     instanceSet = results['Instances']
                     for instance in instanceSet:
                         instanceId = instance['InstanceId']
                         originalInstanceStates[instanceId] = instance['State']['Name']
                 return originalInstanceStates
       outputs:
         - Name: originalInstanceStates
           Selector: $.Payload
           Type: StringMap
       nextStep: verifySecondaryInstancesRunning
     - name: verifySecondaryInstancesRunning
       action: 'aws:executeScript'
       timeoutSeconds: 600
       onFailure: Abort
       inputs:
         Runtime: python3.11
         Handler: verifyInstancesRunning
         InputPayload:
           targetInstances: '{{getSecondaryInstanceState.originalInstanceStates}}'
         Script: |-
           def verifyInstancesRunning(events,context):
             import boto3
   
             #Initialize client
             ec2 = boto3.client('ec2')
             instanceDict = events['targetInstances']
             for instance in instanceDict:
               if instanceDict[instance] == 'stopped':
                   print("The target instance " + instance + " is stopped. The instance will now be started.")
                   ec2.start_instances(
                       InstanceIds=[instance]
                       )
               elif instanceDict[instance] == 'stopping':
                   print("The target instance " + instance + " is stopping. Polling for instance to reach stopped state.")
                   while instanceDict[instance] != 'stopped':
                       poll = ec2.get_waiter('instance_stopped')
                       poll.wait(
                           InstanceIds=[instance]
                       )
                   ec2.start_instances(
                       InstanceIds=[instance]
                   )
               else:
                 pass
       nextStep: waitForSecondaryRunningInstances
     - name: waitForSecondaryRunningInstances
       action: 'aws:executeScript'
       timeoutSeconds: 300
       onFailure: Abort
       inputs:
         Runtime: python3.11
         Handler: waitForRunningInstances
         InputPayload:
           targetInstances: '{{getSecondaryInstanceState.originalInstanceStates}}'
         Script: |-
           def waitForRunningInstances(events,context):
             import boto3
   
             #Initialize client
             ec2 = boto3.client('ec2')
             instanceDict = events['targetInstances']
             for instance in instanceDict:
                 poll = ec2.get_waiter('instance_running')
                 poll.wait(
                     InstanceIds=[instance]
                 )
       nextStep: returnSecondaryTagKey
     - name: returnSecondaryTagKey
       action: 'aws:executeScript'
       timeoutSeconds: 120
       onFailure: Abort
       inputs:
         Runtime: python3.11
         Handler: returnTagValues
         InputPayload:
           secondaryTag: '{{SecondaryPatchGroupTag}}'
         Script: |-
           def returnTagValues(events,context):
             tag = events['secondaryTag']
             tagKey = list(tag)[0]
             stringKey = "tag:" + tagKey
             return {'tagKey' : stringKey}
       outputs:
         - Name: Payload
           Selector: $.Payload
           Type: StringMap
         - Name: secondaryPatchGroupKey
           Selector: $.Payload.tagKey
           Type: String
       nextStep: returnSecondaryTagValue
     - name: returnSecondaryTagValue
       action: 'aws:executeScript'
       timeoutSeconds: 120
       onFailure: Abort
       inputs:
         Runtime: python3.11
         Handler: returnTagValues
         InputPayload:
           secondaryTag: '{{SecondaryPatchGroupTag}}'
         Script: |-
           def returnTagValues(events,context):
             tag = events['secondaryTag']
             tagKey = list(tag)[0]
             tagValue = tag[tagKey]
             return {'tagValue' : tagValue}
       outputs:
         - Name: Payload
           Selector: $.Payload
           Type: StringMap
         - Name: secondaryPatchGroupValue
           Selector: $.Payload.tagValue
           Type: String
       nextStep: patchSecondaryInstances
     - name: patchSecondaryInstances
       action: 'aws:runCommand'
       onFailure: Abort
       timeoutSeconds: 7200
       inputs:
         DocumentName: AWS-RunPatchBaseline
         Parameters:
           SnapshotId: '{{SnapshotId}}'
           RebootOption: '{{RebootOption}}'
           Operation: '{{Operation}}'
         Targets:
           - Key: '{{returnSecondaryTagKey.secondaryPatchGroupKey}}'
             Values:
             - '{{returnSecondaryTagValue.secondaryPatchGroupValue}}'
         MaxConcurrency: 10%
         MaxErrors: 10%
       nextStep: returnSecondaryToOriginalState
     - name: returnSecondaryToOriginalState
       action: 'aws:executeScript'
       timeoutSeconds: 600
       onFailure: Abort
       inputs:
         Runtime: python3.11
         Handler: returnToOriginalState
         InputPayload:
           targetInstances: '{{getSecondaryInstanceState.originalInstanceStates}}'
         Script: |-
           def returnToOriginalState(events,context):
             import boto3
   
             #Initialize client
             ec2 = boto3.client('ec2')
             instanceDict = events['targetInstances']
             for instance in instanceDict:
               if instanceDict[instance] == 'stopped' or instanceDict[instance] == 'stopping':
                   ec2.stop_instances(
                       InstanceIds=[instance]
                       )
               else:
                 pass
   ```

------
#### [ JSON ]

   ```
   {
      "description":"An example of an Automation runbook that patches groups of Amazon EC2 instances in stages.",
      "schemaVersion":"0.3",
      "assumeRole":"{{AutomationAssumeRole}}",
      "parameters":{
         "AutomationAssumeRole":{
            "type":"String",
            "description":"(Required) The Amazon Resource Name (ARN) of the IAM role that allows Automation to perform the actions on your behalf. If no role is specified, Systems Manager Automation uses your IAM permissions to operate this runbook."
         },
         "PrimaryPatchGroupTag":{
            "type":"StringMap",
            "description":"(Required) The tag for the primary group of instances you want to patch. Specify a key-value pair. Example: {\"key\" : \"value\"}"
         },
         "SecondaryPatchGroupTag":{
            "type":"StringMap",
            "description":"(Required) The tag for the secondary group of instances you want to patch. Specify a key-value pair. Example: {\"key\" : \"value\"}"
         },
         "SnapshotId":{
            "type":"String",
            "description":"(Optional) The snapshot ID to use to retrieve a patch baseline snapshot.",
            "default":""
         },
         "RebootOption":{
            "type":"String",
            "description":"(Optional) Reboot behavior after a patch Install operation. If you choose NoReboot and patches are installed, the instance is marked as non-compliant until a subsequent reboot and scan.",
            "allowedValues":[
               "NoReboot",
               "RebootIfNeeded"
            ],
            "default":"RebootIfNeeded"
         },
         "Operation":{
            "type":"String",
            "description":"(Optional) The update or configuration to perform on the instance. The system checks if patches specified in the patch baseline are installed on the instance. The install operation installs patches missing from the baseline.",
            "allowedValues":[
               "Install",
               "Scan"
            ],
            "default":"Install"
         }
      },
      "mainSteps":[
         {
            "name":"getPrimaryInstanceState",
            "action":"aws:executeScript",
            "timeoutSeconds":120,
            "onFailure":"Abort",
            "inputs":{
               "Runtime":"python3.11",
               "Handler":"getInstanceStates",
               "InputPayload":{
                  "primaryTag":"{{PrimaryPatchGroupTag}}"
               },
               "Script":"..."
            },
            "outputs":[
               {
                  "Name":"originalInstanceStates",
                  "Selector":"$.Payload",
                  "Type":"StringMap"
               }
            ],
            "nextStep":"verifyPrimaryInstancesRunning"
         },
         {
            "name":"verifyPrimaryInstancesRunning",
            "action":"aws:executeScript",
            "timeoutSeconds":600,
            "onFailure":"Abort",
            "inputs":{
               "Runtime":"python3.11",
               "Handler":"verifyInstancesRunning",
               "InputPayload":{
                  "targetInstances":"{{getPrimaryInstanceState.originalInstanceStates}}"
               },
               "Script":"..."
            },
            "nextStep":"waitForPrimaryRunningInstances"
         },
         {
            "name":"waitForPrimaryRunningInstances",
            "action":"aws:executeScript",
            "timeoutSeconds":300,
            "onFailure":"Abort",
            "inputs":{
               "Runtime":"python3.11",
               "Handler":"waitForRunningInstances",
               "InputPayload":{
                  "targetInstances":"{{getPrimaryInstanceState.originalInstanceStates}}"
               },
               "Script":"..."
            },
            "nextStep":"returnPrimaryTagKey"
         },
         {
            "name":"returnPrimaryTagKey",
            "action":"aws:executeScript",
            "timeoutSeconds":120,
            "onFailure":"Abort",
            "inputs":{
               "Runtime":"python3.11",
               "Handler":"returnTagValues",
               "InputPayload":{
                  "primaryTag":"{{PrimaryPatchGroupTag}}"
               },
               "Script":"..."
            },
            "outputs":[
               {
                  "Name":"Payload",
                  "Selector":"$.Payload",
                  "Type":"StringMap"
               },
               {
                  "Name":"primaryPatchGroupKey",
                  "Selector":"$.Payload.tagKey",
                  "Type":"String"
               }
            ],
            "nextStep":"returnPrimaryTagValue"
         },
         {
            "name":"returnPrimaryTagValue",
            "action":"aws:executeScript",
            "timeoutSeconds":120,
            "onFailure":"Abort",
            "inputs":{
               "Runtime":"python3.11",
               "Handler":"returnTagValues",
               "InputPayload":{
                  "primaryTag":"{{PrimaryPatchGroupTag}}"
               },
               "Script":"..."
            },
            "outputs":[
               {
                  "Name":"Payload",
                  "Selector":"$.Payload",
                  "Type":"StringMap"
               },
               {
                  "Name":"primaryPatchGroupValue",
                  "Selector":"$.Payload.tagValue",
                  "Type":"String"
               }
            ],
            "nextStep":"patchPrimaryInstances"
         },
         {
            "name":"patchPrimaryInstances",
            "action":"aws:runCommand",
            "onFailure":"Abort",
            "timeoutSeconds":7200,
            "inputs":{
               "DocumentName":"AWS-RunPatchBaseline",
               "Parameters":{
                  "SnapshotId":"{{SnapshotId}}",
                  "RebootOption":"{{RebootOption}}",
                  "Operation":"{{Operation}}"
               },
               "Targets":[
                  {
                     "Key":"{{returnPrimaryTagKey.primaryPatchGroupKey}}",
                     "Values":[
                        "{{returnPrimaryTagValue.primaryPatchGroupValue}}"
                     ]
                  }
               ],
               "MaxConcurrency":"10%",
               "MaxErrors":"10%"
            },
            "nextStep":"returnPrimaryToOriginalState"
         },
         {
            "name":"returnPrimaryToOriginalState",
            "action":"aws:executeScript",
            "timeoutSeconds":600,
            "onFailure":"Abort",
            "inputs":{
               "Runtime":"python3.11",
               "Handler":"returnToOriginalState",
               "InputPayload":{
                  "targetInstances":"{{getPrimaryInstanceState.originalInstanceStates}}"
               },
               "Script":"..."
            },
            "nextStep":"getSecondaryInstanceState"
         },
         {
            "name":"getSecondaryInstanceState",
            "action":"aws:executeScript",
            "timeoutSeconds":120,
            "onFailure":"Abort",
            "inputs":{
               "Runtime":"python3.11",
               "Handler":"getInstanceStates",
               "InputPayload":{
                  "secondaryTag":"{{SecondaryPatchGroupTag}}"
               },
               "Script":"..."
            },
            "outputs":[
               {
                  "Name":"originalInstanceStates",
                  "Selector":"$.Payload",
                  "Type":"StringMap"
               }
            ],
            "nextStep":"verifySecondaryInstancesRunning"
         },
         {
            "name":"verifySecondaryInstancesRunning",
            "action":"aws:executeScript",
            "timeoutSeconds":600,
            "onFailure":"Abort",
            "inputs":{
               "Runtime":"python3.11",
               "Handler":"verifyInstancesRunning",
               "InputPayload":{
                  "targetInstances":"{{getSecondaryInstanceState.originalInstanceStates}}"
               },
               "Script":"..."
            },
            "nextStep":"waitForSecondaryRunningInstances"
         },
         {
            "name":"waitForSecondaryRunningInstances",
            "action":"aws:executeScript",
            "timeoutSeconds":300,
            "onFailure":"Abort",
            "inputs":{
               "Runtime":"python3.11",
               "Handler":"waitForRunningInstances",
               "InputPayload":{
                  "targetInstances":"{{getSecondaryInstanceState.originalInstanceStates}}"
               },
               "Script":"..."
            },
            "nextStep":"returnSecondaryTagKey"
         },
         {
            "name":"returnSecondaryTagKey",
            "action":"aws:executeScript",
            "timeoutSeconds":120,
            "onFailure":"Abort",
            "inputs":{
               "Runtime":"python3.11",
               "Handler":"returnTagValues",
               "InputPayload":{
                  "secondaryTag":"{{SecondaryPatchGroupTag}}"
               },
               "Script":"..."
            },
            "outputs":[
               {
                  "Name":"Payload",
                  "Selector":"$.Payload",
                  "Type":"StringMap"
               },
               {
                  "Name":"secondaryPatchGroupKey",
                  "Selector":"$.Payload.tagKey",
                  "Type":"String"
               }
            ],
            "nextStep":"returnSecondaryTagValue"
         },
         {
            "name":"returnSecondaryTagValue",
            "action":"aws:executeScript",
            "timeoutSeconds":120,
            "onFailure":"Abort",
            "inputs":{
               "Runtime":"python3.11",
               "Handler":"returnTagValues",
               "InputPayload":{
                  "secondaryTag":"{{SecondaryPatchGroupTag}}"
               },
               "Script":"..."
            },
            "outputs":[
               {
                  "Name":"Payload",
                  "Selector":"$.Payload",
                  "Type":"StringMap"
               },
               {
                  "Name":"secondaryPatchGroupValue",
                  "Selector":"$.Payload.tagValue",
                  "Type":"String"
               }
            ],
            "nextStep":"patchSecondaryInstances"
         },
         {
            "name":"patchSecondaryInstances",
            "action":"aws:runCommand",
            "onFailure":"Abort",
            "timeoutSeconds":7200,
            "inputs":{
               "DocumentName":"AWS-RunPatchBaseline",
               "Parameters":{
                  "SnapshotId":"{{SnapshotId}}",
                  "RebootOption":"{{RebootOption}}",
                  "Operation":"{{Operation}}"
               },
               "Targets":[
                  {
                     "Key":"{{returnSecondaryTagKey.secondaryPatchGroupKey}}",
                     "Values":[
                        "{{returnSecondaryTagValue.secondaryPatchGroupValue}}"
                     ]
                  }
               ],
               "MaxConcurrency":"10%",
               "MaxErrors":"10%"
            },
            "nextStep":"returnSecondaryToOriginalState"
         },
         {
            "name":"returnSecondaryToOriginalState",
            "action":"aws:executeScript",
            "timeoutSeconds":600,
            "onFailure":"Abort",
            "inputs":{
               "Runtime":"python3.11",
               "Handler":"returnToOriginalState",
               "InputPayload":{
                  "targetInstances":"{{getSecondaryInstanceState.originalInstanceStates}}"
               },
               "Script":"..."
            }
         }
      ]
   }
   ```

------

For more information about the automation actions used in this example, see the [Systems Manager Automation actions reference](automation-actions.md).

# Additional runbook examples
<a name="automation-document-examples"></a>

The following example runbook demonstrate how you can use AWS Systems Manager automation actions to automate common deployment, troubleshooting, and maintenance tasks.

**Note**  
The example runbooks in this section are provided to demonstrate how you can create custom runbooks to support your specific operational needs. These runbooks aren't meant for use in production environments as is. However, you can customize them for your own use.

**Topics**
+ [Deploy VPC architecture and Microsoft Active Directory domain controllers](automation-document-architecture-deployment-example.md)
+ [Restore a root volume from the latest snapshot](automation-document-instance-recovery-example.md)
+ [Create an AMI and cross-Region copy](automation-document-backup-maintenance-example.md)

# Deploy VPC architecture and Microsoft Active Directory domain controllers
<a name="automation-document-architecture-deployment-example"></a>

To increase efficiency and standardize common tasks, you might choose to automate deployments. This is useful if you regularly deploy the same architecture across multiple accounts and AWS Regions. Automating architecture deployments can also reduce the potential for human error that can occur when deploying architecture manually. AWS Systems Manager Automation actions can help you accomplish this. Automation is a tool in AWS Systems Manager.

The following example AWS Systems Manager runbook performs these actions:
+ Retrieves the latest Windows Server 2016 Amazon Machine Image (AMI) using Systems Manager Parameter Store to use when launching the EC2 instances that will be configured as domain controllers. Parameter Store is a tool in AWS Systems Manager.
+ Uses the `aws:executeAwsApi` automation action to call several AWS API operations to create the VPC architecture. The domain controller instances are launched in private subnets, and connect to the internet using a NAT gateway. This allows the SSM Agent on the instances to access the requisite Systems Manager endpoints.
+ Uses the `aws:waitForAwsResourceProperty` automation action to confirm the instances launched by the previous action are `Online` for AWS Systems Manager.
+ Uses the `aws:runCommand` automation action to configure the instances launched as Microsoft Active Directory domain controllers.

------
#### [ YAML ]

```
    ---
    description: Custom Automation Deployment Example
    schemaVersion: '0.3'
    parameters:
      AutomationAssumeRole:
        type: String
        default: ''
        description: >-
          (Optional) The ARN of the role that allows Automation to perform the
          actions on your behalf. If no role is specified, Systems Manager
          Automation uses your IAM permissions to run this runbook.
    mainSteps:
      - name: getLatestWindowsAmi
        action: aws:executeAwsApi
        onFailure: Abort
        inputs:
          Service: ssm
          Api: GetParameter
          Name: >-
            /aws/service/ami-windows-latest/Windows_Server-2016-English-Full-Base
        outputs:
          - Name: amiId
            Selector: $.Parameter.Value
            Type: String
        nextStep: createSSMInstanceRole
      - name: createSSMInstanceRole
        action: aws:executeAwsApi
        onFailure: Abort
        inputs:
          Service: iam
          Api: CreateRole
          AssumeRolePolicyDocument: >-
            {"Version": "2012-10-17",		 	 	 "Statement":[{"Effect":"Allow","Principal":{"Service":["ec2.amazonaws.com"]},"Action":["sts:AssumeRole"]}]}
          RoleName: sampleSSMInstanceRole
        nextStep: attachManagedSSMPolicy
      - name: attachManagedSSMPolicy
        action: aws:executeAwsApi
        onFailure: Abort
        inputs:
          Service: iam
          Api: AttachRolePolicy
          PolicyArn: 'arn:aws:iam::aws:policy/service-role/AmazonSSMManagedInstanceCore'
          RoleName: sampleSSMInstanceRole
        nextStep: createSSMInstanceProfile
      - name: createSSMInstanceProfile
        action: aws:executeAwsApi
        onFailure: Abort
        inputs:
          Service: iam
          Api: CreateInstanceProfile
          InstanceProfileName: sampleSSMInstanceRole
        outputs:
          - Name: instanceProfileArn
            Selector: $.InstanceProfile.Arn
            Type: String
        nextStep: addSSMInstanceRoleToProfile
      - name: addSSMInstanceRoleToProfile
        action: aws:executeAwsApi
        onFailure: Abort
        inputs:
          Service: iam
          Api: AddRoleToInstanceProfile
          InstanceProfileName: sampleSSMInstanceRole
          RoleName: sampleSSMInstanceRole
        nextStep: createVpc
      - name: createVpc
        action: aws:executeAwsApi
        onFailure: Abort
        inputs:
          Service: ec2
          Api: CreateVpc
          CidrBlock: 10.0.100.0/22
        outputs:
          - Name: vpcId
            Selector: $.Vpc.VpcId
            Type: String
        nextStep: getMainRtb
      - name: getMainRtb
        action: aws:executeAwsApi
        onFailure: Abort
        inputs:
          Service: ec2
          Api: DescribeRouteTables
          Filters:
            - Name: vpc-id
              Values:
                - '{{ createVpc.vpcId }}'
        outputs:
          - Name: mainRtbId
            Selector: '$.RouteTables[0].RouteTableId'
            Type: String
        nextStep: verifyMainRtb
      - name: verifyMainRtb
        action: aws:assertAwsResourceProperty
        onFailure: Abort
        inputs:
          Service: ec2
          Api: DescribeRouteTables
          RouteTableIds:
            - '{{ getMainRtb.mainRtbId }}'
          PropertySelector: '$.RouteTables[0].Associations[0].Main'
          DesiredValues:
            - 'True'
        nextStep: createPubSubnet
      - name: createPubSubnet
        action: aws:executeAwsApi
        onFailure: Abort
        inputs:
          Service: ec2
          Api: CreateSubnet
          CidrBlock: 10.0.103.0/24
          AvailabilityZone: us-west-2c
          VpcId: '{{ createVpc.vpcId }}'
        outputs:
          - Name: pubSubnetId
            Selector: $.Subnet.SubnetId
            Type: String
        nextStep: createPubRtb
      - name: createPubRtb
        action: aws:executeAwsApi
        onFailure: Abort
        inputs:
          Service: ec2
          Api: CreateRouteTable
          VpcId: '{{ createVpc.vpcId }}'
        outputs:
          - Name: pubRtbId
            Selector: $.RouteTable.RouteTableId
            Type: String
        nextStep: createIgw
      - name: createIgw
        action: aws:executeAwsApi
        onFailure: Abort
        inputs:
          Service: ec2
          Api: CreateInternetGateway
        outputs:
          - Name: igwId
            Selector: $.InternetGateway.InternetGatewayId
            Type: String
        nextStep: attachIgw
      - name: attachIgw
        action: aws:executeAwsApi
        onFailure: Abort
        inputs:
          Service: ec2
          Api: AttachInternetGateway
          InternetGatewayId: '{{ createIgw.igwId }}'
          VpcId: '{{ createVpc.vpcId }}'
        nextStep: allocateEip
      - name: allocateEip
        action: aws:executeAwsApi
        onFailure: Abort
        inputs:
          Service: ec2
          Api: AllocateAddress
          Domain: vpc
        outputs:
          - Name: eipAllocationId
            Selector: $.AllocationId
            Type: String
        nextStep: createNatGw
      - name: createNatGw
        action: aws:executeAwsApi
        onFailure: Abort
        inputs:
          Service: ec2
          Api: CreateNatGateway
          AllocationId: '{{ allocateEip.eipAllocationId }}'
          SubnetId: '{{ createPubSubnet.pubSubnetId }}'
        outputs:
          - Name: natGwId
            Selector: $.NatGateway.NatGatewayId
            Type: String
        nextStep: verifyNatGwAvailable
      - name: verifyNatGwAvailable
        action: aws:waitForAwsResourceProperty
        timeoutSeconds: 150
        inputs:
          Service: ec2
          Api: DescribeNatGateways
          NatGatewayIds:
            - '{{ createNatGw.natGwId }}'
          PropertySelector: '$.NatGateways[0].State'
          DesiredValues:
            - available
        nextStep: createNatRoute
      - name: createNatRoute
        action: aws:executeAwsApi
        onFailure: Abort
        inputs:
          Service: ec2
          Api: CreateRoute
          DestinationCidrBlock: 0.0.0.0/0
          NatGatewayId: '{{ createNatGw.natGwId }}'
          RouteTableId: '{{ getMainRtb.mainRtbId }}'
        nextStep: createPubRoute
      - name: createPubRoute
        action: aws:executeAwsApi
        onFailure: Abort
        inputs:
          Service: ec2
          Api: CreateRoute
          DestinationCidrBlock: 0.0.0.0/0
          GatewayId: '{{ createIgw.igwId }}'
          RouteTableId: '{{ createPubRtb.pubRtbId }}'
        nextStep: setPubSubAssoc
      - name: setPubSubAssoc
        action: aws:executeAwsApi
        onFailure: Abort
        inputs:
          Service: ec2
          Api: AssociateRouteTable
          RouteTableId: '{{ createPubRtb.pubRtbId }}'
          SubnetId: '{{ createPubSubnet.pubSubnetId }}'
      - name: createDhcpOptions
        action: aws:executeAwsApi
        onFailure: Abort
        inputs:
          Service: ec2
          Api: CreateDhcpOptions
          DhcpConfigurations:
            - Key: domain-name-servers
              Values:
                - '10.0.100.50,10.0.101.50'
            - Key: domain-name
              Values:
                - sample.com
        outputs:
          - Name: dhcpOptionsId
            Selector: $.DhcpOptions.DhcpOptionsId
            Type: String
        nextStep: createDCSubnet1
      - name: createDCSubnet1
        action: aws:executeAwsApi
        onFailure: Abort
        inputs:
          Service: ec2
          Api: CreateSubnet
          CidrBlock: 10.0.100.0/24
          AvailabilityZone: us-west-2a
          VpcId: '{{ createVpc.vpcId }}'
        outputs:
          - Name: firstSubnetId
            Selector: $.Subnet.SubnetId
            Type: String
        nextStep: createDCSubnet2
      - name: createDCSubnet2
        action: aws:executeAwsApi
        onFailure: Abort
        inputs:
          Service: ec2
          Api: CreateSubnet
          CidrBlock: 10.0.101.0/24
          AvailabilityZone: us-west-2b
          VpcId: '{{ createVpc.vpcId }}'
        outputs:
          - Name: secondSubnetId
            Selector: $.Subnet.SubnetId
            Type: String
        nextStep: createDCSecGroup
      - name: createDCSecGroup
        action: aws:executeAwsApi
        onFailure: Abort
        inputs:
          Service: ec2
          Api: CreateSecurityGroup
          GroupName: SampleDCSecGroup
          Description: Security Group for Sample Domain Controllers
          VpcId: '{{ createVpc.vpcId }}'
        outputs:
          - Name: dcSecGroupId
            Selector: $.GroupId
            Type: String
        nextStep: authIngressDCTraffic
      - name: authIngressDCTraffic
        action: aws:executeAwsApi
        onFailure: Abort
        inputs:
          Service: ec2
          Api: AuthorizeSecurityGroupIngress
          GroupId: '{{ createDCSecGroup.dcSecGroupId }}'
          IpPermissions:
            - FromPort: -1
              IpProtocol: '-1'
              IpRanges:
                - CidrIp: 0.0.0.0/0
                  Description: Allow all traffic between Domain Controllers
        nextStep: verifyInstanceProfile
      - name: verifyInstanceProfile
        action: aws:waitForAwsResourceProperty
        maxAttempts: 5
        onFailure: Abort
        inputs:
          Service: iam
          Api: ListInstanceProfilesForRole
          RoleName: sampleSSMInstanceRole
          PropertySelector: '$.InstanceProfiles[0].Arn'
          DesiredValues:
            - '{{ createSSMInstanceProfile.instanceProfileArn }}'
        nextStep: iamEventualConsistency
      - name: iamEventualConsistency
        action: aws:sleep
        inputs:
          Duration: PT2M
        nextStep: launchDC1
      - name: launchDC1
        action: aws:executeAwsApi
        onFailure: Abort
        inputs:
          Service: ec2
          Api: RunInstances
          BlockDeviceMappings:
            - DeviceName: /dev/sda1
              Ebs:
                DeleteOnTermination: true
                VolumeSize: 50
                VolumeType: gp2
            - DeviceName: xvdf
              Ebs:
                DeleteOnTermination: true
                VolumeSize: 100
                VolumeType: gp2
          IamInstanceProfile:
            Arn: '{{ createSSMInstanceProfile.instanceProfileArn }}'
          ImageId: '{{ getLatestWindowsAmi.amiId }}'
          InstanceType: t2.micro
          MaxCount: 1
          MinCount: 1
          PrivateIpAddress: 10.0.100.50
          SecurityGroupIds:
            - '{{ createDCSecGroup.dcSecGroupId }}'
          SubnetId: '{{ createDCSubnet1.firstSubnetId }}'
          TagSpecifications:
            - ResourceType: instance
              Tags:
                - Key: Name
                  Value: SampleDC1
        outputs:
          - Name: pdcInstanceId
            Selector: '$.Instances[0].InstanceId'
            Type: String
        nextStep: launchDC2
      - name: launchDC2
        action: aws:executeAwsApi
        onFailure: Abort
        inputs:
          Service: ec2
          Api: RunInstances
          BlockDeviceMappings:
            - DeviceName: /dev/sda1
              Ebs:
                DeleteOnTermination: true
                VolumeSize: 50
                VolumeType: gp2
            - DeviceName: xvdf
              Ebs:
                DeleteOnTermination: true
                VolumeSize: 100
                VolumeType: gp2
          IamInstanceProfile:
            Arn: '{{ createSSMInstanceProfile.instanceProfileArn }}'
          ImageId: '{{ getLatestWindowsAmi.amiId }}'
          InstanceType: t2.micro
          MaxCount: 1
          MinCount: 1
          PrivateIpAddress: 10.0.101.50
          SecurityGroupIds:
            - '{{ createDCSecGroup.dcSecGroupId }}'
          SubnetId: '{{ createDCSubnet2.secondSubnetId }}'
          TagSpecifications:
            - ResourceType: instance
              Tags:
                - Key: Name
                  Value: SampleDC2
        outputs:
          - Name: adcInstanceId
            Selector: '$.Instances[0].InstanceId'
            Type: String
        nextStep: verifyDCInstanceState
      - name: verifyDCInstanceState
        action: aws:waitForAwsResourceProperty
        inputs:
          Service: ec2
          Api: DescribeInstanceStatus
          IncludeAllInstances: true
          InstanceIds:
            - '{{ launchDC1.pdcInstanceId }}'
            - '{{ launchDC2.adcInstanceId }}'
          PropertySelector: '$.InstanceStatuses..InstanceState.Name'
          DesiredValues:
            - running
        nextStep: verifyInstancesOnlineSSM
      - name: verifyInstancesOnlineSSM
        action: aws:waitForAwsResourceProperty
        timeoutSeconds: 600
        inputs:
          Service: ssm
          Api: DescribeInstanceInformation
          InstanceInformationFilterList:
            - key: InstanceIds
              valueSet:
                - '{{ launchDC1.pdcInstanceId }}'
                - '{{ launchDC2.adcInstanceId }}'
          PropertySelector: '$.InstanceInformationList..PingStatus'
          DesiredValues:
            - Online
        nextStep: installADRoles
      - name: installADRoles
        action: aws:runCommand
        inputs:
          DocumentName: AWS-RunPowerShellScript
          InstanceIds:
            - '{{ launchDC1.pdcInstanceId }}'
            - '{{ launchDC2.adcInstanceId }}'
          Parameters:
            commands: |-
              try {
                  Install-WindowsFeature -Name AD-Domain-Services -IncludeManagementTools
              }
              catch {
                  Write-Error "Failed to install ADDS Role."
              }
        nextStep: setAdminPassword
      - name: setAdminPassword
        action: aws:runCommand
        inputs:
          DocumentName: AWS-RunPowerShellScript
          InstanceIds:
            - '{{ launchDC1.pdcInstanceId }}'
          Parameters:
            commands:
              - net user Administrator "sampleAdminPass123!"
        nextStep: createForest
      - name: createForest
        action: aws:runCommand
        inputs:
          DocumentName: AWS-RunPowerShellScript
          InstanceIds:
            - '{{ launchDC1.pdcInstanceId }}'
          Parameters:
            commands: |-
              $dsrmPass = 'sample123!' | ConvertTo-SecureString -asPlainText -Force
              try {
                  Install-ADDSForest -DomainName "sample.com" -DomainMode 6 -ForestMode 6 -InstallDNS -DatabasePath "D:\NTDS" -SysvolPath "D:\SYSVOL" -SafeModeAdministratorPassword $dsrmPass -Force
              }
              catch {
                  Write-Error $_
              }
              try {
                  Add-DnsServerForwarder -IPAddress "10.0.100.2"
              }
              catch {
                  Write-Error $_
              }
        nextStep: associateDhcpOptions
      - name: associateDhcpOptions
        action: aws:executeAwsApi
        onFailure: Abort
        inputs:
          Service: ec2
          Api: AssociateDhcpOptions
          DhcpOptionsId: '{{ createDhcpOptions.dhcpOptionsId }}'
          VpcId: '{{ createVpc.vpcId }}'
        nextStep: waitForADServices
      - name: waitForADServices
        action: aws:sleep
        inputs:
          Duration: PT1M
        nextStep: promoteADC
      - name: promoteADC
        action: aws:runCommand
        inputs:
          DocumentName: AWS-RunPowerShellScript
          InstanceIds:
            - '{{ launchDC2.adcInstanceId }}'
          Parameters:
            commands: |-
              ipconfig /renew
              $dsrmPass = 'sample123!' | ConvertTo-SecureString -asPlainText -Force
              $domAdminUser = "sample\Administrator"
              $domAdminPass = "sampleAdminPass123!" | ConvertTo-SecureString -asPlainText -Force
              $domAdminCred = New-Object System.Management.Automation.PSCredential($domAdminUser,$domAdminPass)
    
              try {
                  Install-ADDSDomainController -DomainName "sample.com" -InstallDNS -DatabasePath "D:\NTDS" -SysvolPath "D:\SYSVOL" -SafeModeAdministratorPassword $dsrmPass -Credential $domAdminCred -Force
              }
              catch {
                  Write-Error $_
              }
```

------
#### [ JSON ]

```
{
      "description": "Custom Automation Deployment Example",
      "schemaVersion": "0.3",
      "assumeRole": "{{ AutomationAssumeRole }}",
      "parameters": {
        "AutomationAssumeRole": {
          "type": "String",
          "description": "(Optional) The ARN of the role that allows Automation to perform the actions on your behalf. If no role is specified, Systems Manager Automation uses your IAM permissions to run this runbook.",
          "default": ""
        }
      },
      "mainSteps": [
        {
          "name": "getLatestWindowsAmi",
          "action": "aws:executeAwsApi",
          "onFailure": "Abort",
          "inputs": {
            "Service": "ssm",
            "Api": "GetParameter",
            "Name": "/aws/service/ami-windows-latest/Windows_Server-2016-English-Full-Base"
          },
          "outputs": [
            {
              "Name": "amiId",
              "Selector": "$.Parameter.Value",
              "Type": "String"
            }
          ],
          "nextStep": "createSSMInstanceRole"
        },
        {
          "name": "createSSMInstanceRole",
          "action": "aws:executeAwsApi",
          "onFailure": "Abort",
          "inputs": {
            "Service": "iam",
            "Api": "CreateRole",
            "AssumeRolePolicyDocument": "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Effect\":\"Allow\",\"Principal\":{\"Service\":[\"ec2.amazonaws.com\"]},\"Action\":[\"sts:AssumeRole\"]}]}",
            "RoleName": "sampleSSMInstanceRole"
          },
          "nextStep": "attachManagedSSMPolicy"
        },
        {
          "name": "attachManagedSSMPolicy",
          "action": "aws:executeAwsApi",
          "onFailure": "Abort",
          "inputs": {
            "Service": "iam",
            "Api": "AttachRolePolicy",
            "PolicyArn": "arn:aws:iam::aws:policy/service-role/AmazonSSMManagedInstanceCore",
            "RoleName": "sampleSSMInstanceRole"
          },
          "nextStep": "createSSMInstanceProfile"
        },
        {
          "name": "createSSMInstanceProfile",
          "action":"aws:executeAwsApi",
          "onFailure": "Abort",
          "inputs": {
            "Service": "iam",
            "Api": "CreateInstanceProfile",
            "InstanceProfileName": "sampleSSMInstanceRole"
          },
          "outputs": [
            {
              "Name": "instanceProfileArn",
              "Selector": "$.InstanceProfile.Arn",
              "Type": "String"
            }
          ],
          "nextStep": "addSSMInstanceRoleToProfile"
        },
        {
          "name": "addSSMInstanceRoleToProfile",
          "action": "aws:executeAwsApi",
          "onFailure": "Abort",
          "inputs": {
            "Service": "iam",
            "Api": "AddRoleToInstanceProfile",
            "InstanceProfileName": "sampleSSMInstanceRole",
            "RoleName": "sampleSSMInstanceRole"
          },
          "nextStep": "createVpc"
        },
        {
          "name": "createVpc",
          "action": "aws:executeAwsApi",
          "onFailure": "Abort",
          "inputs": {
            "Service": "ec2",
            "Api": "CreateVpc",
            "CidrBlock": "10.0.100.0/22"
          },
          "outputs": [
            {
              "Name": "vpcId",
              "Selector": "$.Vpc.VpcId",
              "Type": "String"
            }
          ],
          "nextStep": "getMainRtb"
        },
        {
          "name": "getMainRtb",
          "action": "aws:executeAwsApi",
          "onFailure": "Abort",
          "inputs": {
            "Service": "ec2",
            "Api": "DescribeRouteTables",
            "Filters": [
              {
                "Name": "vpc-id",
                "Values": ["{{ createVpc.vpcId }}"]
              }
            ]
          },
          "outputs": [
            {
              "Name": "mainRtbId",
              "Selector": "$.RouteTables[0].RouteTableId",
              "Type": "String"
            }
          ],
          "nextStep": "verifyMainRtb"
        },
        {
          "name": "verifyMainRtb",
          "action": "aws:assertAwsResourceProperty",
          "onFailure": "Abort",
          "inputs": {
            "Service": "ec2",
            "Api": "DescribeRouteTables",
            "RouteTableIds": ["{{ getMainRtb.mainRtbId }}"],
            "PropertySelector": "$.RouteTables[0].Associations[0].Main",
            "DesiredValues": ["True"]
          },
          "nextStep": "createPubSubnet"
        },
        {
          "name": "createPubSubnet",
          "action": "aws:executeAwsApi",
          "onFailure": "Abort",
          "inputs": {
            "Service": "ec2",
            "Api": "CreateSubnet",
            "CidrBlock": "10.0.103.0/24",
            "AvailabilityZone": "us-west-2c",
            "VpcId": "{{ createVpc.vpcId }}"
          },
          "outputs":[
            {
              "Name": "pubSubnetId",
              "Selector": "$.Subnet.SubnetId",
              "Type": "String"
            }
          ],
          "nextStep": "createPubRtb"
        },
        {
          "name": "createPubRtb",
          "action": "aws:executeAwsApi",
          "onFailure": "Abort",
          "inputs": {
            "Service": "ec2",
            "Api": "CreateRouteTable",
            "VpcId": "{{ createVpc.vpcId }}"
          },
          "outputs": [
            {
              "Name": "pubRtbId",
              "Selector": "$.RouteTable.RouteTableId",
              "Type": "String"
            }
          ],
          "nextStep": "createIgw"
        },
        {
          "name": "createIgw",
          "action": "aws:executeAwsApi",
          "onFailure": "Abort",
          "inputs": {
            "Service": "ec2",
            "Api": "CreateInternetGateway"
          },
          "outputs": [
            {
              "Name": "igwId",
              "Selector": "$.InternetGateway.InternetGatewayId",
              "Type": "String"
            }
          ],
          "nextStep": "attachIgw"
        },
        {
          "name": "attachIgw",
          "action": "aws:executeAwsApi",
          "onFailure": "Abort",
          "inputs": {
            "Service": "ec2",
            "Api": "AttachInternetGateway",
            "InternetGatewayId": "{{ createIgw.igwId }}",
            "VpcId": "{{ createVpc.vpcId }}"
          },
          "nextStep": "allocateEip"
        },
        {
          "name": "allocateEip",
          "action": "aws:executeAwsApi",
          "onFailure": "Abort",
          "inputs": {
            "Service": "ec2",
            "Api": "AllocateAddress",
            "Domain": "vpc"
          },
          "outputs": [
            {
              "Name": "eipAllocationId",
              "Selector": "$.AllocationId",
              "Type": "String"
            }
          ],
          "nextStep": "createNatGw"
        },
        {
          "name": "createNatGw",
          "action": "aws:executeAwsApi",
          "onFailure": "Abort",
          "inputs": {
            "Service": "ec2",
            "Api": "CreateNatGateway",
            "AllocationId": "{{ allocateEip.eipAllocationId }}",
            "SubnetId": "{{ createPubSubnet.pubSubnetId }}"
          },
          "outputs":[
            {
              "Name": "natGwId",
              "Selector": "$.NatGateway.NatGatewayId",
              "Type": "String"
            }
          ],
          "nextStep": "verifyNatGwAvailable"
        },
        {
          "name": "verifyNatGwAvailable",
          "action": "aws:waitForAwsResourceProperty",
          "timeoutSeconds": 150,
          "inputs": {
            "Service": "ec2",
            "Api": "DescribeNatGateways",
            "NatGatewayIds": [
              "{{ createNatGw.natGwId }}"
            ],
            "PropertySelector": "$.NatGateways[0].State",
            "DesiredValues": [
              "available"
            ]
          },
          "nextStep": "createNatRoute"
        },
        {
          "name": "createNatRoute",
          "action": "aws:executeAwsApi",
          "onFailure": "Abort",
          "inputs": {
            "Service": "ec2",
            "Api": "CreateRoute",
            "DestinationCidrBlock": "0.0.0.0/0",
            "NatGatewayId": "{{ createNatGw.natGwId }}",
            "RouteTableId": "{{ getMainRtb.mainRtbId }}"
          },
          "nextStep": "createPubRoute"
        },
        {
          "name": "createPubRoute",
          "action": "aws:executeAwsApi",
          "onFailure": "Abort",
          "inputs": {
            "Service": "ec2",
            "Api": "CreateRoute",
            "DestinationCidrBlock": "0.0.0.0/0",
            "GatewayId": "{{ createIgw.igwId }}",
            "RouteTableId": "{{ createPubRtb.pubRtbId }}"
          },
          "nextStep": "setPubSubAssoc"
        },
        {
          "name": "setPubSubAssoc",
          "action": "aws:executeAwsApi",
          "onFailure": "Abort",
          "inputs": {
            "Service": "ec2",
            "Api": "AssociateRouteTable",
            "RouteTableId": "{{ createPubRtb.pubRtbId }}",
            "SubnetId": "{{ createPubSubnet.pubSubnetId }}"
          }
        },
        {
          "name": "createDhcpOptions",
          "action": "aws:executeAwsApi",
          "onFailure": "Abort",
          "inputs": {
            "Service": "ec2",
            "Api": "CreateDhcpOptions",
            "DhcpConfigurations": [
              {
                "Key": "domain-name-servers",
                "Values": ["10.0.100.50,10.0.101.50"]
              },
              {
                "Key": "domain-name",
                "Values": ["sample.com"]
              }
            ]
          },
          "outputs": [
            {
              "Name": "dhcpOptionsId",
              "Selector": "$.DhcpOptions.DhcpOptionsId",
              "Type": "String"
            }
          ],
          "nextStep": "createDCSubnet1"
        },
        {
          "name": "createDCSubnet1",
          "action": "aws:executeAwsApi",
          "onFailure": "Abort",
          "inputs": {
            "Service": "ec2",
            "Api": "CreateSubnet",
            "CidrBlock": "10.0.100.0/24",
            "AvailabilityZone": "us-west-2a",
            "VpcId": "{{ createVpc.vpcId }}"
          },
          "outputs": [
            {
              "Name": "firstSubnetId",
              "Selector": "$.Subnet.SubnetId",
              "Type": "String"
            }
          ],
          "nextStep": "createDCSubnet2"
        },
        {
          "name": "createDCSubnet2",
          "action": "aws:executeAwsApi",
          "onFailure": "Abort",
          "inputs": {
            "Service": "ec2",
            "Api": "CreateSubnet",
            "CidrBlock": "10.0.101.0/24",
            "AvailabilityZone": "us-west-2b",
            "VpcId": "{{ createVpc.vpcId }}"
          },
          "outputs": [
            {
              "Name": "secondSubnetId",
              "Selector": "$.Subnet.SubnetId",
              "Type": "String"
            }
          ],
          "nextStep": "createDCSecGroup"
        },
        {
          "name": "createDCSecGroup",
          "action": "aws:executeAwsApi",
          "onFailure": "Abort",
          "inputs": {
            "Service": "ec2",
            "Api": "CreateSecurityGroup",
            "GroupName": "SampleDCSecGroup",
            "Description": "Security Group for Example Domain Controllers",
            "VpcId": "{{ createVpc.vpcId }}"
          },
          "outputs": [
            {
              "Name": "dcSecGroupId",
              "Selector": "$.GroupId",
              "Type": "String"
            }
          ],
          "nextStep": "authIngressDCTraffic"
        },
        {
          "name": "authIngressDCTraffic",
          "action": "aws:executeAwsApi",
          "onFailure": "Abort",
          "inputs": {
            "Service": "ec2",
            "Api": "AuthorizeSecurityGroupIngress",
            "GroupId": "{{ createDCSecGroup.dcSecGroupId }}",
            "IpPermissions": [
              {
                "FromPort": -1,
                "IpProtocol": "-1",
                "IpRanges": [
                  {
                    "CidrIp": "0.0.0.0/0",
                    "Description": "Allow all traffic between Domain Controllers"
                  }
                ]
              }
            ]
          },
          "nextStep": "verifyInstanceProfile"
        },
        {
          "name": "verifyInstanceProfile",
          "action": "aws:waitForAwsResourceProperty",
          "maxAttempts": 5,
          "onFailure": "Abort",
          "inputs": {
            "Service": "iam",
            "Api": "ListInstanceProfilesForRole",
            "RoleName": "sampleSSMInstanceRole",
            "PropertySelector": "$.InstanceProfiles[0].Arn",
            "DesiredValues": [
              "{{ createSSMInstanceProfile.instanceProfileArn }}"
            ]
          },
          "nextStep": "iamEventualConsistency"
        },
        {
          "name": "iamEventualConsistency",
          "action": "aws:sleep",
          "inputs": {
            "Duration": "PT2M"
          },
          "nextStep": "launchDC1"
        },
        {
          "name": "launchDC1",
          "action": "aws:executeAwsApi",
          "onFailure": "Abort",
          "inputs": {
            "Service": "ec2",
            "Api": "RunInstances",
            "BlockDeviceMappings": [
              {
                "DeviceName": "/dev/sda1",
                "Ebs": {
                  "DeleteOnTermination": true,
                  "VolumeSize": 50,
                  "VolumeType": "gp2"
                }
              },
              {
                "DeviceName": "xvdf",
                "Ebs": {
                  "DeleteOnTermination": true,
                  "VolumeSize": 100,
                  "VolumeType": "gp2"
                }
              }
            ],
            "IamInstanceProfile": {
              "Arn": "{{ createSSMInstanceProfile.instanceProfileArn }}"
            },
            "ImageId": "{{ getLatestWindowsAmi.amiId }}",
            "InstanceType": "t2.micro",
            "MaxCount": 1,
            "MinCount": 1,
            "PrivateIpAddress": "10.0.100.50",
            "SecurityGroupIds": [
              "{{ createDCSecGroup.dcSecGroupId }}"
            ],
            "SubnetId": "{{ createDCSubnet1.firstSubnetId }}",
            "TagSpecifications": [
              {
                "ResourceType": "instance",
                "Tags": [
                  {
                    "Key": "Name",
                    "Value": "SampleDC1"
                  }
                ]
              }
            ]
          },
          "outputs": [
            {
              "Name": "pdcInstanceId",
              "Selector": "$.Instances[0].InstanceId",
              "Type": "String"
            }
          ],
          "nextStep": "launchDC2"
        },
        {
          "name": "launchDC2",
          "action": "aws:executeAwsApi",
          "onFailure": "Abort",
          "inputs": {
            "Service": "ec2",
            "Api": "RunInstances",
            "BlockDeviceMappings": [
              {
                "DeviceName": "/dev/sda1",
                "Ebs": {
                  "DeleteOnTermination": true,
                  "VolumeSize": 50,
                  "VolumeType": "gp2"
                }
              },
              {
                "DeviceName": "xvdf",
                "Ebs": {
                  "DeleteOnTermination": true,
                  "VolumeSize": 100,
                  "VolumeType": "gp2"
                }
              }
            ],
            "IamInstanceProfile": {
              "Arn": "{{ createSSMInstanceProfile.instanceProfileArn }}"
            },
            "ImageId": "{{ getLatestWindowsAmi.amiId }}",
            "InstanceType": "t2.micro",
            "MaxCount": 1,
            "MinCount": 1,
            "PrivateIpAddress": "10.0.101.50",
            "SecurityGroupIds": [
              "{{ createDCSecGroup.dcSecGroupId }}"
            ],
            "SubnetId": "{{ createDCSubnet2.secondSubnetId }}",
            "TagSpecifications": [
              {
                "ResourceType": "instance",
                "Tags": [
                  {
                    "Key": "Name",
                    "Value": "SampleDC2"
                  }
                ]
              }
            ]
          },
          "outputs": [
            {
              "Name": "adcInstanceId",
              "Selector": "$.Instances[0].InstanceId",
              "Type": "String"
            }
          ],
          "nextStep": "verifyDCInstanceState"
        },
        {
          "name": "verifyDCInstanceState",
          "action": "aws:waitForAwsResourceProperty",
          "inputs": {
            "Service": "ec2",
            "Api": "DescribeInstanceStatus",
            "IncludeAllInstances": true,
            "InstanceIds": [
              "{{ launchDC1.pdcInstanceId }}",
              "{{ launchDC2.adcInstanceId }}"
            ],
            "PropertySelector": "$.InstanceStatuses[0].InstanceState.Name",
            "DesiredValues": [
              "running"
            ]
          },
          "nextStep": "verifyInstancesOnlineSSM"
        },
        {
          "name": "verifyInstancesOnlineSSM",
          "action": "aws:waitForAwsResourceProperty",
          "timeoutSeconds": 600,
          "inputs": {
            "Service": "ssm",
            "Api": "DescribeInstanceInformation",
            "InstanceInformationFilterList": [
              {
                "key": "InstanceIds",
                "valueSet": [
                  "{{ launchDC1.pdcInstanceId }}",
                  "{{ launchDC2.adcInstanceId }}"
                ]
              }
            ],
            "PropertySelector": "$.InstanceInformationList[0].PingStatus",
            "DesiredValues": [
              "Online"
            ]
          },
          "nextStep": "installADRoles"
        },
        {
          "name": "installADRoles",
          "action": "aws:runCommand",
          "inputs": {
            "DocumentName": "AWS-RunPowerShellScript",
            "InstanceIds": [
              "{{ launchDC1.pdcInstanceId }}",
              "{{ launchDC2.adcInstanceId }}"
            ],
            "Parameters": {
              "commands": [
                "try {",
                "  Install-WindowsFeature -Name AD-Domain-Services -IncludeManagementTools",
                "}",
                "catch {",
                "  Write-Error \"Failed to install ADDS Role.\"",
                "}"
              ]
            }
          },
          "nextStep": "setAdminPassword"
        },
        {
          "name": "setAdminPassword",
          "action": "aws:runCommand",
          "inputs": {
            "DocumentName": "AWS-RunPowerShellScript",
            "InstanceIds": [
              "{{ launchDC1.pdcInstanceId }}"
            ],
            "Parameters": {
              "commands": [
                "net user Administrator \"sampleAdminPass123!\""
              ]
            }
          },
          "nextStep": "createForest"
        },
        {
          "name": "createForest",
          "action": "aws:runCommand",
          "inputs": {
            "DocumentName": "AWS-RunPowerShellScript",
            "InstanceIds": [
              "{{ launchDC1.pdcInstanceId }}"
            ],
            "Parameters": {
              "commands": [
                "$dsrmPass = 'sample123!' | ConvertTo-SecureString -asPlainText -Force",
                "try {",
                "   Install-ADDSForest -DomainName \"sample.com\" -DomainMode 6 -ForestMode 6 -InstallDNS -DatabasePath \"D:\\NTDS\" -SysvolPath \"D:\\SYSVOL\" -SafeModeAdministratorPassword $dsrmPass -Force",
                "}",
                "catch {",
                "   Write-Error $_",
                "}",
                "try {",
                "   Add-DnsServerForwarder -IPAddress \"10.0.100.2\"",
                "}",
                "catch {",
                "   Write-Error $_",
                "}"
              ]
            }
          },
          "nextStep": "associateDhcpOptions"
        },
        {
          "name": "associateDhcpOptions",
          "action": "aws:executeAwsApi",
          "onFailure": "Abort",
          "inputs": {
            "Service": "ec2",
            "Api": "AssociateDhcpOptions",
            "DhcpOptionsId": "{{ createDhcpOptions.dhcpOptionsId }}",
            "VpcId": "{{ createVpc.vpcId }}"
          },
          "nextStep": "waitForADServices"
        },
        {
          "name": "waitForADServices",
          "action": "aws:sleep",
          "inputs": {
            "Duration": "PT1M"
          },
          "nextStep": "promoteADC"
        },
        {
          "name": "promoteADC",
          "action": "aws:runCommand",
          "inputs": {
            "DocumentName": "AWS-RunPowerShellScript",
            "InstanceIds": [
              "{{ launchDC2.adcInstanceId }}"
            ],
            "Parameters": {
              "commands": [
                "ipconfig /renew",
                "$dsrmPass = 'sample123!' | ConvertTo-SecureString -asPlainText -Force",
                "$domAdminUser = \"sample\\Administrator\"",
                "$domAdminPass = \"sampleAdminPass123!\" | ConvertTo-SecureString -asPlainText -Force",
                "$domAdminCred = New-Object System.Management.Automation.PSCredential($domAdminUser,$domAdminPass)",
                "try {",
                "   Install-ADDSDomainController -DomainName \"sample.com\" -InstallDNS -DatabasePath \"D:\\NTDS\" -SysvolPath \"D:\\SYSVOL\" -SafeModeAdministratorPassword $dsrmPass -Credential $domAdminCred -Force",
                "}",
                "catch {",
                "   Write-Error $_",
                "}"
              ]
            }
          }
        }
      ]
    }
```

------

# Restore a root volume from the latest snapshot
<a name="automation-document-instance-recovery-example"></a>

The operating system on a root volume can become corrupted for various reasons. For example, following a patching operation, instances might fail to boot successfully due to a corrupted kernel or registry. Automating common troubleshooting tasks, like restoring a root volume from the latest snapshot taken before the patching operation, can reduce downtime and expedite your troubleshooting efforts. AWS Systems Manager Automation actions can help you accomplish this. Automation is a tool in AWS Systems Manager.

The following example AWS Systems Manager runbook performs these actions: 
+ Uses the `aws:executeAwsApi` automation action to retrieve details from the root volume of the instance.
+ Uses the `aws:executeScript` automation action to retrieve the latest snapshot for the root volume.
+ Uses the `aws:branch` automation action to continue the automation if a snapshot is found for the root volume.

------
#### [ YAML ]

```
    ---
    description: Custom Automation Troubleshooting Example
    schemaVersion: '0.3'
    assumeRole: "{{ AutomationAssumeRole }}"
    parameters:
      AutomationAssumeRole:
        type: String
        description: "(Required) The ARN of the role that allows Automation to perform
          the actions on your behalf. If no role is specified, Systems Manager Automation
          uses your IAM permissions to use this runbook."
        default: ''
      InstanceId:
          type: String
          description: "(Required) The Instance Id whose root EBS volume you want to restore the latest Snapshot."
          default: ''
    mainSteps:
    - name: getInstanceDetails
      action: aws:executeAwsApi
      onFailure: Abort
      inputs:
        Service: ec2
        Api: DescribeInstances
        InstanceIds:
        - "{{ InstanceId }}"
      outputs:
        - Name: availabilityZone
          Selector: "$.Reservations[0].Instances[0].Placement.AvailabilityZone"
          Type: String
        - Name: rootDeviceName
          Selector: "$.Reservations[0].Instances[0].RootDeviceName"
          Type: String
      nextStep: getRootVolumeId
    - name: getRootVolumeId
      action: aws:executeAwsApi
      onFailure: Abort
      inputs:
        Service: ec2
        Api: DescribeVolumes
        Filters:
        -  Name: attachment.device
           Values: ["{{ getInstanceDetails.rootDeviceName }}"]
        -  Name: attachment.instance-id
           Values: ["{{ InstanceId }}"]
      outputs:
        - Name: rootVolumeId
          Selector: "$.Volumes[0].VolumeId"
          Type: String
      nextStep: getSnapshotsByStartTime
    - name: getSnapshotsByStartTime
      action: aws:executeScript
      timeoutSeconds: 45
      onFailure: Abort
      inputs:
        Runtime: python3.11
        Handler: getSnapshotsByStartTime
        InputPayload:
          rootVolumeId : "{{ getRootVolumeId.rootVolumeId }}"
        Script: |-
          def getSnapshotsByStartTime(events,context):
            import boto3
    
            #Initialize client
            ec2 = boto3.client('ec2')
            rootVolumeId = events['rootVolumeId']
            snapshotsQuery = ec2.describe_snapshots(
              Filters=[
                {
                  "Name": "volume-id",
                  "Values": [rootVolumeId]
                }
              ]
            )
            if not snapshotsQuery['Snapshots']:
              noSnapshotFoundString = "NoSnapshotFound"
              return { 'noSnapshotFound' : noSnapshotFoundString }
            else:
              jsonSnapshots = snapshotsQuery['Snapshots']
              sortedSnapshots = sorted(jsonSnapshots, key=lambda k: k['StartTime'], reverse=True)
              latestSortedSnapshotId = sortedSnapshots[0]['SnapshotId']
              return { 'latestSnapshotId' : latestSortedSnapshotId }
      outputs:
      - Name: Payload
        Selector: $.Payload
        Type: StringMap
      - Name: latestSnapshotId
        Selector: $.Payload.latestSnapshotId
        Type: String
      - Name: noSnapshotFound
        Selector: $.Payload.noSnapshotFound
        Type: String 
      nextStep: branchFromResults
    - name: branchFromResults
      action: aws:branch
      onFailure: Abort
      inputs:
        Choices:
        - NextStep: createNewRootVolumeFromSnapshot
          Not:
            Variable: "{{ getSnapshotsByStartTime.noSnapshotFound }}"
            StringEquals: "NoSnapshotFound"
      isEnd: true
    - name: createNewRootVolumeFromSnapshot
      action: aws:executeAwsApi
      onFailure: Abort
      inputs:
        Service: ec2
        Api: CreateVolume
        AvailabilityZone: "{{ getInstanceDetails.availabilityZone }}"
        SnapshotId: "{{ getSnapshotsByStartTime.latestSnapshotId }}"
      outputs:
        - Name: newRootVolumeId
          Selector: "$.VolumeId"
          Type: String
      nextStep: stopInstance
    - name: stopInstance
      action: aws:executeAwsApi
      onFailure: Abort
      inputs:
        Service: ec2
        Api: StopInstances
        InstanceIds:
        - "{{ InstanceId }}"
      nextStep: verifyVolumeAvailability
    - name: verifyVolumeAvailability
      action: aws:waitForAwsResourceProperty
      timeoutSeconds: 120
      inputs:
        Service: ec2
        Api: DescribeVolumes
        VolumeIds:
        - "{{ createNewRootVolumeFromSnapshot.newRootVolumeId }}"
        PropertySelector: "$.Volumes[0].State"
        DesiredValues:
        - "available"
      nextStep: verifyInstanceStopped
    - name: verifyInstanceStopped
      action: aws:waitForAwsResourceProperty
      timeoutSeconds: 120
      inputs:
        Service: ec2
        Api: DescribeInstances
        InstanceIds:
        - "{{ InstanceId }}"
        PropertySelector: "$.Reservations[0].Instances[0].State.Name"
        DesiredValues:
        - "stopped"
      nextStep: detachRootVolume
    - name: detachRootVolume
      action: aws:executeAwsApi
      onFailure: Abort
      inputs:
        Service: ec2
        Api: DetachVolume
        VolumeId: "{{ getRootVolumeId.rootVolumeId }}"
      nextStep: verifyRootVolumeDetached
    - name: verifyRootVolumeDetached
      action: aws:waitForAwsResourceProperty
      timeoutSeconds: 30
      inputs:
        Service: ec2
        Api: DescribeVolumes
        VolumeIds:
        - "{{ getRootVolumeId.rootVolumeId }}"
        PropertySelector: "$.Volumes[0].State"
        DesiredValues:
        - "available"
      nextStep: attachNewRootVolume
    - name: attachNewRootVolume
      action: aws:executeAwsApi
      onFailure: Abort
      inputs:
        Service: ec2
        Api: AttachVolume
        Device: "{{ getInstanceDetails.rootDeviceName }}"
        InstanceId: "{{ InstanceId }}"
        VolumeId: "{{ createNewRootVolumeFromSnapshot.newRootVolumeId }}"
      nextStep: verifyNewRootVolumeAttached
    - name: verifyNewRootVolumeAttached
      action: aws:waitForAwsResourceProperty
      timeoutSeconds: 30
      inputs:
        Service: ec2
        Api: DescribeVolumes
        VolumeIds:
        - "{{ createNewRootVolumeFromSnapshot.newRootVolumeId }}"
        PropertySelector: "$.Volumes[0].Attachments[0].State"
        DesiredValues:
        - "attached"
      nextStep: startInstance
    - name: startInstance
      action: aws:executeAwsApi
      onFailure: Abort
      inputs:
        Service: ec2
        Api: StartInstances
        InstanceIds:
        - "{{ InstanceId }}"
```

------
#### [ JSON ]

```
    {
       "description": "Custom Automation Troubleshooting Example",
       "schemaVersion": "0.3",
       "assumeRole": "{{ AutomationAssumeRole }}",
       "parameters": {
          "AutomationAssumeRole": {
             "type": "String",
             "description": "(Required) The ARN of the role that allows Automation to perform the actions on your behalf. If no role is specified, Systems Manager Automation uses your IAM permissions to run this runbook.",
             "default": ""
          },
          "InstanceId": {
             "type": "String",
             "description": "(Required) The Instance Id whose root EBS volume you want to restore the latest Snapshot.",
             "default": ""
          }
       },
       "mainSteps": [
          {
             "name": "getInstanceDetails",
             "action": "aws:executeAwsApi",
             "onFailure": "Abort",
             "inputs": {
                "Service": "ec2",
                "Api": "DescribeInstances",
                "InstanceIds": [
                   "{{ InstanceId }}"
                ]
             },
             "outputs": [
                {
                   "Name": "availabilityZone",
                   "Selector": "$.Reservations[0].Instances[0].Placement.AvailabilityZone",
                   "Type": "String"
                },
                {
                   "Name": "rootDeviceName",
                   "Selector": "$.Reservations[0].Instances[0].RootDeviceName",
                   "Type": "String"
                }
             ],
             "nextStep": "getRootVolumeId"
          },
          {
             "name": "getRootVolumeId",
             "action": "aws:executeAwsApi",
             "onFailure": "Abort",
             "inputs": {
                "Service": "ec2",
                "Api": "DescribeVolumes",
                "Filters": [
                   {
                      "Name": "attachment.device",
                      "Values": [
                         "{{ getInstanceDetails.rootDeviceName }}"
                      ]
                   },
                   {
                      "Name": "attachment.instance-id",
                      "Values": [
                         "{{ InstanceId }}"
                      ]
                   }
                ]
             },
             "outputs": [
                {
                   "Name": "rootVolumeId",
                   "Selector": "$.Volumes[0].VolumeId",
                   "Type": "String"
                }
             ],
             "nextStep": "getSnapshotsByStartTime"
          },
          {
             "name": "getSnapshotsByStartTime",
             "action": "aws:executeScript",
             "timeoutSeconds": 45,
             "onFailure": "Continue",
             "inputs": {
                "Runtime": "python3.11",
                "Handler": "getSnapshotsByStartTime",
                "InputPayload": {
                   "rootVolumeId": "{{ getRootVolumeId.rootVolumeId }}"
                },
                "Attachment": "getSnapshotsByStartTime.py"
             },
             "outputs": [
                {
                   "Name": "Payload",
                   "Selector": "$.Payload",
                   "Type": "StringMap"
                },
                {
                   "Name": "latestSnapshotId",
                   "Selector": "$.Payload.latestSnapshotId",
                   "Type": "String"
                },
                {
                   "Name": "noSnapshotFound",
                   "Selector": "$.Payload.noSnapshotFound",
                   "Type": "String"
                }
             ],
             "nextStep": "branchFromResults"
          },
          {
             "name": "branchFromResults",
             "action": "aws:branch",
             "onFailure": "Abort",
             "inputs": {
                "Choices": [
                   {
                      "NextStep": "createNewRootVolumeFromSnapshot",
                      "Not": {
                         "Variable": "{{ getSnapshotsByStartTime.noSnapshotFound }}",
                         "StringEquals": "NoSnapshotFound"
                      }
                   }
                ]
             },
             "isEnd": true
          },
          {
             "name": "createNewRootVolumeFromSnapshot",
             "action": "aws:executeAwsApi",
             "onFailure": "Abort",
             "inputs": {
                "Service": "ec2",
                "Api": "CreateVolume",
                "AvailabilityZone": "{{ getInstanceDetails.availabilityZone }}",
                "SnapshotId": "{{ getSnapshotsByStartTime.latestSnapshotId }}"
             },
             "outputs": [
                {
                   "Name": "newRootVolumeId",
                   "Selector": "$.VolumeId",
                   "Type": "String"
                }
             ],
             "nextStep": "stopInstance"
          },
          {
             "name": "stopInstance",
             "action": "aws:executeAwsApi",
             "onFailure": "Abort",
             "inputs": {
                "Service": "ec2",
                "Api": "StopInstances",
                "InstanceIds": [
                   "{{ InstanceId }}"
                ]
             },
             "nextStep": "verifyVolumeAvailability"
          },
          {
             "name": "verifyVolumeAvailability",
             "action": "aws:waitForAwsResourceProperty",
             "timeoutSeconds": 120,
             "inputs": {
                "Service": "ec2",
                "Api": "DescribeVolumes",
                "VolumeIds": [
                   "{{ createNewRootVolumeFromSnapshot.newRootVolumeId }}"
                ],
                "PropertySelector": "$.Volumes[0].State",
                "DesiredValues": [
                   "available"
                ]
             },
             "nextStep": "verifyInstanceStopped"
          },
          {
             "name": "verifyInstanceStopped",
             "action": "aws:waitForAwsResourceProperty",
             "timeoutSeconds": 120,
             "inputs": {
                "Service": "ec2",
                "Api": "DescribeInstances",
                "InstanceIds": [
                   "{{ InstanceId }}"
                ],
                "PropertySelector": "$.Reservations[0].Instances[0].State.Name",
                "DesiredValues": [
                   "stopped"
                ]
             },
             "nextStep": "detachRootVolume"
          },
          {
             "name": "detachRootVolume",
             "action": "aws:executeAwsApi",
             "onFailure": "Abort",
             "inputs": {
                "Service": "ec2",
                "Api": "DetachVolume",
                "VolumeId": "{{ getRootVolumeId.rootVolumeId }}"
             },
             "nextStep": "verifyRootVolumeDetached"
          },
          {
             "name": "verifyRootVolumeDetached",
             "action": "aws:waitForAwsResourceProperty",
             "timeoutSeconds": 30,
             "inputs": {
                "Service": "ec2",
                "Api": "DescribeVolumes",
                "VolumeIds": [
                   "{{ getRootVolumeId.rootVolumeId }}"
                ],
                "PropertySelector": "$.Volumes[0].State",
                "DesiredValues": [
                   "available"
                ]
             },
             "nextStep": "attachNewRootVolume"
          },
          {
             "name": "attachNewRootVolume",
             "action": "aws:executeAwsApi",
             "onFailure": "Abort",
             "inputs": {
                "Service": "ec2",
                "Api": "AttachVolume",
                "Device": "{{ getInstanceDetails.rootDeviceName }}",
                "InstanceId": "{{ InstanceId }}",
                "VolumeId": "{{ createNewRootVolumeFromSnapshot.newRootVolumeId }}"
             },
             "nextStep": "verifyNewRootVolumeAttached"
          },
          {
             "name": "verifyNewRootVolumeAttached",
             "action": "aws:waitForAwsResourceProperty",
             "timeoutSeconds": 30,
             "inputs": {
                "Service": "ec2",
                "Api": "DescribeVolumes",
                "VolumeIds": [
                   "{{ createNewRootVolumeFromSnapshot.newRootVolumeId }}"
                ],
                "PropertySelector": "$.Volumes[0].Attachments[0].State",
                "DesiredValues": [
                   "attached"
                ]
             },
             "nextStep": "startInstance"
          },
          {
             "name": "startInstance",
             "action": "aws:executeAwsApi",
             "onFailure": "Abort",
             "inputs": {
                "Service": "ec2",
                "Api": "StartInstances",
                "InstanceIds": [
                   "{{ InstanceId }}"
                ]
             }
          }
       ],
       "files": {
            "getSnapshotsByStartTime.py": {
                "checksums": {
                    "sha256": "sampleETagValue"
                }
            }
        }
    }
```

------

# Create an AMI and cross-Region copy
<a name="automation-document-backup-maintenance-example"></a>

Creating an Amazon Machine Image (AMI) of an instance is a common process used in backup and recovery. You might also choose to copy an AMI to another AWS Region as part of a disaster recovery architecture. Automating common maintenance tasks can reduce downtime if an issue requires failover. AWS Systems Manager Automation actions can help you accomplish this. Automation is a tool in AWS Systems Manager.

The following example AWS Systems Manager runbook performs these actions:
+ Uses the `aws:executeAwsApi` automation action to create an AMI.
+ Uses the `aws:waitForAwsResourceProperty` automation action to confirm the availability of the AMI.
+ Uses the `aws:executeScript` automation action to copy the AMI to the destination Region.

------
#### [ YAML ]

```
    ---
    description: Custom Automation Backup and Recovery Example
    schemaVersion: '0.3'
    assumeRole: "{{ AutomationAssumeRole }}"
    parameters:
      AutomationAssumeRole:
        type: String
        description: "(Required) The ARN of the role that allows Automation to perform
          the actions on your behalf. If no role is specified, Systems Manager Automation
          uses your IAM permissions to use this runbook."
        default: ''
      InstanceId:
        type: String
        description: "(Required) The ID of the EC2 instance."
        default: ''
    mainSteps:
    - name: createImage
      action: aws:executeAwsApi
      onFailure: Abort
      inputs:
        Service: ec2
        Api: CreateImage
        InstanceId: "{{ InstanceId }}"
        Name: "Automation Image for {{ InstanceId }}"
        NoReboot: false
      outputs:
        - Name: newImageId
          Selector: "$.ImageId"
          Type: String
      nextStep: verifyImageAvailability
    - name: verifyImageAvailability
      action: aws:waitForAwsResourceProperty
      timeoutSeconds: 600
      inputs:
        Service: ec2
        Api: DescribeImages
        ImageIds:
        - "{{ createImage.newImageId }}"
        PropertySelector: "$.Images[0].State"
        DesiredValues:
        - available
      nextStep: copyImage
    - name: copyImage
      action: aws:executeScript
      timeoutSeconds: 45
      onFailure: Abort
      inputs:
        Runtime: python3.11
        Handler: crossRegionImageCopy
        InputPayload:
          newImageId : "{{ createImage.newImageId }}"
        Script: |-
          def crossRegionImageCopy(events,context):
            import boto3
    
            #Initialize client
            ec2 = boto3.client('ec2', region_name='us-east-1')
            newImageId = events['newImageId']
    
            ec2.copy_image(
              Name='DR Copy for ' + newImageId,
              SourceImageId=newImageId,
              SourceRegion='us-west-2'
            )
```

------
#### [ JSON ]

```
    {
       "description": "Custom Automation Backup and Recovery Example",
       "schemaVersion": "0.3",
       "assumeRole": "{{ AutomationAssumeRole }}",
       "parameters": {
          "AutomationAssumeRole": {
             "type": "String",
             "description": "(Required) The ARN of the role that allows Automation to perform\nthe actions on your behalf. If no role is specified, Systems Manager Automation\nuses your IAM permissions to run this runbook.",
             "default": ""
          },
          "InstanceId": {
             "type": "String",
             "description": "(Required) The ID of the EC2 instance.",
             "default": ""
          }
       },
       "mainSteps": [
          {
             "name": "createImage",
             "action": "aws:executeAwsApi",
             "onFailure": "Abort",
             "inputs": {
                "Service": "ec2",
                "Api": "CreateImage",
                "InstanceId": "{{ InstanceId }}",
                "Name": "Automation Image for {{ InstanceId }}",
                "NoReboot": false
             },
             "outputs": [
                {
                   "Name": "newImageId",
                   "Selector": "$.ImageId",
                   "Type": "String"
                }
             ],
             "nextStep": "verifyImageAvailability"
          },
          {
             "name": "verifyImageAvailability",
             "action": "aws:waitForAwsResourceProperty",
             "timeoutSeconds": 600,
             "inputs": {
                "Service": "ec2",
                "Api": "DescribeImages",
                "ImageIds": [
                   "{{ createImage.newImageId }}"
                ],
                "PropertySelector": "$.Images[0].State",
                "DesiredValues": [
                   "available"
                ]
             },
             "nextStep": "copyImage"
          },
          {
             "name": "copyImage",
             "action": "aws:executeScript",
             "timeoutSeconds": 45,
             "onFailure": "Abort",
             "inputs": {
                "Runtime": "python3.11",
                "Handler": "crossRegionImageCopy",
                "InputPayload": {
                   "newImageId": "{{ createImage.newImageId }}"
                },
                "Attachment": "crossRegionImageCopy.py"
             }
          }
       ],
       "files": {
            "crossRegionImageCopy.py": {
                "checksums": {
                    "sha256": "sampleETagValue"
                }
            }
        }
    }
```

------

# Creating input parameters that populate AWS resources
<a name="populating-input-parameters"></a>

Automation, a tool in Systems Manager, populates AWS resources in the AWS Management Console that match the resource type you define for an input parameter. Resources in your AWS account that match the resource type are displayed in a dropdown list for you to choose. You can define input parameter types for Amazon Elastic Compute Cloud (Amazon EC2) instances, Amazon Simple Storage Service (Amazon S3) buckets, and AWS Identity and Access Management (IAM) roles. The supported type definitions and the regular expressions used to locate matching resources are as follows:
+ `AWS::EC2::Instance::Id` - `^m?i-([a-z0-9]{8}|[a-z0-9]{17})$`
+ `List<AWS::EC2::Instance::Id>` - `^m?i-([a-z0-9]{8}|[a-z0-9]{17})$`
+ `AWS::S3::Bucket::Name` - `^[0-9a-z][a-z0-9\\-\\.]{3,63}$`
+ `List<AWS::S3::Bucket::Name>` - `^[0-9a-z][a-z0-9\\-\\.]{3,63}$`
+ `AWS::IAM::Role::Arn` - `^arn:(aws|aws-cn|aws-us-gov|aws-iso|aws-iso-b):iam::[0-9]{12}:role/.*$`
+ `List<AWS::IAM::Role::Arn>` - `^arn:(aws|aws-cn|aws-us-gov|aws-iso|aws-iso-b):iam::[0-9]{12}:role/.*$`

The following is an example of input parameter types defined in runbook content.

------
#### [ YAML ]

```
description: Enables encryption on an Amazon S3 bucket
schemaVersion: '0.3'
assumeRole: '{{ AutomationAssumeRole }}'
parameters:
  BucketName:
    type: 'AWS::S3::Bucket::Name'
    description: (Required) The name of the Amazon S3 bucket you want to encrypt.
  SSEAlgorithm:
    type: String
    description: (Optional) The server-side encryption algorithm to use for the default encryption.
    default: AES256
  AutomationAssumeRole:
    type: 'AWS::IAM::Role::Arn'
    description: (Optional) The Amazon Resource Name (ARN) of the role that allows Automation to perform the actions on your behalf.
    default: ''
mainSteps:
  - name: enableBucketEncryption
    action: 'aws:executeAwsApi'
    inputs:
      Service: s3
      Api: PutBucketEncryption
      Bucket: '{{BucketName}}'
      ServerSideEncryptionConfiguration:
        Rules:
          - ApplyServerSideEncryptionByDefault:
              SSEAlgorithm: '{{SSEAlgorithm}}'
    isEnd: true
```

------
#### [ JSON ]

```
{
   "description": "Enables encryption on an Amazon S3 bucket",
   "schemaVersion": "0.3",
   "assumeRole": "{{ AutomationAssumeRole }}",
   "parameters": {
      "BucketName": {
         "type": "AWS::S3::Bucket::Name",
         "description": "(Required) The name of the Amazon S3 bucket you want to encrypt."
      },
      "SSEAlgorithm": {
         "type": "String",
         "description": "(Optional) The server-side encryption algorithm to use for the default encryption.",
         "default": "AES256"
      },
      "AutomationAssumeRole": {
         "type": "AWS::IAM::Role::Arn",
         "description": "(Optional) The Amazon Resource Name (ARN) of the role that allows Automation to perform the actions on your behalf.",
         "default": ""
      }
   },
   "mainSteps": [
      {
         "name": "enableBucketEncryption",
         "action": "aws:executeAwsApi",
         "inputs": {
            "Service": "s3",
            "Api": "PutBucketEncryption",
            "Bucket": "{{BucketName}}",
            "ServerSideEncryptionConfiguration": {
               "Rules": [
                  {
                     "ApplyServerSideEncryptionByDefault": {
                        "SSEAlgorithm": "{{SSEAlgorithm}}"
                     }
                  }
               ]
            }
         },
         "isEnd": true
      }
   ]
}
```

------

# Using Document Builder to create runbooks
<a name="automation-document-builder"></a>

If the AWS Systems Manager public runbooks don't support all the actions you want to perform on your AWS resources, you can create your own runbooks. To create a custom runbook, you can manually create a local YAML or JSON format file with the appropriate automation actions. Alternatively, you can use Document Builder in the Systems Manager Automation console to build a custom runbook.

Using Document Builder, you can add automation actions to your custom runbook and provide the required parameters without having to use JSON or YAML syntax. After you add steps and create the runbook, the system converts the actions you've added into the YAML format that Systems Manager can use to run automation.

Runbooks support the use of Markdown, a markup language, which allows you to add wiki-style descriptions to runbooks and individual steps within the runbook. For more information about using Markdown, see [Using Markdown in AWS](https://docs.aws.amazon.com/general/latest/gr/aws-markdown.html).

## Create a runbook using Document Builder
<a name="create-runbook"></a>

**Before you begin**  
We recommend that you read about the different actions that you can use within a runbook. For more information, see [Systems Manager Automation actions reference](automation-actions.md).

**To create a runbook using Document Builder**

1. Open the AWS Systems Manager console at [https://console.aws.amazon.com/systems-manager/](https://console.aws.amazon.com/systems-manager/).

1. In the navigation pane, choose **Documents**.

1. Choose **Create automation**.

1. For **Name**, enter a descriptive name for the runbook.

1. For **Document description**, provide the markdown style description for the runbook. You can provide instructions for using the runbook, numbered steps, or any other type of information to describe the runbook. Refer to the default text for information about formatting your content.
**Tip**  
Toggle between **Hide preview** and **Show preview** to see what your description content looks like as you compose.

1. (Optional) For **Assume role**, enter the name or ARN of a service role to perform actions on your behalf. If you don't specify a role, Automation uses the access permissions of the user who runs the automation.
**Important**  
For runbooks not owned by Amazon that use the `aws:executeScript` action, a role must be specified. For information, see [Permissions for using runbooks](automation-document-script-considerations.md#script-permissions).

1. (Optional) For **Outputs**, enter any outputs for the automation of this runbook to make available for other processes. 

   For example, if your runbook creates a new AMI, you might specify ["CreateImage.ImageId"], and then use this output to create new instances in a subsequent automation.

1. (Optional) Expand the **Input parameters** section and do the following.

   1. For **Parameter name**, enter a descriptive name for the runbook parameter you're creating.

   1. For **Type**, choose a type for the parameter, such as `String` or `MapList`.

   1. For **Required**, do one of the following: 
      + Choose **Yes** if a value for this runbook parameter must be supplied at runtime.
      + Choose **No** if the parameter isn't required, and (optional) enter a default parameter value in **Default value**.

   1. For **Description**, enter a description for the runbook parameter.
**Note**  
To add more runbook parameters, choose **Add a parameter**. To remove a runbook parameter, choose the **X** (Remove) button.

1. (Optional) Expand the **Target type** section and choose a target type to define the kinds of resources the automation can run on. For example, to use a runbook on EC2 instances, choose `/AWS::EC2::Instance`.
**Note**  
If you specify a value of '`/`', the runbook can run on all types of resources. For a list of valid resource types, see [AWS Resource Types Reference](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-template-resource-type-ref.html) in the *AWS CloudFormation User Guide*.

1. (Optional) Expand the **Document tags** section and enter one or more tag key-value pairs to apply to the runbook. Tags make it easier to identify, organize, and search for resources.

1. In the **Step 1** section, provide the following information.
   + For **Step name**, enter a descriptive name for the first step of the automation.
   + For **Action type**, select the action type to use for this step.

     For a list and information about the available action types, see [Systems Manager Automation actions reference](automation-actions.md).
   + For **Description**, enter a description for the automation step. You can use Markdown to format your text.
   + Depending on the **Action type** selected, enter the required inputs for the action type in the **Step inputs** section. For example, if you selected the action `aws:approve`, you must specify a value for the `Approvers` property.

     For information about the step input fields, see the entry in [Systems Manager Automation actions reference](automation-actions.md) for the action type you selected. For example: [`aws:executeStateMachine` – Run an AWS Step Functions state machine](automation-action-executeStateMachine.md).
   + (Optional) For **Additional inputs**, provide any additional input values needed for your runbook. The available input types depend on the action type you selected for the step. (Note that some action types require input values.)
**Note**  
To add more inputs, choose **Add optional input**. To remove an input, choose the **X** (Remove) button.
   + (Optional) For **Outputs**, enter any outputs for this step to make available for other processes.
**Note**  
**Outputs** isn't available for all action types.
   + (Optional) Expand the **Common properties** section and specify properties for the actions that are common to all automation actions. For example, for **Timeout seconds**, you can provide a value in seconds to specify how long the step can run before it's stopped.

     For more information, see [Properties shared by all actions](automation-actions.md#automation-common).
**Note**  
To add more steps, select **Add step** and repeat the procedure for creating a step. To remove a step, choose **Remove step**.

1. Choose **Create automation** to save the runbook.

## Create a runbook that runs scripts
<a name="create-runbook-scripts"></a>

The following procedure shows how to use Document Builder in the AWS Systems Manager Automation console to create a custom runbook that runs a script.

The first step of the runbook you create runs a script to launch an Amazon Elastic Compute Cloud (Amazon EC2) instance. The second step runs another script to monitor for the instance status check to change to `ok`. Then, an overall status of `Success` is reported for the automation.

**Before you begin**  
Make sure you have completed the following steps:
+ Verify that you have administrator privileges, or that you have been granted the appropriate permissions to access Systems Manager in AWS Identity and Access Management (IAM). 

  For information, see [Verifying user access for runbooks](automation-setup.md#automation-setup-user-access).
+ Verify that you have an IAM service role for Automation (also known as an *assume role*) in your AWS account. The role is required because this walkthrough uses the `aws:executeScript` action. 

  For information about creating this role, see [Configuring a service role (assume role) access for automations](automation-setup.md#automation-setup-configure-role). 

  For information about the IAM service role requirement for running `aws:executeScript`, see [Permissions for using runbooks](automation-document-script-considerations.md#script-permissions).
+ Verify that you have permission to launch EC2 instances. 

  For information, see [IAM and Amazon EC2](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/UsingIAM.html#intro-to-iam) in the *Amazon EC2 User Guide*.

**To create a custom runbook that runs scripts using Document Builder**

1. Open the AWS Systems Manager console at [https://console.aws.amazon.com/systems-manager/](https://console.aws.amazon.com/systems-manager/).

1. In the navigation pane, choose **Documents**.

1. Choose **Create automation**.

1. For **Name**, type this descriptive name for the runbook: **LaunchInstanceAndCheckStatus**.

1. (Optional) For **Document description**, replace the default text with a description for this runbook, using Markdown. The following is an example.

   ```
   ##Title: LaunchInstanceAndCheckState
       -----
       **Purpose**: This runbook first launches an EC2 instance using the AMI ID provided in the parameter ```imageId```. The second step of this runbook continuously checks the instance status check value for the launched instance until the status ```ok``` is returned.
       
       ##Parameters:
       -----
       Name | Type | Description | Default Value
       ------------- | ------------- | ------------- | -------------
       assumeRole | String | (Optional) The ARN of the role that allows Automation to perform the actions on your behalf. | -
       imageId  | String | (Optional) The AMI ID to use for launching the instance. The default value uses the latest Amazon Linux 2023 AMI ID available. | {{ ssm:/aws/service/ami-amazon-linux-latest/al2023-ami-kernel-6.1-arm64 }}
   ```

1. For **Assume role**, enter the ARN of the IAM service role for Automation (Assume role) for the automation, in the format **arn:aws:iam::111122223333:role/AutomationServiceRole**. Substitute your AWS account ID for 111122223333.

   The role you specify is used to provide the permissions needed to start the automation.
**Important**  
For runbooks not owned by Amazon that use the `aws:executeScript` action, a role must be specified. For information, see [Permissions for using runbooks](automation-document-script-considerations.md#script-permissions).

1. Expand **Input parameters** and do the following.

   1. For **Parameter name**, enter **imageId**.

   1. For **Type**, choose **String**.

   1. For **Required**, choose `No`. 

   1. For **Default value**, enter the following.

      ```
      {{ ssm:/aws/service/ami-amazon-linux-latest/al2023-ami-kernel-6.1-arm64 }}
      ```
**Note**  
This value launches an Amazon EC2 instance using the latest Amazon Linux 2023 Amazon Machine Image (AMI) ID. If you want to use a different AMI, replace the value with your AMI ID.

   1. For **Description**, enter the following.

      ```
      (Optional) The AMI ID to use for launching the instance. The default value uses the latest released Amazon Linux 2023 AMI ID.
      ```

1. Choose **Add a parameter** to create the second parameter, **tagValue**, and enter the following.

   1. For **Parameter name**, enter **tagValue**.

   1. For **Type**, choose **String**.

   1. For **Required**, choose `No`. 

   1. For **Default value**, enter **LaunchedBySsmAutomation**. This adds the tag key-pair value `Name:LaunchedBySsmAutomation` to the instance.

   1. For **Description**, enter the following.

      ```
      (Optional) The tag value to add to the instance. The default value is LaunchedBySsmAutomation.
      ```

1. Choose **Add a parameter** to create the third parameter, **instanceType**, and enter the following information.

   1. For **Parameter name**, enter **instanceType**.

   1. For **Type**, choose **String**.

   1. For **Required**, choose `No`. 

   1. For **Default value**, enter **t2.micro**.

   1. For **Parameter description**, enter the following.

      ```
      (Optional) The instance type to use for the instance. The default value is t2.micro.
      ```

1. Expand **Target type** and choose **"/"**.

1. (Optional) Expand **Document tags** to apply resource tags to your runbook. For **Tag key**, enter **Purpose**, and for **Tag value**, enter **LaunchInstanceAndCheckState**.

1. In the **Step 1** section, complete the following steps.

   1. For **Step name**, enter this descriptive step name for the first step of the automation: **LaunchEc2Instance**.

   1. For **Action type**, choose **Run a script** (**aws:executeScript**).

   1. For **Description**, enter a description for the automation step, such as the following.

      ```
      **About This Step**
          
          This step first launches an EC2 instance using the ```aws:executeScript``` action and the provided script.
      ```

   1. Expand **Inputs**.

   1. For **Runtime**, choose the runtime language to use to run the provided script.

   1. For **Handler**, enter **launch\$1instance**. This is the function name declared in the following script.
**Note**  
This is not required for PowerShell.

   1. For **Script**, replace the default contents with the following. Be sure to match the script with the corresponding runtime value.

------
#### [ Python ]

      ```
      def launch_instance(events, context):
            import boto3
            ec2 = boto3.client('ec2')
          
            image_id = events['image_id']
            tag_value = events['tag_value']
            instance_type = events['instance_type']
          
            tag_config = {'ResourceType': 'instance', 'Tags': [{'Key':'Name', 'Value':tag_value}]}
          
            res = ec2.run_instances(ImageId=image_id, InstanceType=instance_type, MaxCount=1, MinCount=1, TagSpecifications=[tag_config])
          
            instance_id = res['Instances'][0]['InstanceId']
          
            print('[INFO] 1 EC2 instance is successfully launched', instance_id)
          
            return { 'InstanceId' : instance_id }
      ```

------
#### [ PowerShell ]

      ```
      Install-Module AWS.Tools.EC2 -Force
          Import-Module AWS.Tools.EC2
          
          $payload = $env:InputPayload | ConvertFrom-Json
          
          $imageid = $payload.image_id
          
          $tagvalue = $payload.tag_value
          
          $instanceType = $payload.instance_type
          
          $type = New-Object Amazon.EC2.InstanceType -ArgumentList $instanceType
          
          $resource = New-Object Amazon.EC2.ResourceType -ArgumentList 'instance'
          
          $tag = @{Key='Name';Value=$tagValue}
          
          $tagSpecs = New-Object Amazon.EC2.Model.TagSpecification
          
          $tagSpecs.ResourceType = $resource
          
          $tagSpecs.Tags.Add($tag)
          
          $res = New-EC2Instance -ImageId $imageId -MinCount 1 -MaxCount 1 -InstanceType $type -TagSpecification $tagSpecs
          
          return @{'InstanceId'=$res.Instances.InstanceId}
      ```

------

   1. Expand **Additional inputs**. 

   1. For **Input name**, choose **InputPayload**. For **Input value**, enter the following YAML data. 

      ```
      image_id: "{{ imageId }}"
          tag_value: "{{ tagValue }}"
          instance_type: "{{ instanceType }}"
      ```

1. Expand **Outputs** and do the following:
   + For **Name**, enter **payload**.
   + For **Selector**, enter **\$1.Payload**.
   + For **Type**, choose `StringMap`.

1. Choose **Add step** to add a second step to the runbook. The second step queries the status of the instance launched in Step 1 and waits until the status returned is `ok`.

1. In the **Step 2** section, do the following.

   1. For **Step name**, enter this descriptive name for the second step of the automation: **WaitForInstanceStatusOk**.

   1. For **Action type**, choose **Run a script** (**aws:executeScript**).

   1. For **Description**, enter a description for the automation step, such as the following.

      ```
      **About This Step**
          
          The script continuously polls the instance status check value for the instance launched in Step 1 until the ```ok``` status is returned.
      ```

   1. For **Runtime**, choose the runtime language to be used for executing the provided script.

   1. For **Handler**, enter **poll\$1instance**. This is the function name declared in the following script.
**Note**  
This is not required for PowerShell.

   1. For **Script**, replace the default contents with the following. Be sure to match the script with the corresponding runtime value.

------
#### [ Python ]

      ```
      def poll_instance(events, context):
            import boto3
            import time
          
            ec2 = boto3.client('ec2')
          
            instance_id = events['InstanceId']
          
            print('[INFO] Waiting for instance status check to report ok', instance_id)
          
            instance_status = "null"
          
            while True:
              res = ec2.describe_instance_status(InstanceIds=[instance_id])
          
              if len(res['InstanceStatuses']) == 0:
                print("Instance status information is not available yet")
                time.sleep(5)
                continue
          
              instance_status = res['InstanceStatuses'][0]['InstanceStatus']['Status']
          
              print('[INFO] Polling to get status of the instance', instance_status)
          
              if instance_status == 'ok':
                break
          
              time.sleep(10)
          
            return {'Status': instance_status, 'InstanceId': instance_id}
      ```

------
#### [ PowerShell ]

      ```
          Install-Module AWS.Tools.EC2 -Force
          
          $inputPayload = $env:InputPayload | ConvertFrom-Json
          
          $instanceId = $inputPayload.payload.InstanceId
          
          $status = Get-EC2InstanceStatus -InstanceId $instanceId
          
          while ($status.Status.Status -ne 'ok'){
             Write-Host 'Polling get status of the instance', $instanceId
          
             Start-Sleep -Seconds 5
          
             $status = Get-EC2InstanceStatus -InstanceId $instanceId
          }
          
          return @{Status = $status.Status.Status; InstanceId = $instanceId}
      ```

------

   1. Expand **Additional inputs**. 

   1. For **Input name**, choose **InputPayload**. For **Input value**, enter the following:

      ```
      {{ LaunchEc2Instance.payload }}
      ```

1. Choose **Create automation** to save the runbook.

# Using scripts in runbooks
<a name="automation-document-script-considerations"></a>

Automation runbooks support running scripts as part of the automation. Automation is a tool in AWS Systems Manager. By using runbooks, you can run scripts directly in AWS without creating a separate compute environment to run your scripts. Because runbooks can run script steps along with other automation step types, such as approvals, you can manually intervene in critical or ambiguous situations. You can send the output from `aws:executeScript` actions in your runbooks to Amazon CloudWatch Logs. For more information, see [Logging Automation action output with CloudWatch Logs](automation-action-logging.md).

## Permissions for using runbooks
<a name="script-permissions"></a>

To use a runbook, Systems Manager must use the permissions of an AWS Identity and Access Management (IAM) role. The method that Automation uses to determine which role's permissions to use depends on a few factors, and whether a step uses the `aws:executeScript` action. 

For runbooks that don't use `aws:executeScript`, Automation uses one of two sources of permissions:
+ The permissions of an IAM service role, or Assume role, that is specified in the runbook or passed in as a parameter.
+ If no IAM service role is specified, the permissions of the user who started the automation. 

When a step in a runbook includes the `aws:executeScript` action, however, an IAM service role (Assume role) is always required if the Python or PowerShell script specified for the action is calling any AWS API operations. Automation checks for this role in the following order:
+ The permissions of an IAM service role, or Assume role, that is specified in the runbook or passed in as a parameter.
+ If no role is found, Automation attempts to run the Python or PowerShell script specified for `aws:executeScript` without any permissions. If the script is calling an AWS API operation (for example the Amazon EC2 `CreateImage` operation), or attempting to act on an AWS resource (such as an EC2 instance), the step containing the script fails, and Systems Manager returns an error message reporting the failure. 

## Adding scripts to runbooks
<a name="adding-scripts"></a>

You can add scripts to your runbooks by including the script inline as part of a step in the runbook. You can also attach scripts to the runbook by uploading the scripts from your local machine or by specifying an Amazon Simple Storage Service (Amazon S3) bucket where the scripts are located. After a step that runs a script is complete, the output of the script is available as a JSON object, which you can then use as input for subsequent steps in your runbook. For more information about the `aws:executeScript` action and how to use attachments for scripts, see [`aws:executeScript` – Run a script](automation-action-executeScript.md).

## Script constraints for runbooks
<a name="script-constraints"></a>

Runbooks enforce a limit of five file attachments. Scripts can either be in the form of a Python script (.py), a PowerShell Core script (.ps1), or attached as contents within a .zip file.

# Using conditional statements in runbooks
<a name="automation-branch-condition"></a>

By default, the steps that you define in the `mainSteps` section of a runbook run in sequential order. After one action is completed, the next action specified in the `mainSteps` section begins. Furthermore, if an action fails to run, the entire automation fails (by default). You can use the `aws:branch` automation action and the runbook options described in this section to create automations that perform *conditional branching*. This means that you can create automations that jump to a different step after evaluating different choices or that dynamically respond to changes when a step is complete. Here is a list of options that you can use to create dynamic automations:
+ **`aws:branch`**: This automation action allows you to create a dynamic automation that evaluates multiple choices in a single step and then jumps to a different step in the runbook based on the results of that evaluation.
+ **`nextStep`**: This option specifies which step in an automation to process next after successfully completing a step. 
+ **`isEnd`**: This option stops an automation at the end of a specific step. The default value for this option is false.
+ **`isCritical`**: This option designates a step as critical for the successful completion of the automation. If a step with this designation fails, then Automation reports the final status of the automation as `Failed`. The default value for this option is `true`.
+ **`onFailure`**: This option indicates whether the automation should stop, continue, or go to a different step on failure. The default value for this option is abort.

The following section describes the `aws:branch` automation action. For more information about the `nextStep`, `isEnd`, `isCritical`, and `onFailure` options, see [Example `aws:branch` runbooks](#branch-runbook-examples).

## Working with the `aws:branch` action
<a name="branch-action-explained"></a>

The `aws:branch` action offers the most dynamic conditional branching options for automations. As noted earlier, this action allows your automation to evaluate multiple conditions in a single step and then jump to a new step based on the results of that evaluation. The `aws:branch` action functions like an `IF-ELIF-ELSE` statement in programming.

Here is a YAML example of an `aws:branch` step.

```
- name: ChooseOSforCommands
  action: aws:branch
  inputs:
    Choices:
    - NextStep: runPowerShellCommand
      Variable: "{{GetInstance.platform}}"
      StringEquals: Windows
    - NextStep: runShellCommand
      Variable: "{{GetInstance.platform}}"
      StringEquals: Linux
    Default:
      PostProcessing
```

When you specify the `aws:branch` action for a step, you specify `Choices` that the automation must evaluate. The automation can evaluate `Choices` based on the value of a parameter that you specified in the `Parameters` section of the runbook. The automation can also evaluate `Choices` based on output from a previous step.

The automation evaluates each choice by using a Boolean expression. If the evaluation determines that the first choice is `true`, then the automation jumps to the step designated for that choice. If the evaluation determines that the first choice is `false`, then the automation evaluates the next choice. If your step includes three or more `Choices`, then the automation evaluates each choice in sequential order until it evaluates a choice that is `true`. The automation then jumps to the designated step for the `true` choice.

If none of the `Choices` are `true`, the automation checks to see if the step contains a `Default` value. A `Default` value defines a step that the automation should jump to if none of the choices are `true`. If no `Default` value is specified for the step, then the automation processes the next step in the runbook.

Here is an `aws:branch` step in YAML named **chooseOSfromParameter**. The step includes two `Choices`: (`NextStep: runWindowsCommand`) and (`NextStep: runLinuxCommand`). The automation evaluates these `Choices` to determine which command to run for the appropriate operating system. The `Variable` for each choice uses `{{OSName}}`, which is a parameter that the runbook author defined in the `Parameters` section of the runbook.

```
mainSteps:
- name: chooseOSfromParameter
  action: aws:branch
  inputs:
    Choices:
    - NextStep: runWindowsCommand
      Variable: "{{OSName}}"
      StringEquals: Windows
    - NextStep: runLinuxCommand
      Variable: "{{OSName}}"
      StringEquals: Linux
```

Here is an `aws:branch` step in YAML named **chooseOSfromOutput**. The step includes two `Choices`: (`NextStep: runPowerShellCommand`) and (`NextStep: runShellCommand`). The automation evaluates these `Choices` to determine which command to run for the appropriate operating system. The `Variable` for each choice uses `{{GetInstance.platform}}`, which is the output from an earlier step in the runbook. This example also includes an option called `Default`. If the automation evaluates both `Choices`, and neither choice is `true`, then the automation jumps to a step called `PostProcessing`.

```
mainSteps:
- name: chooseOSfromOutput
  action: aws:branch
  inputs:
    Choices:
    - NextStep: runPowerShellCommand
      Variable: "{{GetInstance.platform}}"
      StringEquals: Windows
    - NextStep: runShellCommand
      Variable: "{{GetInstance.platform}}"
      StringEquals: Linux
    Default:
      PostProcessing
```

### Creating an `aws:branch` step in a runbook
<a name="create-branch-action"></a>

When you create an `aws:branch` step in a runbook, you define the `Choices` the automation should evaluate to determine which step the automation should jump to next. As noted earlier, `Choices` are evaluated by using a Boolean expression. Each choice must define the following options:
+ **NextStep**: The next step in the runbook to process if the designated choice is `true`.
+ **Variable**: Specify either the name of a parameter that is defined in the `Parameters` section of the runbook, a variable defined in the `Variables` section, or specify an output object from a previous step.

  Specify variable values by using the following form.

  `Variable: "{{variable name}}"`

  Specify parameter values by using the following form.

  `Variable: "{{parameter name}}"`

  Specify output object variables by using the following form.

  `Variable: "{{previousStepName.outputName}}"`
**Note**  
Creating the output variable is described in more detail in the next section, [About creating the output variable](#branch-action-output).
+ **Operation**: The criteria used to evaluate the choice, such as `StringEquals: Linux`. The `aws:branch` action supports the following operations:

**String operations**
  + StringEquals
  + EqualsIgnoreCase
  + StartsWith
  + EndsWith
  + Contains

**Numeric operations**
  + NumericEquals
  + NumericGreater
  + NumericLesser
  + NumericGreaterOrEquals
  + NumericLesser
  + NumericLesserOrEquals

**Boolean operation**
  + BooleanEquals
**Important**  
When you create a runbook, the system validates each operation in the runbook. If an operation isn't supported, the system returns an error when you try to create the runbook.
+ **Default**: Specify a fallback step that the automation should jump to if none of the `Choices` are `true`.
**Note**  
If you don't want to specify a `Default` value, then you can specify the `isEnd` option. If none of the `Choices` are `true` and no `Default` value is specified, then the automation stops at the end of the step.

Use the following templates to help you construct the `aws:branch` step in your runbook. Replace each *example resource placeholder* with your own information.

------
#### [ YAML ]

```
mainSteps:
- name: step name
  action: aws:branch
  inputs:
    Choices:
    - NextStep: step to jump to if evaluation for this choice is true
      Variable: "{{parameter name or output from previous step}}"
      Operation type: Operation value
    - NextStep: step to jump to if evaluation for this choice is true
      Variable: "{{parameter name or output from previous step}}"
      Operation type: Operation value
    Default:
      step to jump to if all choices are false
```

------
#### [ JSON ]

```
{
   "mainSteps":[
      {
         "name":"a name for the step",
         "action":"aws:branch",
         "inputs":{
            "Choices":[
               {
                  "NextStep":"step to jump to if evaluation for this choice is true",
                  "Variable":"{{parameter name or output from previous step}}",
                  "Operation type":"Operation value"
               },
               {
                  "NextStep":"step to jump to if evaluation for this choice is true",
                  "Variable":"{{parameter name or output from previous step}}",
                  "Operation type":"Operation value"
               }
            ],
            "Default":"step to jump to if all choices are false"
         }
      }
   ]
}
```

------

#### About creating the output variable
<a name="branch-action-output"></a>

To create an `aws:branch` choice that references the output from a previous step, you need to identify the name of the previous step and the name of the output field. You then combine the names of the step and the field by using the following format.

`Variable: "{{previousStepName.outputName}}"`

For example, the first step in the following example is named `GetInstance`. And then, under `outputs`, there is a field called `platform`. In the second step (`ChooseOSforCommands`), the author wants to reference the output from the platform field as a variable. To create the variable, simply combine the step name (GetInstance) and the output field name (platform) to create `Variable: "{{GetInstance.platform}}"`.

```
mainSteps:
- Name: GetInstance
  action: aws:executeAwsApi
  inputs:
    Service: ssm
    Api: DescribeInstanceInformation
    Filters:
    - Key: InstanceIds
      Values: ["{{ InstanceId }}"]
  outputs:
  - Name: myInstance
    Selector: "$.InstanceInformationList[0].InstanceId"
    Type: String
  - Name: platform
    Selector: "$.InstanceInformationList[0].PlatformType"
    Type: String
- name: ChooseOSforCommands
  action: aws:branch
  inputs:
    Choices:
    - NextStep: runPowerShellCommand
      Variable: "{{GetInstance.platform}}"
      StringEquals: Windows
    - NextStep: runShellCommand
      Variable: "{{GetInstance.platform}}"
      StringEquals: Linux
    Default:
      Sleep
```

Here is an example that shows how *"Variable": "\$1\$1 describeInstance.Platform \$1\$1"* is created from the previous step and the output.

```
- name: describeInstance
  action: aws:executeAwsApi
  onFailure: Abort
  inputs:
    Service: ec2
    Api: DescribeInstances
    InstanceIds:
    - "{{ InstanceId }}"
  outputs:
  - Name: Platform
    Selector: "$.Reservations[0].Instances[0].Platform"
    Type: String
  nextStep: branchOnInstancePlatform
- name: branchOnInstancePlatform
  action: aws:branch
  inputs:
    Choices:
    - NextStep: runEC2RescueForWindows
      Variable: "{{ describeInstance.Platform }}"
      StringEquals: windows
    Default: runEC2RescueForLinux
```

### Example `aws:branch` runbooks
<a name="branch-runbook-examples"></a>

Here are some example runbooks that use `aws:branch`.

**Example 1: Using `aws:branch` with an output variable to run commands based on the operating system type**

In the first step of this example (`GetInstance`), the runbook author uses the `aws:executeAwsApi` action to call the `ssm` `DescribeInstanceInformation` API operation. The author uses this action to determine the type of operating system being used by an instance. The `aws:executeAwsApi` action outputs the instance ID and the platform type.

In the second step (`ChooseOSforCommands`), the author uses the `aws:branch` action with two `Choices` (`NextStep: runPowerShellCommand`) and (`NextStep: runShellCommand`). The automation evaluates the operating system of the instance by using the output from the previous step (`Variable: "{{GetInstance.platform}}"`). The automation jumps to a step for the designated operating system.

```
---
schemaVersion: '0.3'
assumeRole: "{{AutomationAssumeRole}}"
parameters:
  AutomationAssumeRole:
    default: ""
    type: String
mainSteps:
- name: GetInstance
  action: aws:executeAwsApi
  inputs:
    Service: ssm
    Api: DescribeInstanceInformation
  outputs:
  - Name: myInstance
    Selector: "$.InstanceInformationList[0].InstanceId"
    Type: String
  - Name: platform
    Selector: "$.InstanceInformationList[0].PlatformType"
    Type: String
- name: ChooseOSforCommands
  action: aws:branch
  inputs:
    Choices:
    - NextStep: runPowerShellCommand
      Variable: "{{GetInstance.platform}}"
      StringEquals: Windows
    - NextStep: runShellCommand
      Variable: "{{GetInstance.platform}}"
      StringEquals: Linux
    Default:
      Sleep
- name: runShellCommand
  action: aws:runCommand
  inputs:
    DocumentName: AWS-RunShellScript
    InstanceIds:
    - "{{GetInstance.myInstance}}"
    Parameters:
      commands:
      - ls
  isEnd: true
- name: runPowerShellCommand
  action: aws:runCommand
  inputs:
    DocumentName: AWS-RunPowerShellScript
    InstanceIds:
    - "{{GetInstance.myInstance}}"
    Parameters:
      commands:
      - ls
  isEnd: true
- name: Sleep
  action: aws:sleep
  inputs:
    Duration: PT3S
```

**Example 2: Using `aws:branch` with a parameter variable to run commands based on the operating system type**

The runbook author defines several parameter options at the beginning of the runbook in the `parameters` section. One parameter is named `OperatingSystemName`. In the first step (`ChooseOS`), the author uses the `aws:branch` action with two `Choices` (`NextStep: runWindowsCommand`) and (`NextStep: runLinuxCommand`). The variable for these `Choices` references the parameter option specified in the parameters section (`Variable: "{{OperatingSystemName}}"`). When the user runs this runbook, they specify a value at runtime for `OperatingSystemName`. The automation uses the runtime parameter during the `Choices` evaluation. The automation jumps to a step for the designated operating system based on the runtime parameter specified for `OperatingSystemName`.

```
---
schemaVersion: '0.3'
assumeRole: "{{AutomationAssumeRole}}"
parameters:
  AutomationAssumeRole:
    default: ""
    type: String
  OperatingSystemName:
    type: String
  LinuxInstanceId:
    type: String
  WindowsInstanceId:
    type: String
mainSteps:
- name: ChooseOS
  action: aws:branch
  inputs:
    Choices:
    - NextStep: runWindowsCommand
      Variable: "{{OperatingSystemName}}"
      StringEquals: windows
    - NextStep: runLinuxCommand
      Variable: "{{OperatingSystemName}}"
      StringEquals: linux
    Default:
      Sleep
- name: runLinuxCommand
  action: aws:runCommand
  inputs:
    DocumentName: "AWS-RunShellScript"
    InstanceIds:
    - "{{LinuxInstanceId}}"
    Parameters:
      commands:
      - ls
  isEnd: true
- name: runWindowsCommand
  action: aws:runCommand
  inputs:
    DocumentName: "AWS-RunPowerShellScript"
    InstanceIds:
    - "{{WindowsInstanceId}}"
    Parameters:
      commands:
      - date
  isEnd: true
- name: Sleep
  action: aws:sleep
  inputs:
    Duration: PT3S
```

### Creating complex branching automations with operators
<a name="branch-operators"></a>

You can create complex branching automations by using the `And`, `Or`, and `Not` operators in your `aws:branch` steps.

**The 'And' operator**  
Use the `And` operator when you want multiple variables to be `true` for a choice. In the following example, the first choice evaluates if an instance is `running` and uses the `Windows` operating system. If the evaluation of *both* of these variables is true, then the automation jumps to the `runPowerShellCommand` step. If one or more of the variables is `false`, then the automation evaluates the variables for the second choice.

```
mainSteps:
- name: switch2
  action: aws:branch
  inputs:
    Choices:
    - And:
      - Variable: "{{GetInstance.pingStatus}}"
        StringEquals: running
      - Variable: "{{GetInstance.platform}}"
        StringEquals: Windows
      NextStep: runPowerShellCommand

    - And:
      - Variable: "{{GetInstance.pingStatus}}"
        StringEquals: running
      - Variable: "{{GetInstance.platform}}"
        StringEquals: Linux
      NextStep: runShellCommand
    Default:
      sleep3
```

**The 'Or' operator**  
Use the `Or` operator when you want *any* of multiple variables to be true for a choice. In the following example, the first choice evaluates if a parameter string is `Windows` and if the output from an AWS Lambda step is true. If the evaluation determines that *either* of these variables is true, then the automation jumps to the `RunPowerShellCommand` step. If both variables are false, then the automation evaluates the variables for the second choice.

```
- Or:
  - Variable: "{{parameter1}}"
    StringEquals: Windows
  - Variable: "{{BooleanParam1}}"
    BooleanEquals: true
  NextStep: RunPowershellCommand
- Or:
  - Variable: "{{parameter2}}"
    StringEquals: Linux
  - Variable: "{{BooleanParam2}}"
    BooleanEquals: true
  NextStep: RunShellScript
```

**The 'Not' operator**  
Use the `Not` operator when you want to jump to a step defined when a variable is *not* true. In the following example, the first choice evaluates if a parameter string is `Not Linux`. If the evaluation determines that the variable isn't Linux, then the automation jumps to the `sleep2` step. If the evaluation of the first choice determines that it *is* Linux, then the automation evaluates the next choice.

```
mainSteps:
- name: switch
  action: aws:branch
  inputs:
    Choices:
    - NextStep: sleep2
      Not:
        Variable: "{{testParam}}"
        StringEquals: Linux
    - NextStep: sleep1
      Variable: "{{testParam}}"
      StringEquals: Windows
    Default:
      sleep3
```

## Examples of how to use conditional options
<a name="conditional-examples"></a>

This section includes different examples of how to use dynamic options in a runbook. Each example in this section extends the following runbook. This runbook has two actions. The first action is named `InstallMsiPackage`. It uses the `aws:runCommand` action to install an application on a Windows Server instance. The second action is named `TestInstall`. It uses the `aws:invokeLambdaFunction` action to perform a test of the installed application if the application installed successfully. Step one specifies `onFailure: Abort`. This means that if the application didn't install successfully, the automation stops before step two.

**Example 1: Runbook with two linear actions**

```
---
schemaVersion: '0.3'
description: Install MSI package and run validation.
assumeRole: "{{automationAssumeRole}}"
parameters:
  automationAssumeRole:
    type: String
    description: "(Required) Assume role."
  packageName:
    type: String
    description: "(Required) MSI package to be installed."
  instanceIds:
    type: String
    description: "(Required) Comma separated list of instances."
mainSteps:
- name: InstallMsiPackage
  action: aws:runCommand
  maxAttempts: 2
  onFailure: Abort
  inputs:
    InstanceIds:
    - "{{instanceIds}}"
    DocumentName: AWS-RunPowerShellScript
    Parameters:
      commands:
      - msiexec /i {{packageName}}
- name: TestInstall
  action: aws:invokeLambdaFunction
  maxAttempts: 1
  timeoutSeconds: 500
  inputs:
    FunctionName: TestLambdaFunction
...
```

**Creating a dynamic automation that jumps to different steps by using the `onFailure` option**

The following example uses the `onFailure: step:step name`, `nextStep`, and `isEnd` options to create a dynamic automation. With this example, if the `InstallMsiPackage` action fails, then the automation jumps to an action called *PostFailure* (`onFailure: step:PostFailure`) to run an AWS Lambda function to perform some action in the event the install failed. If the install succeeds, then the automation jumps to the TestInstall action (`nextStep: TestInstall`). Both the `TestInstall` and the `PostFailure` steps use the `isEnd` option (`isEnd: true`) so that the automation finishes when either of those steps is completed.

**Note**  
Using the `isEnd` option in the last step of the `mainSteps` section is optional. If the last step doesn't jump to other steps, then the automation stops after running the action in the last step.

**Example 2: A dynamic automation that jumps to different steps**

```
mainSteps
- name: InstallMsiPackage
  action: aws:runCommand
  onFailure: step:PostFailure
  maxAttempts: 2
  inputs:
    InstanceIds:
    - "{{instanceIds}}"
    DocumentName: AWS-RunPowerShellScript
    Parameters:
      commands:
      - msiexec /i {{packageName}}
  nextStep: TestInstall
- name: TestInstall
  action: aws:invokeLambdaFunction
  maxAttempts: 1
  timeoutSeconds: 500
  inputs:
    FunctionName: TestLambdaFunction
  isEnd: true
- name: PostFailure
  action: aws:invokeLambdaFunction
  maxAttempts: 1
  timeoutSeconds: 500
  inputs:
    FunctionName: PostFailureRecoveryLambdaFunction
  isEnd: true
...
```

**Note**  
Before processing a runbook, the system verifies that the runbook doesn't create an infinite loop. If an infinite loop is detected, Automation returns an error and a circle trace showing which steps create the loop.

**Creating a dynamic automation that defines critical steps**

You can specify that a step is critical for the overall success of the automation. If a critical step fails, then Automation reports the status of the automation as `Failed`, even if one or more steps ran successfully. In the following example, the user identifies the *VerifyDependencies* step if the *InstallMsiPackage* step fails (`onFailure: step:VerifyDependencies`). The user specifies that the `InstallMsiPackage` step isn't critical (`isCritical: false`). In this example, if the application failed to install, Automation processes the `VerifyDependencies` step to determine if one or more dependencies is missing, which therefore caused the application install to fail. 

**Example 3: Defining critical steps for the automation **

```
---
name: InstallMsiPackage
action: aws:runCommand
onFailure: step:VerifyDependencies
isCritical: false
maxAttempts: 2
inputs:
  InstanceIds:
  - "{{instanceIds}}"
  DocumentName: AWS-RunPowerShellScript
  Parameters:
    commands:
    - msiexec /i {{packageName}}
nextStep: TestPackage
...
```

# Using action outputs as inputs
<a name="automation-action-outputs-inputs"></a>

Several automation actions return pre-defined outputs. You can pass these outputs as inputs to later steps in your runbook using the format `{{stepName.outputName}}`. You can also define custom outputs for automation actions in your runbooks. This allows you to run scripts, or invoke API operations for other AWS services once so you can reuse the values as inputs in later actions. Parameter types in runbooks are static. This means the parameter type can't be changed after it's defined. To define a step output provide the following fields:
+ Name: (Required) The output name which is used to reference the output value in later steps.
+ Selector: (Required) The JSONPath expression that is used to determine the output value.
+ Type: (Optional) The data type of the value returned by the selector field. Valid type values are `String`, `Integer`, `Boolean`, `StringList`, `StringMap`, `MapList`. The default value is `String`.

If the value of an output doesn't match the data type you've specified, Automation tries to convert the data type. For example, if the value returned is an `Integer`, but the `Type` specified is `String`, the final output value is a `String` value. The following type conversions are supported:
+ `String` values can be converted to `StringList`, `Integer` and `Boolean`.
+ `Integer` values can be converted to `String` and `StringList`.
+ `Boolean` values can be converted to `String` and `StringList`.
+ `StringList`, `IntegerList`, or `BooleanList` values containing one element can be converted to `String`, `Integer`, or `Boolean`.

When using parameters or outputs with automation actions, the data type can't be dynamically changed within an action's input.

Here is an example runbook that demonstrates how to define action outputs, and reference the value as input for a later action. The runbooks does the following:
+ Uses the `aws:executeAwsApi` action to call the Amazon EC2 DescribeImages API operation to get the name of a specific Windows Server 2016 AMI. It outputs the image ID as `ImageId`.
+ Uses the `aws:executeAwsApi` action to call the Amazon EC2 RunInstances API operation to launch one instance that uses the `ImageId` from the previous step. It outputs the instance ID as `InstanceId`.
+ Uses the` aws:waitForAwsResourceProperty` action to poll the Amazon EC2 DescribeInstanceStatus API operation to wait for the instance to reach the `running` state. The action times out in 60 seconds. The step times out if the instance state failed to reach `running` after 60 seconds of polling.
+ Uses the `aws:assertAwsResourceProperty` action to call the Amazon EC2 `DescribeInstanceStatus` API operation to assert that the instance is in the `running` state. The step fails if the instance state isn't `running`.

```
---
description: Sample runbook using AWS API operations
schemaVersion: '0.3'
assumeRole: "{{ AutomationAssumeRole }}"
parameters:
  AutomationAssumeRole:
    type: String
    description: "(Optional) The ARN of the role that allows Automation to perform the actions on your behalf."
    default: ''
  ImageName:
    type: String
    description: "(Optional) Image Name to launch EC2 instance with."
    default: "Windows_Server-2022-English-Full-Base*"
mainSteps:
- name: getImageId
  action: aws:executeAwsApi
  inputs:
    Service: ec2
    Api: DescribeImages
    Filters:  
    - Name: "name"
      Values: 
      - "{{ ImageName }}"
  outputs:
  - Name: ImageId
    Selector: "$.Images[0].ImageId"
    Type: "String"
- name: launchOneInstance
  action: aws:executeAwsApi
  inputs:
    Service: ec2
    Api: RunInstances
    ImageId: "{{ getImageId.ImageId }}"
    MaxCount: 1
    MinCount: 1
  outputs:
  - Name: InstanceId
    Selector: "$.Instances[0].InstanceId"
    Type: "String"
- name: waitUntilInstanceStateRunning
  action: aws:waitForAwsResourceProperty
  timeoutSeconds: 60
  inputs:
    Service: ec2
    Api: DescribeInstanceStatus
    InstanceIds:
    - "{{ launchOneInstance.InstanceId }}"
    PropertySelector: "$.InstanceStatuses[0].InstanceState.Name"
    DesiredValues:
    - running
- name: assertInstanceStateRunning
  action: aws:assertAwsResourceProperty
  inputs:
    Service: ec2
    Api: DescribeInstanceStatus
    InstanceIds:
    - "{{ launchOneInstance.InstanceId }}"
    PropertySelector: "$.InstanceStatuses[0].InstanceState.Name"
    DesiredValues:
    - running
outputs:
- "launchOneInstance.InstanceId"
...
```

Each of the previously described automation actions allows you to call a specific API operation by specifying the service namespace, the API operation name, the input parameters, and the output parameters. Inputs are defined by the API operation that you choose. You can view the API operations (also called methods) by choosing a service in the left navigation on the following [Services Reference](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/index.html) page. Choose a method in the **Client** section for the service that you want to invoke. For example, all API operations (methods) for Amazon Relational Database Service (Amazon RDS) are listed on the following page: [Amazon RDS methods](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/rds.html).

You can view the schema for each automation action in the following locations:
+ [`aws:assertAwsResourceProperty` – Assert an AWS resource state or event state](automation-action-assertAwsResourceProperty.md)
+ [`aws:executeAwsApi` – Call and run AWS API operations](automation-action-executeAwsApi.md)
+ [`aws:waitForAwsResourceProperty` – Wait on an AWS resource property](automation-action-waitForAwsResourceProperty.md)

The schemas include descriptions of the required fields for using each action.

**Using the Selector/PropertySelector fields**  
Each Automation action requires that you specify either an output `Selector` (for `aws:executeAwsApi`) or a `PropertySelector` (for `aws:assertAwsResourceProperty` and `aws:waitForAwsResourceProperty`). These fields are used to process the JSON response from an AWS API operation. These fields use the JSONPath syntax.

Here is an example to help illustrate this concept for the `aws:executeAwsAPi` action.

```
---
mainSteps:
- name: getImageId
  action: aws:executeAwsApi
  inputs:
    Service: ec2
    Api: DescribeImages
    Filters:  
      - Name: "name"
        Values: 
          - "{{ ImageName }}"
  outputs:
    - Name: ImageId
      Selector: "$.Images[0].ImageId"
      Type: "String"
...
```

In the `aws:executeAwsApi` step `getImageId`, the automation invokes the `DescribeImages` API operation and receives a response from `ec2`. The automation then applies `Selector - "$.Images[0].ImageId"` to the API response and assigns the selected value to the output `ImageId` variable. Other steps in the same automation can use the value of `ImageId` by specifying `"{{ getImageId.ImageId }}"`.

Here is an example to help illustrate this concept for the `aws:waitForAwsResourceProperty` action.

```
---
- name: waitUntilInstanceStateRunning
  action: aws:waitForAwsResourceProperty
  # timeout is strongly encouraged for action - aws:waitForAwsResourceProperty
  timeoutSeconds: 60
  inputs:
    Service: ec2
    Api: DescribeInstanceStatus
    InstanceIds:
    - "{{ launchOneInstance.InstanceId }}"
    PropertySelector: "$.InstanceStatuses[0].InstanceState.Name"
    DesiredValues:
    - running
...
```

In the `aws:waitForAwsResourceProperty` step `waitUntilInstanceStateRunning`, the automation invokes the `DescribeInstanceStatus` API operation and receives a response from `ec2`. The automation then applies `PropertySelector - "$.InstanceStatuses[0].InstanceState.Name"` to the response and checks if the specified returned value matches a value in the `DesiredValues` list (in this case `running`). The step repeats the process until the response returns an instance state of `running`. 

## Using JSONPath in runbooks
<a name="automation-action-json-path"></a>

A JSONPath expression is a string beginning with "\$1." that is used to select one of more components within a JSON element. The following list includes information about JSONPath operators that are supported by Systems Manager Automation:
+ **Dot-notated child (.)**: Use with a JSON object. This operator selects the value of a specific key.
+ **Deep-scan (..)**: Use with a JSON element. This operator scans the JSON element level by level and selects a list of values with the specific key. The return type of this operator is always a JSON array. In the context of an automation action output type, the operator can be either StringList or MapList.
+ **Array-Index ([ ])**: Use with a JSON array. This operator gets the value of a specific index.
+ **Filter ([?(*expression*)])**: Use with a JSON array. This operator filters JSON array values that match the criteria defined in the filter expression. Filter expressions can only use the following operators: ==, \$1=, >, <, >=, or <=. Combining multiple filter expressions with AND (&&) or OR (\$1\$1) is not supported. The return type of this operator is always a JSON array. 

To better understand JSONPath operators, review the following JSON response from the ec2 `DescribeInstances` API operation. Following this response are several examples that show different results by applying different JSONPath expressions to the response from the `DescribeInstances` API operation.

```
{
    "NextToken": "abcdefg",
    "Reservations": [
        {
            "OwnerId": "123456789012",
            "ReservationId": "r-abcd12345678910",
            "Instances": [
                {
                    "ImageId": "ami-12345678",
                    "BlockDeviceMappings": [
                        {
                            "Ebs": {
                                "DeleteOnTermination": true,
                                "Status": "attached",
                                "VolumeId": "vol-000000000000"
                            },
                            "DeviceName": "/dev/xvda"
                        }
                    ],
                    "State": {
                        "Code": 16,
                        "Name": "running"
                    }
                }
            ],
            "Groups": []
        },
        {
            "OwnerId": "123456789012",
            "ReservationId": "r-12345678910abcd",
            "Instances": [
                {
                    "ImageId": "ami-12345678",
                    "BlockDeviceMappings": [
                        {
                            "Ebs": {
                                "DeleteOnTermination": true,
                                "Status": "attached",
                                "VolumeId": "vol-111111111111"
                            },
                            "DeviceName": "/dev/xvda"
                        }
                    ],
                    "State": {
                        "Code": 80,
                        "Name": "stopped"
                    }
                }
            ],
            "Groups": []
        }
    ]
}
```

**JSONPath Example 1: Get a specific String from a JSON response**

```
JSONPath: 
$.Reservations[0].Instances[0].ImageId 

Returns:
"ami-12345678"

Type: String
```

**JSONPath Example 2: Get a specific Boolean from a JSON response**

```
JSONPath:
$.Reservations[0].Instances[0].BlockDeviceMappings[0].Ebs.DeleteOnTermination
        
Returns:
true

Type: Boolean
```

**JSONPath Example 3: Get a specific Integer from a JSON response**

```
JSONPath:
$.Reservations[0].Instances[0].State.Code
        
Returns:
16

Type: Integer
```

**JSONPath Example 4: Deep scan a JSON response, then get all of the values for VolumeId as a StringList** 

```
JSONPath:
$.Reservations..BlockDeviceMappings..VolumeId
        
Returns:
[
   "vol-000000000000",
   "vol-111111111111"
]

Type: StringList
```

**JSONPath Example 5: Get a specific BlockDeviceMappings object as a StringMap**

```
JSONPath:
$.Reservations[0].Instances[0].BlockDeviceMappings[0]
        
Returns:
{
   "Ebs" : {
      "DeleteOnTermination" : true,
      "Status" : "attached",
      "VolumeId" : "vol-000000000000"
   },
   "DeviceName" : "/dev/xvda"
}

Type: StringMap
```

**JSONPath Example 6: Deep scan a JSON response, then get all of the State objects as a MapList**

```
JSONPath:
$.Reservations..Instances..State 
    
Returns:
[
   {
      "Code" : 16,
      "Name" : "running"
   },
   {
      "Code" : 80,
      "Name" : "stopped"
   }
]

Type: MapList
```

**JSONPath Example 7: Filter for instances in the `running` state**

```
JSONPath:
$.Reservations..Instances[?(@.State.Name == 'running')]

Returns:
[
  {
    "ImageId": "ami-12345678",
    "BlockDeviceMappings": [
      {
        "Ebs": {
          "DeleteOnTermination": true,
          "Status": "attached",
          "VolumeId": "vol-000000000000"
        },
        "DeviceName": "/dev/xvda"
      }
    ],
    "State": {
      "Code": 16,
      "Name": "running"
    }
  }
]

Type: MapList
```

**JSONPath Example 8: Return the `ImageId` of instances which aren't in the `running` state**

```
JSONPath:
$.Reservations..Instances[?(@.State.Name != 'running')].ImageId

Returns:
[
  "ami-12345678"
]

Type: StringList | String
```

# Creating webhook integrations for Automation
<a name="creating-webhook-integrations"></a>

To send messages using webhooks during an automation, create an integration. Integrations can be invoked during an automation by using the `aws:invokeWebhook` action in your runbook. If you haven't already created a webhook, see [Creating webhooks for integrations](#creating-webhooks). To learn more about the `aws:invokeWebhook` action, see [`aws:invokeWebhook` – Invoke an Automation webhook integration](invoke-webhook.md).

As shown in the following procedures, you can create an integration by using either the Systems Manager Automation console or your preferred command line tool. 

## Creating integrations (console)
<a name="creating-integrations-console"></a>

**To create an integration for Automation (console)**

1. Open the AWS Systems Manager console at [https://console.aws.amazon.com/systems-manager/](https://console.aws.amazon.com/systems-manager/).

1. In the navigation pane, choose **Automation**.

1. Choose the **Integrations** tab.

1. Select **Add integration**, and choose **Webhook**.

1. Enter the required values and any optional values you want to include for the integration.

1. Choose **Add** to create the integration.

## Creating integrations (command line)
<a name="creating-integrations-commandline"></a>

To create an integration using command line tools, you must create the required `SecureString` parameter for an integration. Automation uses a reserved namespace in Parameter Store, a tool in Systems Manager, to store information about your integration. If you create an integration using the AWS Management Console, Automation handles this process for you. Following the namespace, you must specify the type of integration you want to create and then the name of your integration. Currently, Automation supports `webhook` type integrations.

The supported fields for `webhook` type integrations are as follows:
+ Description
+ headers
+ payload
+ URL

**Before you begin**  
If you haven't already, install and configure the AWS Command Line Interface (AWS CLI) or the AWS Tools for PowerShell. For information, see [Installing or updating the latest version of the AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html) and [Installing the AWS Tools for PowerShell](https://docs.aws.amazon.com/powershell/latest/userguide/pstools-getting-set-up.html).

**To create an integration for Automation (command line)**
+ Run the following commands to create the required `SecureString` parameter for an integration. Replace each *example resource placeholder* with your own information. The `/d9d01087-4a3f-49e0-b0b4-d568d7826553/ssm/integrations/webhook/` namespace is reserved in Parameter Store for integrations. The name of your parameter must use this namespace followed by the name of your integration. For example `/d9d01087-4a3f-49e0-b0b4-d568d7826553/ssm/integrations/webhook/myWebhookIntegration`.

------
#### [ Linux & macOS ]

  ```
  aws ssm put-parameter \
      --name "/d9d01087-4a3f-49e0-b0b4-d568d7826553/ssm/integrations/webhook/myWebhookIntegration" \
      --type "SecureString" \
      --data-type "aws:ssm:integration" \
      --value '{"description": "My first webhook integration for Automation.", "url": "myWebHookURL"}'
  ```

------
#### [ Windows ]

  ```
  aws ssm put-parameter ^
      --name "/d9d01087-4a3f-49e0-b0b4-d568d7826553/ssm/integrations/webhook/myWebhookIntegration" ^
      --type "SecureString" ^
      --data-type "aws:ssm:integration" ^
      --value  "{\"description\":\"My first webhook integration for Automation.\",\"url\":\"myWebHookURL\"}"
  ```

------
#### [ PowerShell ]

  ```
  Write-SSMParameter `
      -Name "/d9d01087-4a3f-49e0-b0b4-d568d7826553/ssm/integrations/webhook/myWebhookIntegration" `
      -Type "SecureString"
      -DataType "aws:ssm:integration"
      -Value '{"description": "My first webhook integration for Automation.", "url": "myWebHookURL"}'
  ```

------

## Creating webhooks for integrations
<a name="creating-webhooks"></a>

When creating webhooks with your provider, note the following:
+ Protocol must be HTTPS.
+ Custom request headers are supported.
+ A default request body can be specified.
+ The default request body can be overridden when an integration is invoked by using the `aws:invokeWebhook` action.

# Handling timeouts in runbooks
<a name="automation-handling-timeouts"></a>

The `timeoutSeconds` property is shared by all automation actions. You can use this property to specify the execution timeout value for an action. Further, you can change how an action timing out affects the automation and overall execution status. You can accomplish this by also defining the `onFailure` and `isCritical` shared properties for an action.

For example, depending on your use case, you might want your automation to continue to a different action and not affect the overall status of the automation if an action times out. In this example, you specify the length of time to wait before the action times out using the `timeoutSeconds` property. Then you specify the action, or step, the automation should go to if there is a timeout. Specify a value using the format `step:step name` for the `onFailure` property rather than the default value of `Abort`. By default, if an action times out, the automation execution status will be `Timed Out`. To prevent a timeout from affecting the automation execution status, specify `false` for the `isCritical` property.

The following example shows how to define the shared properties for an action described in this scenario.

------
#### [ YAML ]

```
- name: verifyImageAvailability
  action: 'aws:waitForAwsResourceProperty'
  timeoutSeconds: 600
  isCritical: false
  onFailure: 'step:getCurrentImageState'
  inputs:
    Service: ec2
    Api: DescribeImages
    ImageIds:
      - '{{ createImage.newImageId }}'
    PropertySelector: '$.Images[0].State'
    DesiredValues:
      - available
  nextStep: copyImage
```

------
#### [ JSON ]

```
{
    "name": "verifyImageAvailability",
    "action": "aws:waitForAwsResourceProperty",
    "timeoutSeconds": 600,
    "isCritical": false,
    "onFailure": "step:getCurrentImageState",
    "inputs": {
        "Service": "ec2",
        "Api": "DescribeImages",
        "ImageIds": [
            "{{ createImage.newImageId }}"
        ],
        "PropertySelector": "$.Images[0].State",
        "DesiredValues": [
            "available"
        ]
    },
    "nextStep": "copyImage"
}
```

------

For more information about properties shared by all automation actions, see [Properties shared by all actions](automation-actions.md#automation-common).

# Systems Manager Automation Runbook Reference
<a name="automation-documents-reference"></a>

To help you get started quickly, AWS Systems Manager provides predefined runbooks. These runbooks are maintained by Amazon Web Services, AWS Support, and AWS Config. The Runbook Reference describes each of the predefined runbooks provided by Systems Manager, Support, and AWS Config. For more information, see [Systems Manager Automation Runbook Reference](https://docs.aws.amazon.com/systems-manager-automation-runbooks/latest/userguide).

# Tutorials
<a name="automation-tutorials"></a>

The following tutorials help you to use AWS Systems Manager Automation to address common use cases. These tutorials demonstrate how to use your own runbooks, predefined runbooks provided by Automation, and other Systems Manager tools with other AWS services.

**Contents**
+ [Updating AMIs](automation-tutorial-update-ami.md)
  + [Update a Linux AMI](automation-tutorial-update-patch-linux-ami.md)
  + [Update a Linux AMI (AWS CLI)](automation-tutorial-update-ami.md#update-patch-linux-ami-cli)
  + [Update a Windows Server AMI](automation-tutorial-update-patch-windows-ami.md)
  + [Update a golden AMI using Automation, AWS Lambda, and Parameter Store](automation-tutorial-update-patch-golden-ami.md)
    + [Task 1: Create a parameter in Systems Manager Parameter Store](automation-tutorial-update-patch-golden-ami.md#create-parameter-ami)
    + [Task 2: Create an IAM role for AWS Lambda](automation-tutorial-update-patch-golden-ami.md#create-lambda-role)
    + [Task 3: Create an AWS Lambda function](automation-tutorial-update-patch-golden-ami.md#create-lambda-function)
    + [Task 4: Create a runbook and patch the AMI](automation-tutorial-update-patch-golden-ami.md#create-custom-ami-update-runbook)
  + [Updating AMIs using Automation and Jenkins](automation-tutorial-update-patch-ami-jenkins-integration.md)
  + [Updating AMIs for Auto Scaling groups](automation-tutorial-update-patch-windows-ami-autoscaling.md)
    + [Create the **PatchAMIAndUpdateASG** runbook](automation-tutorial-update-patch-windows-ami-autoscaling.md#create-autoscaling-update-runbook)
+ [Using AWS Support self-service runbooks](automation-tutorial-support-runbooks.md)
  + [Run the EC2Rescue tool on unreachable instances](automation-ec2rescue.md)
    + [How it works](automation-ec2rescue.md#automation-ec2rescue-how)
    + [Before you begin](automation-ec2rescue.md#automation-ec2rescue-begin)
      + [Granting `AWSSupport-EC2Rescue` permissions to perform actions on your instances](automation-ec2rescue.md#automation-ec2rescue-access)
        + [Granting permissions by using IAM policies](automation-ec2rescue.md#automation-ec2rescue-access-iam)
        + [Granting permissions by using an CloudFormation template](automation-ec2rescue.md#automation-ec2rescue-access-cfn)
    + [Running the Automation](automation-ec2rescue.md#automation-ec2rescue-executing)
  + [Reset passwords and SSH keys on EC2 instances](automation-ec2reset.md)
    + [How it works](automation-ec2reset.md#automation-ec2reset-how)
    + [Before you begin](automation-ec2reset.md#automation-ec2reset-begin)
      + [Granting AWSSupport-EC2Rescue permissions to perform actions on your instances](automation-ec2reset.md#automation-ec2reset-access)
        + [Granting permissions by using IAM policies](automation-ec2reset.md#automation-ec2reset-access-iam)
        + [Granting permissions by using an CloudFormation template](automation-ec2reset.md#automation-ec2reset-access-cfn)
    + [Running the Automation](automation-ec2reset.md#automation-ec2reset-executing)
+ [Passing data to Automation using input transformers](automation-tutorial-eventbridge-input-transformers.md)

# Updating AMIs
<a name="automation-tutorial-update-ami"></a>

The following tutorials explain how to update Amazon Machine Image (AMIs) to include the latest patches.

**Topics**
+ [Update a Linux AMI](automation-tutorial-update-patch-linux-ami.md)
+ [Update a Linux AMI (AWS CLI)](#update-patch-linux-ami-cli)
+ [Update a Windows Server AMI](automation-tutorial-update-patch-windows-ami.md)
+ [Update a golden AMI using Automation, AWS Lambda, and Parameter Store](automation-tutorial-update-patch-golden-ami.md)
+ [Updating AMIs using Automation and Jenkins](automation-tutorial-update-patch-ami-jenkins-integration.md)
+ [Updating AMIs for Auto Scaling groups](automation-tutorial-update-patch-windows-ami-autoscaling.md)

# Update a Linux AMI
<a name="automation-tutorial-update-patch-linux-ami"></a>

This Systems Manager Automation walkthrough shows you how to use the console or AWS CLI and the `AWS-UpdateLinuxAmi` runbook to update a Linux AMI with the latest patches of packages that you specify. Automation is a tool in AWS Systems Manager. The `AWS-UpdateLinuxAmi` runbook also automates the installation of additional site-specific packages and configurations. You can update a variety of Linux distributions using this walkthrough, including Ubuntu Server, Red Hat Enterprise Linux (RHEL), or Amazon Linux AMIs. For a full list of supported Linux versions, see [Patch Manager prerequisites](patch-manager-prerequisites.md).

The `AWS-UpdateLinuxAmi` runbook allows you to automate image maintenance tasks without having to author the runbook in JSON or YAML. You can use the `AWS-UpdateLinuxAmi` runbook to perform the following types of tasks.
+ Upgrade all distribution packages and Amazon software on an Amazon Linux, Red Hat Enterprise Linux, or Ubuntu Server Amazon Machine Image (AMI). This is the default runbook behavior.
+ Install AWS Systems Manager SSM Agent on an existing image to enable Systems Manager tools, such as running remote commands using AWS Systems Manager Run Command or software inventory collection using Inventory.
+ Install additional software packages.

**Before you begin**  
Before you begin working with runbooks, configure roles and, optionally, EventBridge for Automation. For more information, see [Setting up Automation](automation-setup.md). This walkthrough also requires that you specify the name of an AWS Identity and Access Management (IAM) instance profile. For more information about creating an IAM instance profile, see [Configure instance permissions required for Systems Manager](setup-instance-permissions.md).

The `AWS-UpdateLinuxAmi` runbook accepts the following input parameters.


****  

| Parameter | Type | Description | 
| --- | --- | --- | 
|  SourceAmiId  |  String  |  (Required) The source AMI ID.  | 
|  IamInstanceProfileName  |  String  |  (Required) The name of the IAM instance profile role you created in [Configure instance permissions required for Systems Manager](setup-instance-permissions.md). The instance profile role gives Automation permission to perform actions on your instances, such as running commands or starting and stopping services. The runbook uses only the name of the instance profile role. If you specify the Amazon Resource Name (ARN), the automation fails.  | 
|  AutomationAssumeRole  |  String  |  (Required) The name of the IAM service role you created in [Setting up Automation](automation-setup.md). The service role (also called an assume role) gives Automation permission to assume your IAM role and perform actions on your behalf. For example, the service role allows Automation to create a new AMI when running the `aws:createImage` action in a runbook. For this parameter, the complete ARN must be specified.  | 
|  TargetAmiName  |  String  |  (Optional) The name of the new AMI after it is created. The default name is a system-generated string that includes the source AMI ID, and the creation time and date.  | 
|  InstanceType  |  String  |  (Optional) The type of instance to launch as the workspace host. Instance types vary by region. The default type is t2.micro.  | 
|  PreUpdateScript  |  String  |  (Optional) URL of a script to run before updates are applied. Default (\$1"none\$1") is to not run a script.  | 
|  PostUpdateScript  |  String  |  (Optional) URL of a script to run after package updates are applied. Default (\$1"none\$1") is to not run a script.  | 
|  IncludePackages  |  String  |  (Optional) Only update these named packages. By default (\$1"all\$1"), all available updates are applied.  | 
|  ExcludePackages  |  String  |  (Optional) Names of packages to hold back from updates, under all conditions. By default (\$1"none\$1"), no package is excluded.  | 

**Automation Steps**  
The `AWS-UpdateLinuxAmi` runbook includes the following automation actions, by default.

**Step 1: launchInstance (`aws:runInstances` action) **  
This step launches an instance using Amazon Elastic Compute Cloud (Amazon EC2) userdata and an IAM instance profile role. Userdata installs the appropriate SSM Agent, based on the operating system. Installing SSM Agent enables you to utilize Systems Manager tools such as Run Command, State Manager, and Inventory.

**Step 2: updateOSSoftware (`aws:runCommand` action) **  
This step runs the following commands on the launched instance:  
+ Downloads an update script from Amazon S3.
+ Runs an optional pre-update script.
+ Updates distribution packages and Amazon software.
+ Runs an optional post-update script.
The execution log is stored in the /tmp folder for the user to view later.  
If you want to upgrade a specific set of packages, you can supply the list using the `IncludePackages` parameter. When provided, the system attempts to update only these packages and their dependencies. No other updates are performed. By default, when no *include* packages are specified, the program updates all available packages.  
If you want to exclude upgrading a specific set of packages, you can supply the list to the `ExcludePackages` parameter. If provided, these packages remain at their current version, independent of any other options specified. By default, when no *exclude* packages are specified, no packages are excluded.

**Step 3: stopInstance (`aws:changeInstanceState` action)**  
This step stops the updated instance.

**Step 4: createImage (`aws:createImage` action) **  
This step creates a new AMI with a descriptive name that links it to the source ID and creation time. For example: “AMI Generated by EC2 Automation on \$1\$1global:DATE\$1TIME\$1\$1 from \$1\$1SourceAmiId\$1\$1” where DATE\$1TIME and SourceID represent Automation variables.

**Step 5: terminateInstance (`aws:changeInstanceState` action) **  
This step cleans up the automation by terminating the running instance.

**Output**  
The automation returns the new AMI ID as output.

**Note**  
By default, when Automation runs the `AWS-UpdateLinuxAmi` runbook, the system creates a temporary instance in the default VPC (172.30.0.0/16). If you deleted the default VPC, you will receive the following error:  
`VPC not defined 400`  
To solve this problem, you must make a copy of the `AWS-UpdateLinuxAmi` runbook and specify a subnet ID. For more information, see [VPC not defined 400](automation-troubleshooting.md#automation-trbl-common-vpc).

**To create a patched AMI using Automation (AWS Systems Manager)**

1. Open the AWS Systems Manager console at [https://console.aws.amazon.com/systems-manager/](https://console.aws.amazon.com/systems-manager/).

1. In the navigation pane, choose **Automation**.

1. Choose **Execute automation**.

1. In the **Automation document** list, choose `AWS-UpdateLinuxAmi`.

1. In the **Document details** section, verify that **Document version** is set to **Default version at runtime**.

1. Choose **Next**.

1. In the **Execution mode** section, choose **Simple Execution**.

1. In the **Input parameters** section, enter the information you collected in the **Before you begin** section.

1. Choose **Execute**. The console displays the status of the Automation execution.

After the automation finishes, launch a test instance from the updated AMI to verify changes.

**Note**  
If any step in the automation fails, information about the failure is listed on the **Automation Executions** page. The automation is designed to terminate the temporary instance after successfully completing all tasks. If a step fails, the system might not terminate the instance. So if a step fails, manually terminate the temporary instance.

## Update a Linux AMI (AWS CLI)
<a name="update-patch-linux-ami-cli"></a>

This AWS Systems Manager Automation walkthrough shows you how to use the AWS Command Line Interface (AWS CLI) and the Systems Manager `AWS-UpdateLinuxAmi` runbook to automatically patch a Linux Amazon Machine Image (AMI) with the latest versions of packages that you specify. Automation is a tool in AWS Systems Manager. The `AWS-UpdateLinuxAmi` runbook also automates the installation of additional site-specific packages and configurations. You can update a variety of Linux distributions using this walkthrough, including Ubuntu Server, Red Hat Enterprise Linux (RHEL), or Amazon Linux AMIs. For a full list of supported Linux versions, see [Patch Manager prerequisites](patch-manager-prerequisites.md).

The `AWS-UpdateLinuxAmi` runbook enables you to automate image-maintenance tasks without having to author the runbook in JSON or YAML. You can use the `AWS-UpdateLinuxAmi` runbook to perform the following types of tasks.
+ Upgrade all distribution packages and Amazon software on an Amazon Linux, RHEL, or Ubuntu Server Amazon Machine Image (AMI). This is the default runbook behavior.
+ Install AWS Systems Manager SSM Agent on an existing image to enable Systems Manager capabilities, such as running remote commands using AWS Systems Manager Run Command or software inventory collection using Inventory.
+ Install additional software packages.

**Before you begin**  
Before you begin working with runbooks, configure roles and, optionally, EventBridge for Automation. For more information, see [Setting up Automation](automation-setup.md). This walkthrough also requires that you specify the name of an AWS Identity and Access Management (IAM) instance profile. For more information about creating an IAM instance profile, see [Configure instance permissions required for Systems Manager](setup-instance-permissions.md).

The `AWS-UpdateLinuxAmi` runbook accepts the following input parameters.


****  

| Parameter | Type | Description | 
| --- | --- | --- | 
|  SourceAmiId  |  String  |  (Required) The source AMI ID. You can automatically reference the latest ID of an Amazon EC2 AMI for Linux by using a AWS Systems Manager Parameter Store *public* parameter. For more information, see [Query for the latest Amazon Linux AMI IDs using AWS Systems Manager Parameter Store](https://aws.amazon.com/blogs/compute/query-for-the-latest-amazon-linux-ami-ids-using-aws-systems-manager-parameter-store/).  | 
|  IamInstanceProfileName  |  String  |  (Required) The name of the IAM instance profile role you created in [Configure instance permissions required for Systems Manager](setup-instance-permissions.md). The instance profile role gives Automation permission to perform actions on your instances, such as running commands or starting and stopping services. The runbook uses only the name of the instance profile role.  | 
|  AutomationAssumeRole  |  String  |  (Required) The name of the IAM service role you created in [Setting up Automation](automation-setup.md). The service role (also called an assume role) gives Automation permission to assume your IAM role and perform actions on your behalf. For example, the service role allows Automation to create a new AMI when running the `aws:createImage` action in a runbook. For this parameter, the complete ARN must be specified.  | 
|  TargetAmiName  |  String  |  (Optional) The name of the new AMI after it is created. The default name is a system-generated string that includes the source AMI ID, and the creation time and date.  | 
|  InstanceType  |  String  |  (Optional) The type of instance to launch as the workspace host. Instance types vary by Region. The default type is t2.micro.  | 
|  PreUpdateScript  |  String  |  (Optional) URL of a script to run before updates are applied. Default (\$1"none\$1") is to not run a script.  | 
|  PostUpdateScript  |  String  |  (Optional) URL of a script to run after package updates are applied. Default (\$1"none\$1") is to not run a script.  | 
|  IncludePackages  |  String  |  (Optional) Only update these named packages. By default (\$1"all\$1"), all available updates are applied.  | 
|  ExcludePackages  |  String  |  (Optional) Names of packages to hold back from updates, under all conditions. By default (\$1"none\$1"), no package is excluded.  | 

**Automation Steps**  
The `AWS-UpdateLinuxAmi` runbook includes the following steps, by default.

**Step 1: launchInstance (`aws:runInstances` action) **  
This step launches an instance using Amazon Elastic Compute Cloud (Amazon EC2) user data and an IAM instance profile role. User data installs the appropriate SSM Agent, based on the operating system. Installing SSM Agent enables you to utilize Systems Manager tools such as Run Command, State Manager, and Inventory.

**Step 2: updateOSSoftware (`aws:runCommand` action) **  
This step runs the following commands on the launched instance:  
+ Downloads an update script from Amazon Simple Storage Service (Amazon S3).
+ Runs an optional pre-update script.
+ Updates distribution packages and Amazon software.
+ Runs an optional post-update script.
The execution log is stored in the /tmp folder for the user to view later.  
If you want to upgrade a specific set of packages, you can supply the list using the `IncludePackages` parameter. When provided, the system attempts to update only these packages and their dependencies. No other updates are performed. By default, when no *include* packages are specified, the program updates all available packages.  
If you want to exclude upgrading a specific set of packages, you can supply the list to the `ExcludePackages` parameter. If provided, these packages remain at their current version, independent of any other options specified. By default, when no *exclude* packages are specified, no packages are excluded.

**Step 3: stopInstance (`aws:changeInstanceState` action)**  
This step stops the updated instance.

**Step 4: createImage (`aws:createImage` action) **  
This step creates a new AMI with a descriptive name that links it to the source ID and creation time. For example: “AMI Generated by EC2 Automation on \$1\$1global:DATE\$1TIME\$1\$1 from \$1\$1SourceAmiId\$1\$1” where DATE\$1TIME and SourceID represent Automation variables.

**Step 5: terminateInstance (`aws:changeInstanceState` action) **  
This step cleans up the automation by terminating the running instance.

**Output**  
The automation returns the new AMI ID as output.

**Note**  
By default, when Automation runs the `AWS-UpdateLinuxAmi` runbook, the system creates a temporary instance in the default VPC (172.30.0.0/16). If you deleted the default VPC, you will receive the following error:  
`VPC not defined 400`  
To solve this problem, you must make a copy of the `AWS-UpdateLinuxAmi` runbook and specify a subnet ID. For more information, see [VPC not defined 400](automation-troubleshooting.md#automation-trbl-common-vpc).

**To create a patched AMI using Automation**

1. Install and configure the AWS Command Line Interface (AWS CLI), if you haven't already.

   For information, see [Installing or updating the latest version of the AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html).

1. Run the following command to run the `AWS-UpdateLinuxAmi` runbook. Replace each *example resource placeholder* with your own information.

   ```
   aws ssm start-automation-execution \
       --document-name "AWS-UpdateLinuxAmi" \
       --parameters \
       SourceAmiId=AMI ID, \
       IamInstanceProfileName=IAM instance profile, \
       AutomationAssumeRole='arn:aws:iam::{{global:ACCOUNT_ID}}:role/AutomationServiceRole'
   ```

   The command returns an execution ID. Copy this ID to the clipboard. You will use this ID to view the status of the automation.

   ```
   {
       "AutomationExecutionId": "automation execution ID"
   }
   ```

1. To view the automation using the AWS CLI, run the following command:

   ```
   aws ssm describe-automation-executions
   ```

1. To view details about the automation progress, run the following command. Replace *automation execution ID* with your own information.

   ```
   aws ssm get-automation-execution --automation-execution-id automation execution ID
   ```

   The update process can take 30 minutes or more to complete.
**Note**  
You can also monitor the status of the automation in the console. In the list, choose the automation you just ran and then choose the **Steps** tab. This tab shows you the status of the automation actions.

After the automation finishes, launch a test instance from the updated AMI to verify changes.

**Note**  
If any step in the automation fails, information about the failure is listed on the **Automation Executions** page. The automation is designed to terminate the temporary instance after successfully completing all tasks. If a step fails, the system might not terminate the instance. So if a step fails, manually terminate the temporary instance.

# Update a Windows Server AMI
<a name="automation-tutorial-update-patch-windows-ami"></a>

The `AWS-UpdateWindowsAmi` runbook enables you to automate image maintenance tasks on your Amazon Windows Amazon Machine Image (AMI) without having to author the runbook in JSON or YAML. This runbook is supported for Windows Server 2008 R2 or later. You can use the `AWS-UpdateWindowsAmi` runbook to perform the following types of tasks.
+ Install all Windows updates and upgrade Amazon software (default behavior).
+ Install specific Windows updates and upgrade Amazon software.
+ Customize an AMI using your scripts.

**Before you begin**  
Before you begin working with runbooks, [configure roles for Automation](automation-setup-iam.md) to add an `iam:PassRole` policy that references the ARN of the instance profile you want to grant access to. Optionally, configure Amazon EventBridge for Automation, a tool in AWS Systems Manager. For more information, see [Setting up Automation](automation-setup.md). This walkthrough also requires that you specify the name of an AWS Identity and Access Management (IAM) instance profile. For more information about creating an IAM instance profile, see [Configure instance permissions required for Systems Manager](setup-instance-permissions.md).

**Note**  
Updates to AWS Systems Manager SSM Agent are typically rolled out to different regions at different times. When you customize or update an AMI, use only source AMIs published for the region that you are working in. This will ensure that you are working with the latest SSM Agent released for that region and avoid compatibility issues.

The `AWS-UpdateWindowsAmi` runbook accepts the following input parameters.


****  

| Parameter | Type | Description | 
| --- | --- | --- | 
|  SourceAmiId  |  String  |  (Required) The source AMI ID. You can automatically reference the latest Windows Server AMI ID by using a Systems Manager Parameter Store *public* parameter. For more information, see [Query for the latest Windows AMI IDs using AWS Systems Manager Parameter Store](https://aws.amazon.com/blogs/mt/query-for-the-latest-windows-ami-using-systems-manager-parameter-store/).  | 
|  SubnetId  |  String  |  (Optional) The subnet you want to launch the temporary instance into. You must specify a value for this parameter if you've deleted your default VPC.  | 
|  IamInstanceProfileName  |  String  |  (Required) The name of the IAM instance profile role you created in [Configure instance permissions required for Systems Manager](setup-instance-permissions.md). The instance profile role gives Automation permission to perform actions on your instances, such as running commands or starting and stopping services. The runbook uses only the name of the instance profile role.  | 
|  AutomationAssumeRole  |  String  |  (Required) The name of the IAM service role you created in [Setting up Automation](automation-setup.md). The service role (also called an assume role) gives Automation permission to assume your IAM role and perform actions on your behalf. For example, the service role allows Automation to create a new AMI when running the `aws:createImage` action in a runbook. For this parameter, the complete ARN must be specified.  | 
|  TargetAmiName  |  String  |  (Optional) The name of the new AMI after it is created. The default name is a system-generated string that includes the source AMI ID, and the creation time and date.  | 
|  InstanceType  |  String  |  (Optional) The type of instance to launch as the workspace host. Instance types vary by region. The default type is t2.medium.  | 
|  PreUpdateScript  |  String  |  (Optional) A script to run before updating the AMI. Enter a script in the runbook or at runtime as a parameter.  | 
|  PostUpdateScript  |  String  |  (Optional) A script to run after updating the AMI. Enter a script in the runbook or at runtime as a parameter.  | 
|  IncludeKbs  |  String  |  (Optional) Specify one or more Microsoft Knowledge Base (KB) article IDs to include. You can install multiple IDs using comma-separated values. Valid formats: KB9876543 or 9876543.  | 
|  ExcludeKbs  |  String  |  (Optional) Specify one or more Microsoft Knowledge Base (KB) article IDs to exclude. You can exclude multiple IDs using comma-separated values. Valid formats: KB9876543 or 9876543.  | 
|  Categories  |  String  |  (Optional)Specify one or more update categories. You can filter categories using comma-separated values. Options: Critical Update, Security Update, Definition Update, Update Rollup, Service Pack, Tool, Update, or Driver. Valid formats include a single entry, for example: Critical Update. Or, you can specify a comma separated list: Critical Update,Security Update,Definition Update.  | 
|  SeverityLevels  |  String  |  (Optional) Specify one or more MSRC severity levels associated with an update. You can filter severity levels using comma-separated values. Options: Critical, Important, Low, Moderate or Unspecified. Valid formats include a single entry, for example: Critical. Or, you can specify a comma separated list: Critical,Important,Low.  | 

**Automation Steps**  
The `AWS-UpdateWindowsAmi` runbook includes the following steps, by default.

**Step 1: launchInstance (`aws:runInstances` action)**  
This step launches an instance with an IAM instance profile role from the specified `SourceAmiID`.

**Step 2: runPreUpdateScript (`aws:runCommand` action)**  
This step enables you to specify a script as a string that runs before updates are installed.

**Step 3: updateEC2Config (`aws:runCommand` action)**  
This step uses the `AWS-InstallPowerShellModule` runbook to download an AWS public PowerShell module. Systems Manager verifies the integrity of the module by using an SHA-256 hash. Systems Manager then checks the operating system to determine whether to update EC2Config or EC2Launch. EC2Config runs on Windows Server 2008 R2 through Windows Server 2012 R2. EC2Launch runs on Windows Server 2016.

**Step 4: updateSSMAgent (`aws:runCommand` action)**  
This step updates SSM Agent by using the `AWS-UpdateSSMAgent` runbook.

**Step 5: updateAWSPVDriver (`aws:runCommand` action)**  
This step updates AWS PV drivers by using the `AWS-ConfigureAWSPackage` runbook.

**Step 6: updateAwsEnaNetworkDriver (`aws:runCommand` action)**  
This step updates AWS ENA Network drivers by using the `AWS-ConfigureAWSPackage` runbook.

**Step 7: installWindowsUpdates (`aws:runCommand` action) **  
This step installs Windows updates by using the `AWS-InstallWindowsUpdates` runbook. By default, Systems Manager searches for and installs all missing updates. You can change the default behavior by specifying one of the following parameters: `IncludeKbs`, `ExcludeKbs`, `Categories`, or `SeverityLevels`. 

**Step 8: runPostUpdateScript (`aws:runCommand` action)**  
This step enables you to specify a script as a string that runs after the updates have been installed.

**Step 9: runSysprepGeneralize (`aws:runCommand` action) **  
This step uses the `AWS-InstallPowerShellModule` runbook to download an AWS public PowerShell module. Systems Manager verifies the integrity of the module by using an SHA-256 hash. Systems Manager then runs sysprep using AWS-supported methods for either EC2Launch (Windows Server 2016) or EC2Config (Windows Server 2008 R2 through 2012 R2).

**Step 10: stopInstance (`aws:changeInstanceState` action) **  
This step stops the updated instance. 

**Step 11: createImage (`aws:createImage` action) **  
This step creates a new AMI with a descriptive name that links it to the source ID and creation time. For example: “AMI Generated by EC2 Automation on \$1\$1global:DATE\$1TIME\$1\$1 from \$1\$1SourceAmiId\$1\$1” where DATE\$1TIME and SourceID represent Automation variables.

**Step 12: TerminateInstance (`aws:changeInstanceState` action) **  
This step cleans up the automation by terminating the running instance. 

**Output**  
This section enables you to designate the outputs of various steps or values of any parameter as the Automation output. By default, the output is the ID of the updated Windows AMI created by the automation.

**Note**  
By default, when Automation runs the `AWS-UpdateWindowsAmi` runbook and creates a temporary instance, the system uses the default VPC (172.30.0.0/16). If you deleted the default VPC, you will receive the following error:  
VPC not defined 400  
To solve this problem, you must make a copy of the `AWS-UpdateWindowsAmi` runbook and specify a subnet ID. For more information, see [VPC not defined 400](automation-troubleshooting.md#automation-trbl-common-vpc).

**To create a patched Windows AMI by using Automation**

1. Install and configure the AWS Command Line Interface (AWS CLI), if you haven't already.

   For information, see [Installing or updating the latest version of the AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html).

1. Run the following command to run the `AWS-UpdateWindowsAmi` runbook. Replace each *example resource placeholder* with your own information. The example command below uses a recent Amazon EC2 AMI to minimize the number of patches that need to be applied. If you run this command more than once, you must specify a unique value for `targetAMIname`. AMI names must be unique.

   ```
   aws ssm start-automation-execution \
       --document-name="AWS-UpdateWindowsAmi" \
       --parameters SourceAmiId='AMI ID',IamInstanceProfileName='IAM instance profile',AutomationAssumeRole='arn:aws:iam::{{global:ACCOUNT_ID}}:role/AutomationServiceRole'
   ```

   The command returns an execution ID. Copy this ID to the clipboard. You will use this ID to view the status of the automation.

   ```
   {
       "AutomationExecutionId": "automation execution ID"
   }
   ```

1. To view the automation using the AWS CLI, run the following command:

   ```
   aws ssm describe-automation-executions
   ```

1. To view details about the automation progress, run the following command.

   ```
   aws ssm get-automation-execution 
       --automation-execution-id automation execution ID
   ```

**Note**  
Depending on the number of patches applied, the Windows patching process run in this sample automation can take 30 minutes or more to complete.

# Update a golden AMI using Automation, AWS Lambda, and Parameter Store
<a name="automation-tutorial-update-patch-golden-ami"></a>

The following example uses the model where an organization maintains and periodically patches their own, proprietary AMIs rather than building from Amazon Elastic Compute Cloud (Amazon EC2) AMIs.

The following procedure shows how to automatically apply operating system (OS) patches to an AMI that is already considered to be the most up-to-date or *latest* AMI. In the example, the default value of the parameter `SourceAmiId` is defined by a AWS Systems Manager Parameter Store parameter called `latestAmi`. The value of `latestAmi` is updated by an AWS Lambda function invoked at the end of the automation. As a result of this Automation process, the time and effort spent patching AMIs is minimized because patching is always applied to the most up-to-date AMI. Parameter Store and Automation are tools of AWS Systems Manager.

**Before you begin**  
Configure Automation roles and, optionally, Amazon EventBridge for Automation. For more information, see [Setting up Automation](automation-setup.md).

**Topics**
+ [Task 1: Create a parameter in Systems Manager Parameter Store](#create-parameter-ami)
+ [Task 2: Create an IAM role for AWS Lambda](#create-lambda-role)
+ [Task 3: Create an AWS Lambda function](#create-lambda-function)
+ [Task 4: Create a runbook and patch the AMI](#create-custom-ami-update-runbook)

## Task 1: Create a parameter in Systems Manager Parameter Store
<a name="create-parameter-ami"></a>

Create a string parameter in Parameter Store that uses the following information:
+ **Name**: `latestAmi`.
+ **Value**: An AMI ID. For example:` ami-188d6e0e`.

For information about how to create a Parameter Store string parameter, see [Creating Parameter Store parameters in Systems Manager](sysman-paramstore-su-create.md).

## Task 2: Create an IAM role for AWS Lambda
<a name="create-lambda-role"></a>

Use the following procedure to create an IAM service role for AWS Lambda. These policies give Lambda permission to update the value of the `latestAmi` parameter using a Lambda function and Systems Manager.

**To create an IAM service role for Lambda**

1. Sign in to the AWS Management Console and open the IAM console at [https://console.aws.amazon.com/iam/](https://console.aws.amazon.com/iam/).

1. In the navigation pane, choose **Policies**, and then choose **Create policy**.

1. Choose the **JSON** tab.

1. Replace the default contents with the following policy. Replace each *example resource placeholder* with your own information.

------
#### [ JSON ]

****  

   ```
   {
       "Version":"2012-10-17",		 	 	 
       "Statement": [
           {
               "Effect": "Allow",
               "Action": "logs:CreateLogGroup",
               "Resource": "arn:aws:logs:us-east-1:111122223333:*"
           },
           {
               "Effect": "Allow",
               "Action": [
                   "logs:CreateLogStream",
                   "logs:PutLogEvents"
               ],
               "Resource": [
                   "arn:aws:logs:us-east-1:111122223333:log-group:/aws/lambda/function name:*"
               ]
           }
       ]
   }
   ```

------

1. Choose **Next: Tags**.

1. (Optional) Add one or more tag-key value pairs to organize, track, or control access for this policy. 

1. Choose **Next: Review**.

1. On the **Review policy** page, for **Name**, enter a name for the inline policy, such as **amiLambda**.

1. Choose **Create policy**.

1. Repeat steps 2 and 3.

1. Paste the following policy. Replace each *example resource placeholder* with your own information.

------
#### [ JSON ]

****  

   ```
   {
       "Version":"2012-10-17",		 	 	 
       "Statement": [
           {
               "Effect": "Allow",
               "Action": "ssm:PutParameter",
               "Resource": "arn:aws:ssm:us-east-1:111122223333:parameter/latestAmi"
           },
           {
               "Effect": "Allow",
               "Action": "ssm:DescribeParameters",
               "Resource": "*"
           }
       ]
   }
   ```

------

1. Choose **Next: Tags**.

1. (Optional) Add one or more tag-key value pairs to organize, track, or control access for this policy. 

1. Choose **Next: Review**.

1. On the **Review policy** page, for **Name**, enter a name for the inline policy, such as **amiParameter**.

1. Choose **Create policy**.

1. In the navigation pane, choose **Roles**, and then choose **Create role**.

1. Immediately under **Use case**, choose **Lambda**, and then choose **Next**.

1. On the **Add permissions** page, use the **Search** field to locate the two policies you created earlier.

1. Select the check box next to the policies, and then choose **Next**.

1. For **Role name**, enter a name for your new role, such as **lambda-ssm-role** or another name that you prefer. 
**Note**  
Because various entities might reference the role, you cannot change the name of the role after it has been created.

1. (Optional) Add one or more tag key-value pairs to organize, track, or control access for this role, and then choose **Create role**.

## Task 3: Create an AWS Lambda function
<a name="create-lambda-function"></a>

Use the following procedure to create a Lambda function that automatically updates the value of the `latestAmi` parameter.

**To create a Lambda function**

1. Sign in to the AWS Management Console and open the AWS Lambda console at [https://console.aws.amazon.com/lambda/](https://console.aws.amazon.com/lambda/).

1. Choose **Create function**.

1. On the **Create function** page, choose **Author from scratch**.

1. For **Function name**, enter **Automation-UpdateSsmParam**.

1. For **Runtime**, choose **Python 3.11**.

1. For **Architecture**, select the type of computer processor for Lambda to use to run the function, **x86\$164** or **arm64**, 

1. In the **Permissions** section, expand **Change default execution role**.

1. Choose **Use an existing role**, and then choose the service role for Lambda that you created in Task 2.

1. Choose **Create function**.

1. In the **Code source** area, on the **lambda\$1function** tab, delete the pre-populated code in the field, and then paste the following code sample.

   ```
   from __future__ import print_function
   
   import json
   import boto3
   
   print('Loading function')
   
   
   #Updates an SSM parameter
   #Expects parameterName, parameterValue
   def lambda_handler(event, context):
       print("Received event: " + json.dumps(event, indent=2))
   
       # get SSM client
       client = boto3.client('ssm')
   
       #confirm  parameter exists before updating it
       response = client.describe_parameters(
          Filters=[
             {
              'Key': 'Name',
              'Values': [ event['parameterName'] ]
             },
           ]
       )
   
       if not response['Parameters']:
           print('No such parameter')
           return 'SSM parameter not found.'
   
       #if parameter has a Description field, update it PLUS the Value
       if 'Description' in response['Parameters'][0]:
           description = response['Parameters'][0]['Description']
           
           response = client.put_parameter(
             Name=event['parameterName'],
             Value=event['parameterValue'],
             Description=description,
             Type='String',
             Overwrite=True
           )
       
       #otherwise just update Value
       else:
           response = client.put_parameter(
             Name=event['parameterName'],
             Value=event['parameterValue'],
             Type='String',
             Overwrite=True
           )
           
       responseString = 'Updated parameter %s with value %s.' % (event['parameterName'], event['parameterValue'])
           
       return responseString
   ```

1. Choose **File, Save**.

1. To test the Lambda function, from the **Test** menu, choose **Configure test event**.

1. For **Event name**, enter a name for the test event, such as **MyTestEvent**.

1. Replace the existing text with the following JSON. Replace *AMI ID* with your own information to set your `latestAmi` parameter value.

   ```
   {
      "parameterName":"latestAmi",
      "parameterValue":"AMI ID"
   }
   ```

1. Choose **Save**.

1. Choose **Test** to test the function. On the **Execution result** tab, the status should be reported as **Succeeded**, along with other details about the update.

## Task 4: Create a runbook and patch the AMI
<a name="create-custom-ami-update-runbook"></a>

Use the following procedure to create and run a runbook that patches the AMI you specified for the **latestAmi** parameter. After the automation completes, the value of **latestAmi** is updated with the ID of the newly-patched AMI. Subsequent automations use the AMI created by the previous execution.

**To create and run the runbook**

1. Open the AWS Systems Manager console at [https://console.aws.amazon.com/systems-manager/](https://console.aws.amazon.com/systems-manager/).

1. In the navigation pane, choose **Documents**.

1. For **Create document**, choose **Automation**.

1. For **Name**, enter **UpdateMyLatestWindowsAmi**.

1. Choose the **Editor** tab, and then choose **Edit**.

1. Choose **OK** when prompted.

1. In the **Document editor** field, replace the default content with the following YAML sample runbook content.

   ```
   ---
   description: Systems Manager Automation Demo - Patch AMI and Update ASG
   schemaVersion: '0.3'
   assumeRole: '{{ AutomationAssumeRole }}'
   parameters:
     AutomationAssumeRole:
       type: String
       description: '(Required) The ARN of the role that allows Automation to perform the actions on your behalf. If no role is specified, Systems Manager Automation uses your IAM permissions to execute this document.'
       default: ''
     SourceAMI:
       type: String
       description: The ID of the AMI you want to patch.
       default: '{{ ssm:latestAmi }}'
     SubnetId:
       type: String
       description: The ID of the subnet where the instance from the SourceAMI parameter is launched.
     SecurityGroupIds:
       type: StringList
       description: The IDs of the security groups to associate with the instance that's launched from the SourceAMI parameter.
     NewAMI:
       type: String
       description: The name of of newly patched AMI.
       default: 'patchedAMI-{{global:DATE_TIME}}'
     InstanceProfile:
       type: String
       description: The name of the IAM instance profile you want the source instance to use.
     SnapshotId:
       type: String
       description: (Optional) The snapshot ID to use to retrieve a patch baseline snapshot.
       default: ''
     RebootOption:
       type: String
       description: '(Optional) Reboot behavior after a patch Install operation. If you choose NoReboot and patches are installed, the instance is marked as non-compliant until a subsequent reboot and scan.'
       allowedValues:
         - NoReboot
         - RebootIfNeeded
       default: RebootIfNeeded
     Operation:
       type: String
       description: (Optional) The update or configuration to perform on the instance. The system checks if patches specified in the patch baseline are installed on the instance. The install operation installs patches missing from the baseline.
       allowedValues:
         - Install
         - Scan
       default: Install
   mainSteps:
     - name: startInstances
       action: 'aws:runInstances'
       timeoutSeconds: 1200
       maxAttempts: 1
       onFailure: Abort
       inputs:
         ImageId: '{{ SourceAMI }}'
         InstanceType: m5.large
         MinInstanceCount: 1
         MaxInstanceCount: 1
         IamInstanceProfileName: '{{ InstanceProfile }}'
         SubnetId: '{{ SubnetId }}'
         SecurityGroupIds: '{{ SecurityGroupIds }}'
     - name: verifyInstanceManaged
       action: 'aws:waitForAwsResourceProperty'
       timeoutSeconds: 600
       inputs:
         Service: ssm
         Api: DescribeInstanceInformation
         InstanceInformationFilterList:
           - key: InstanceIds
             valueSet:
               - '{{ startInstances.InstanceIds }}'
         PropertySelector: '$.InstanceInformationList[0].PingStatus'
         DesiredValues:
           - Online
       onFailure: 'step:terminateInstance'
     - name: installPatches
       action: 'aws:runCommand'
       timeoutSeconds: 7200
       onFailure: Abort
       inputs:
         DocumentName: AWS-RunPatchBaseline
         Parameters:
           SnapshotId: '{{SnapshotId}}'
           RebootOption: '{{RebootOption}}'
           Operation: '{{Operation}}'
         InstanceIds:
           - '{{ startInstances.InstanceIds }}'
     - name: stopInstance
       action: 'aws:changeInstanceState'
       maxAttempts: 1
       onFailure: Continue
       inputs:
         InstanceIds:
           - '{{ startInstances.InstanceIds }}'
         DesiredState: stopped
     - name: createImage
       action: 'aws:createImage'
       maxAttempts: 1
       onFailure: Continue
       inputs:
         InstanceId: '{{ startInstances.InstanceIds }}'
         ImageName: '{{ NewAMI }}'
         NoReboot: false
         ImageDescription: Patched AMI created by Automation
     - name: terminateInstance
       action: 'aws:changeInstanceState'
       maxAttempts: 1
       onFailure: Continue
       inputs:
         InstanceIds:
           - '{{ startInstances.InstanceIds }}'
         DesiredState: terminated
     - name: updateSsmParam
       action: aws:invokeLambdaFunction
       timeoutSeconds: 1200
       maxAttempts: 1
       onFailure: Abort
       inputs:
           FunctionName: Automation-UpdateSsmParam
           Payload: '{"parameterName":"latestAmi", "parameterValue":"{{createImage.ImageId}}"}'
   outputs:
   - createImage.ImageId
   ```

1. Choose **Create automation**.

1. In the navigation pane, choose **Automation**, and then choose **Execute automation**.

1. In the **Choose document** page, choose the **Owned by me** tab.

1. Search for the **UpdateMyLatestWindowsAmi** runbook, and select the button in the **UpdateMyLatestWindowsAmi** card.

1. Choose **Next**.

1. Choose **Simple execution**.

1. Specify values for the input parameters.

1. Choose **Execute**.

1. After the automation completes, choose **Parameter Store** in the navigation pane and confirm that the new value for `latestAmi` matches the value returned by the automation. You can also verify the new AMI ID matches the Automation output in the **AMIs** section of the Amazon EC2 console.

# Updating AMIs using Automation and Jenkins
<a name="automation-tutorial-update-patch-ami-jenkins-integration"></a>

If your organization uses Jenkins software in a CI/CD pipeline, you can add Automation as a post-build step to pre-install application releases into Amazon Machine Images (AMIs). Automation is a tool in AWS Systems Manager. You can also use the Jenkins scheduling feature to call Automation and create your own operating system (OS) patching cadence.

The example below shows how to invoke Automation from a Jenkins server that is running either on-premises or in Amazon Elastic Compute Cloud (Amazon EC2). For authentication, the Jenkins server uses AWS credentials based on an IAM policy that you create in the example and attach to your instance profile.

**Note**  
Be sure to follow Jenkins security best practices when configuring your instance.

**Before you begin**  
Complete the following tasks before you configure Automation with Jenkins:
+ Complete the [Update a golden AMI using Automation, AWS Lambda, and Parameter Store](automation-tutorial-update-patch-golden-ami.md) example. The following example uses the **UpdateMyLatestWindowsAmi** runbook created in that example.
+ Configure IAM roles for Automation. Systems Manager requires an instance profile role and a service role ARN to process automations. For more information, see [Setting up Automation](automation-setup.md).

**To create an IAM policy for the Jenkins server**

1. Sign in to the AWS Management Console and open the IAM console at [https://console.aws.amazon.com/iam/](https://console.aws.amazon.com/iam/).

1. In the navigation pane, choose **Policies**, and then choose **Create policy**.

1. Choose the **JSON** tab.

1. Replace each *example resource placeholder* with your own information.

------
#### [ JSON ]

****  

   ```
   {
       "Version":"2012-10-17",		 	 	 
       "Statement": [
           {
               "Effect": "Allow",
               "Action": "ssm:StartAutomationExecution",
               "Resource": [
                   "arn:aws:ssm:us-east-1:111122223333:document/UpdateMyLatestWindowsAmi",
                   "arn:aws:ssm:us-east-1:111122223333:automation-execution/*"
               ]
           }
       ]
   }
   ```

------

1. Choose **Review policy**.

1. On the **Review policy** page, for **Name**, enter a name for the inline policy, such as **JenkinsPolicy**.

1. Choose **Create policy**.

1. In the navigation pane, choose **Roles**.

1. Choose the instance profile that's attached to your Jenkins server.

1. In the **Permissions** tab, select **Add permissions** and choose **Attach policies**.

1. In the **Other permissions policies** section, enter the name of policy you created in the previous steps. For example, **JenkinsPolicy**.

1. Select the check box next to your policy, and choose **Attach policies**.

Use the following procedure to configure the AWS CLI on your Jenkins server.

**To configure the Jenkins server for Automation**

1. Connect to your Jenkins server on port 8080 using your preferred browser to access the management interface.

1. Enter the password found in `/var/lib/jenkins/secrets/initialAdminPassword`. To display your password, run the following command.

   ```
   sudo cat /var/lib/jenkins/secrets/initialAdminPassword
   ```

1. The Jenkins installation script directs you to the **Customize Jenkins** page. Select **Install suggested plugins**.

1. Once the installation is complete, choose **Administrator Credentials**, select **Save Credentials**, and then select **Start Using Jenkins**.

1. In the left navigation pane, choose **Manage Jenkins**, and then choose **Manage Plugins**.

1. Choose the **Available** tab, and then enter **Amazon EC2 plugin**.

1. Select the check box for **Amazon EC2 plugin**, and then select **Install without restart**.

1. When the installation completes, select **Go back to the top page**.

1. Choose **Manage Jenkins**, and then choose **Manage nodes and clouds**.

1. In the **Configure Clouds** section, select **Add a new cloud**, and then choose **Amazon EC2**.

1. Enter your information in the remaining fields. Make sure you select the **Use EC2 instance profile to obtain credentials** option.

Use the following procedure to configure your Jenkins project to invoke Automation.

**To configure your Jenkins server to invoke Automation**

1. Open the Jenkins console in a web browser.

1. Choose the project that you want to configure with Automation, and then choose **Configure**.

1. On the **Build** tab, choose **Add Build Step**.

1. Choose **Execute shell** or **Execute Windows batch command** (depending on your operating system).

1. In the **Command** field, run an AWS CLI command like the following. Replace each *example resource placeholder* with your own information.

   ```
   aws ssm start-automation-execution \
           --document-name runbook name \
           --region AWS Region of your source AMI \
           --parameters runbook parameters
   ```

   The following example command uses the **UpdateMyLatestWindowsAmi** runbook and the Systems Manager Parameter `latestAmi` created in [Update a golden AMI using Automation, AWS Lambda, and Parameter Store](automation-tutorial-update-patch-golden-ami.md).

   ```
   aws ssm start-automation-execution \
           --document-name UpdateMyLatestWindowsAmi \
           --parameters \
               "sourceAMIid='{{ssm:latestAmi}}'"
           --region region
   ```

   In Jenkins, the command looks like the example in the following screenshot.  
![\[A sample command in Jenkins software.\]](http://docs.aws.amazon.com/systems-manager/latest/userguide/images/sysman-ami-jenkins2.png)

1. In the Jenkins project, choose **Build Now**. Jenkins returns output similar to the following example.  
![\[Sample command output in Jenkins software.\]](http://docs.aws.amazon.com/systems-manager/latest/userguide/images/sysman-ami-jenkins.png)

# Updating AMIs for Auto Scaling groups
<a name="automation-tutorial-update-patch-windows-ami-autoscaling"></a>

The following example updates an Auto Scaling group with a newly patched AMI. This approach ensures that new images are automatically made available to different computing environments that use Auto Scaling groups.

The final step of the automation in this example uses a Python function to create a new launch template that uses the newly patched AMI. Then the Auto Scaling group is updated to use the new launch template. In this type of Auto Scaling scenario, users could terminate existing instances in the Auto Scaling group to force a new instance to launch that uses the new image. Or, users could wait and allow scale-in or scale-out events to naturally launch newer instances.

**Before you begin**  
Complete the following tasks before you begin this example.
+ Configure IAM roles for Automation, a tool in AWS Systems Manager. Systems Manager requires an instance profile role and a service role ARN to process automations. For more information, see [Setting up Automation](automation-setup.md).

## Create the **PatchAMIAndUpdateASG** runbook
<a name="create-autoscaling-update-runbook"></a>

Use the following procedure to create the **PatchAMIAndUpdateASG** runbook that patches the AMI you specify for the **SourceAMI** parameter. The runbook also updates an Auto Scaling group to use the latest, patched AMI.

**To create and run the runbook**

1. Open the AWS Systems Manager console at [https://console.aws.amazon.com/systems-manager/](https://console.aws.amazon.com/systems-manager/).

1. In the navigation pane, choose **Documents**.

1. In the **Create document** dropdown, choose **Automation**.

1. In the **Name** field, enter **PatchAMIAndUpdateASG**.

1. Choose the **Editor** tab, and choose the **Edit**.

1. Choose **OK** when prompted, and delete the content in the **Document editor** field.

1. In the **Document editor** field, paste the following YAML sample runbook content.

   ```
   ---
   description: Systems Manager Automation Demo - Patch AMI and Update ASG
   schemaVersion: '0.3'
   assumeRole: '{{ AutomationAssumeRole }}'
   parameters:
     AutomationAssumeRole:
       type: String
       description: '(Required) The ARN of the role that allows Automation to perform the actions on your behalf. If no role is specified, Systems Manager Automation uses your IAM permissions to execute this document.'
       default: ''
     SourceAMI:
       type: String
       description: '(Required) The ID of the AMI you want to patch.'
     SubnetId:
       type: String
       description: '(Required) The ID of the subnet where the instance from the SourceAMI parameter is launched.'
     SecurityGroupIds:
       type: StringList
       description: '(Required) The IDs of the security groups to associate with the instance launched from the SourceAMI parameter.'
     NewAMI:
       type: String
       description: '(Optional) The name of of newly patched AMI.'
       default: 'patchedAMI-{{global:DATE_TIME}}'
     TargetASG:
       type: String
       description: '(Required) The name of the Auto Scaling group you want to update.'
     InstanceProfile:
       type: String
       description: '(Required) The name of the IAM instance profile you want the source instance to use.'
     SnapshotId:
       type: String
       description: (Optional) The snapshot ID to use to retrieve a patch baseline snapshot.
       default: ''
     RebootOption:
       type: String
       description: '(Optional) Reboot behavior after a patch Install operation. If you choose NoReboot and patches are installed, the instance is marked as non-compliant until a subsequent reboot and scan.'
       allowedValues:
         - NoReboot
         - RebootIfNeeded
       default: RebootIfNeeded
     Operation:
       type: String
       description: (Optional) The update or configuration to perform on the instance. The system checks if patches specified in the patch baseline are installed on the instance. The install operation installs patches missing from the baseline.
       allowedValues:
         - Install
         - Scan
       default: Install
   mainSteps:
     - name: startInstances
       action: 'aws:runInstances'
       timeoutSeconds: 1200
       maxAttempts: 1
       onFailure: Abort
       inputs:
         ImageId: '{{ SourceAMI }}'
         InstanceType: m5.large
         MinInstanceCount: 1
         MaxInstanceCount: 1
         IamInstanceProfileName: '{{ InstanceProfile }}'
         SubnetId: '{{ SubnetId }}'
         SecurityGroupIds: '{{ SecurityGroupIds }}'
     - name: verifyInstanceManaged
       action: 'aws:waitForAwsResourceProperty'
       timeoutSeconds: 600
       inputs:
         Service: ssm
         Api: DescribeInstanceInformation
         InstanceInformationFilterList:
           - key: InstanceIds
             valueSet:
               - '{{ startInstances.InstanceIds }}'
         PropertySelector: '$.InstanceInformationList[0].PingStatus'
         DesiredValues:
           - Online
       onFailure: 'step:terminateInstance'
     - name: installPatches
       action: 'aws:runCommand'
       timeoutSeconds: 7200
       onFailure: Abort
       inputs:
         DocumentName: AWS-RunPatchBaseline
         Parameters:
           SnapshotId: '{{SnapshotId}}'
           RebootOption: '{{RebootOption}}'
           Operation: '{{Operation}}'
         InstanceIds:
           - '{{ startInstances.InstanceIds }}'
     - name: stopInstance
       action: 'aws:changeInstanceState'
       maxAttempts: 1
       onFailure: Continue
       inputs:
         InstanceIds:
           - '{{ startInstances.InstanceIds }}'
         DesiredState: stopped
     - name: createImage
       action: 'aws:createImage'
       maxAttempts: 1
       onFailure: Continue
       inputs:
         InstanceId: '{{ startInstances.InstanceIds }}'
         ImageName: '{{ NewAMI }}'
         NoReboot: false
         ImageDescription: Patched AMI created by Automation
     - name: terminateInstance
       action: 'aws:changeInstanceState'
       maxAttempts: 1
       onFailure: Continue
       inputs:
         InstanceIds:
           - '{{ startInstances.InstanceIds }}'
         DesiredState: terminated
     - name: updateASG
       action: 'aws:executeScript'
       timeoutSeconds: 300
       maxAttempts: 1
       onFailure: Abort
       inputs:
         Runtime: python3.11
         Handler: update_asg
         InputPayload:
           TargetASG: '{{TargetASG}}'
           NewAMI: '{{createImage.ImageId}}'
         Script: |-
           from __future__ import print_function
           import datetime
           import json
           import time
           import boto3
   
           # create auto scaling and ec2 client
           asg = boto3.client('autoscaling')
           ec2 = boto3.client('ec2')
   
           def update_asg(event, context):
               print("Received event: " + json.dumps(event, indent=2))
   
               target_asg = event['TargetASG']
               new_ami = event['NewAMI']
   
               # get object for the ASG we're going to update, filter by name of target ASG
               asg_query = asg.describe_auto_scaling_groups(AutoScalingGroupNames=[target_asg])
               if 'AutoScalingGroups' not in asg_query or not asg_query['AutoScalingGroups']:
                   return 'No ASG found matching the value you specified.'
   
               # gets details of an instance from the ASG that we'll use to model the new launch template after
               source_instance_id = asg_query.get('AutoScalingGroups')[0]['Instances'][0]['InstanceId']
               instance_properties = ec2.describe_instances(
                   InstanceIds=[source_instance_id]
               )
               source_instance = instance_properties['Reservations'][0]['Instances'][0]
   
               # create list of security group IDs
               security_groups = []
               for group in source_instance['SecurityGroups']:
                   security_groups.append(group['GroupId'])
   
               # create a list of dictionary objects for block device mappings
               mappings = []
               for block in source_instance['BlockDeviceMappings']:
                   volume_query = ec2.describe_volumes(
                       VolumeIds=[block['Ebs']['VolumeId']]
                   )
                   volume_details = volume_query['Volumes']
                   device_name = block['DeviceName']
                   volume_size = volume_details[0]['Size']
                   volume_type = volume_details[0]['VolumeType']
                   device = {'DeviceName': device_name, 'Ebs': {'VolumeSize': volume_size, 'VolumeType': volume_type}}
                   mappings.append(device)
   
               # create new launch template using details returned from instance in the ASG and specify the newly patched AMI
               time_stamp = time.time()
               time_stamp_string = datetime.datetime.fromtimestamp(time_stamp).strftime('%m-%d-%Y_%H-%M-%S')
               new_template_name = f'{new_ami}_{time_stamp_string}'
               try:
                   ec2.create_launch_template(
                       LaunchTemplateName=new_template_name,
                       LaunchTemplateData={
                           'BlockDeviceMappings': mappings,
                           'ImageId': new_ami,
                           'InstanceType': source_instance['InstanceType'],
                           'IamInstanceProfile': {
                               'Arn': source_instance['IamInstanceProfile']['Arn']
                           },
                           'KeyName': source_instance['KeyName'],
                           'SecurityGroupIds': security_groups
                       }
                   )
               except Exception as e:
                   return f'Exception caught: {str(e)}'
               else:
                   # update ASG to use new launch template
                   asg.update_auto_scaling_group(
                       AutoScalingGroupName=target_asg,
                       LaunchTemplate={
                           'LaunchTemplateName': new_template_name
                       }
                   )
                   return f'Updated ASG {target_asg} with new launch template {new_template_name} which uses AMI {new_ami}.'
   outputs:
   - createImage.ImageId
   ```

1. Choose **Create automation**.

1. In the navigation pane, choose **Automation**, and then choose **Execute automation**.

1. In the **Choose document** page, choose the **Owned by me** tab.

1. Search for the **PatchAMIAndUpdateASG** runbook, and select the button in the **PatchAMIAndUpdateASG** card.

1. Choose **Next**.

1. Choose **Simple execution**.

1. Specify values for the input parameters. Be sure the `SubnetId` and `SecurityGroupIds` you specify allow access to the public Systems Manager endpoints, or your interface endpoints for Systems Manager.

1. Choose **Execute**.

1. After automation completes, in the Amazon EC2 console, choose **Auto Scaling**, and then choose **Launch Templates**. Verify that you see the new launch template, and that it uses the new AMI.

1. Choose **Auto Scaling**, and then choose **Auto Scaling Groups**. Verify that the Auto Scaling group uses the new launch template.

1. Terminate one or more instances in your Auto Scaling group. Replacement instances will be launched using the new AMI.

# Using AWS Support self-service runbooks
<a name="automation-tutorial-support-runbooks"></a>

This section describes how to use some of the self-service automations created by the AWS Support team. These automations help you manage your AWS resources.

**Support Automation Workflows**  
Support Automation Workflows (SAW) are automation runbooks written and maintained by the AWS Support team. These runbooks help you troubleshoot common issues with your AWS resources, proactively monitor and identify network issues, collect and analyze logs, and more.

SAW runbooks use the **`AWSSupport`** prefix. For example, [https://docs.aws.amazon.com/systems-manager-automation-runbooks/latest/userguide/automation-awssupport-activatewindowswithamazonlicense.html](https://docs.aws.amazon.com/systems-manager-automation-runbooks/latest/userguide/automation-awssupport-activatewindowswithamazonlicense.html).

Additionally, customers with Business Support\$1 and higher AWS Support plans also have access to runbooks that use the **`AWSPremiumSupport`** prefix. For example, [https://docs.aws.amazon.com/systems-manager-automation-runbooks/latest/userguide/automation-awspremiumsupport-troubleshootEC2diskusage.html](https://docs.aws.amazon.com/systems-manager-automation-runbooks/latest/userguide/automation-awspremiumsupport-troubleshootEC2diskusage.html).

To learn more about AWS Support, see [Getting started with AWS Support](https://docs.aws.amazon.com/awssupport/latest/user/getting-started.html).

**Topics**
+ [Run the EC2Rescue tool on unreachable instances](automation-ec2rescue.md)
+ [Reset passwords and SSH keys on EC2 instances](automation-ec2reset.md)

# Run the EC2Rescue tool on unreachable instances
<a name="automation-ec2rescue"></a>

EC2Rescue can help you diagnose and troubleshoot problems on Amazon Elastic Compute Cloud (Amazon EC2) instances for Linux and Windows Server. You can run the tool manually, as described in [Using EC2Rescue for Linux Server](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/Linux-Server-EC2Rescue.html) and [Using EC2Rescue for Windows Server](https://docs.aws.amazon.com/AWSEC2/latest/WindowsGuide/Windows-Server-EC2Rescue.html). Or, you can run the tool automatically by using Systems Manager Automation and the **`AWSSupport-ExecuteEC2Rescue`** runbook. Automation is a tool in AWS Systems Manager. The **`AWSSupport-ExecuteEC2Rescue`** runbook is designed to perform a combination of Systems Manager actions, CloudFormation actions, and Lambda functions that automate the steps normally required to use EC2Rescue. 

You can use the **`AWSSupport-ExecuteEC2Rescue`** runbook to troubleshoot and potentially remediate different types of operating system (OS) issues. Instances with encypted root volumes are not supported. See the following topics for a complete list:

**Windows**: See *Rescue Action* in [Using EC2Rescue for Windows Server with the Command Line](https://docs.aws.amazon.com/AWSEC2/latest/WindowsGuide/ec2rw-cli.html#ec2rw-rescue).

**Linux** and **macOS**: Some EC2Rescue for Linux modules detect and attempt to remediate issues. For more information, see the [https://github.com/awslabs/aws-ec2rescue-linux/tree/master/docs](https://github.com/awslabs/aws-ec2rescue-linux/tree/master/docs) documentation for each module on GitHub.

## How it works
<a name="automation-ec2rescue-how"></a>

Troubleshooting an instance with Automation and the **`AWSSupport-ExecuteEC2Rescue`** runbook works as follows:
+ You specify the ID of the unreachable instance and start the runbook.
+ The system creates a temporary VPC, and then runs a series of Lambda functions to configure the VPC.
+ The system identifies a subnet for your temporary VPC in the same Availability Zone as your original instance.
+ The system launches a temporary, SSM-enabled helper instance.
+ The system stops your original instance, and creates a backup. It then attaches the original root volume to the helper instance.
+ The system uses Run Command to run EC2Rescue on the helper instance. EC2Rescue identifies and attempts to fix issues on the attached, original root volume. When finished, EC2Rescue reattaches the root volume back to the original instance.
+ The system restarts your original instance, and terminates the temporary instance. The system also terminates the temporary VPC and the Lambda functions created at the start of the automation.

## Before you begin
<a name="automation-ec2rescue-begin"></a>

Before you run the following Automation, do the following:
+ Copy the instance ID of the unreachable instance. You will specify this ID in the procedure.
+ Optionally, collect the ID of a subnet in the same availability zone as your unreachable instance. The EC2Rescue instance will be created in this subnet. If you don’t specify a subnet, then Automation creates a new temporary VPC in your AWS account. Verify that your AWS account has at least one VPC available. By default, you can create five VPCs in a Region. If you already created five VPCs in the Region, the automation fails without making changes to your instance. For more information about Amazon VPC quotas, see [VPC and Subnets](https://docs.aws.amazon.com/vpc/latest/userguide/amazon-vpc-limits.html#vpc-limits-vpcs-subnets) in the *Amazon VPC User Guide*.
+ Optionally, you can create and specify an AWS Identity and Access Management (IAM) role for Automation. If you don't specify this role, then Automation runs in the context of the user who ran the automation.

### Granting `AWSSupport-EC2Rescue` permissions to perform actions on your instances
<a name="automation-ec2rescue-access"></a>

EC2Rescue needs permission to perform a series of actions on your instances during the automation. These actions invoke the AWS Lambda, IAM, and Amazon EC2 services to safely and securely attempt to remediate issues with your instances. If you have Administrator-level permissions in your AWS account and/or VPC, you might be able to run the automation without configuring permissions, as described in this section. If you don't have Administrator-level permissions, then you or an administrator must configure permissions by using one of the following options.
+ [Granting permissions by using IAM policies](#automation-ec2rescue-access-iam)
+ [Granting permissions by using an CloudFormation template](#automation-ec2rescue-access-cfn)

#### Granting permissions by using IAM policies
<a name="automation-ec2rescue-access-iam"></a>

You can either attach the following IAM policy to your user, group, or role as an inline policy; or, you can create a new IAM managed policy and attach it to your user, group, or role. For more information about adding an inline policy to your user, group, or role see [Working With Inline Policies](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_inline-using.html). For more information about creating a new managed policy, see [Working With Managed Policies](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_managed-using.html).

**Note**  
If you create a new IAM managed policy, you must also attach the **AmazonSSMAutomationRole** managed policy to it so that your instances can communicate with the Systems Manager API.

**IAM Policy for AWSSupport-EC2Rescue**

Replace *account ID* with your own information.

------
#### [ JSON ]

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Action": [
                "lambda:InvokeFunction",
                "lambda:DeleteFunction",
                "lambda:GetFunction"
            ],
            "Resource": "arn:aws:lambda:*:111122223333:function:AWSSupport-EC2Rescue-*",
            "Effect": "Allow"
        },
        {
            "Action": [
                "s3:GetObject",
                "s3:GetObjectVersion"
            ],
            "Resource": [
                "arn:aws:s3:::awssupport-ssm.*/*.template",
                "arn:aws:s3:::awssupport-ssm.*/*.zip"
            ],
            "Effect": "Allow"
        },
        {
            "Action": [
                "iam:CreateRole",
                "iam:CreateInstanceProfile",
                "iam:GetRole",
                "iam:GetInstanceProfile",
                "iam:PutRolePolicy",
                "iam:DetachRolePolicy",
                "iam:AttachRolePolicy",
                "iam:PassRole",
                "iam:AddRoleToInstanceProfile",
                "iam:RemoveRoleFromInstanceProfile",
                "iam:DeleteRole",
                "iam:DeleteRolePolicy",
                "iam:DeleteInstanceProfile"
            ],
            "Resource": [
                "arn:aws:iam::111122223333:role/AWSSupport-EC2Rescue-*",
                "arn:aws:iam::111122223333:instance-profile/AWSSupport-EC2Rescue-*"
            ],
            "Effect": "Allow"
        },
        {
            "Action": [
                "lambda:CreateFunction",
                "ec2:CreateVpc",
                "ec2:ModifyVpcAttribute",
                "ec2:DeleteVpc",
                "ec2:CreateInternetGateway",
                "ec2:AttachInternetGateway",
                "ec2:DetachInternetGateway",
                "ec2:DeleteInternetGateway",
                "ec2:CreateSubnet",
                "ec2:DeleteSubnet",
                "ec2:CreateRoute",
                "ec2:DeleteRoute",
                "ec2:CreateRouteTable",
                "ec2:AssociateRouteTable",
                "ec2:DisassociateRouteTable",
                "ec2:DeleteRouteTable",
                "ec2:CreateVpcEndpoint",
                "ec2:DeleteVpcEndpoints",
                "ec2:ModifyVpcEndpoint",
                "ec2:Describe*",
                "autoscaling:DescribeAutoScalingInstances"
            ],
            "Resource": "*",
            "Effect": "Allow"
        }
    ]
}
```

------

#### Granting permissions by using an CloudFormation template
<a name="automation-ec2rescue-access-cfn"></a>

CloudFormation automates the process of creating IAM roles and policies by using a preconfigured template. Use the following procedure to create the required IAM roles and policies for the EC2Rescue Automation by using CloudFormation.

**To create the required IAM roles and policies for EC2Rescue**

1. Download [https://docs.aws.amazon.com/systems-manager/latest/userguide/samples/AWSSupport-EC2RescueRole.zip](https://docs.aws.amazon.com/systems-manager/latest/userguide/samples/AWSSupport-EC2RescueRole.zip) and extract the `AWSSupport-EC2RescueRole.json` file to a directory on your local machine.

1. If your AWS account is in a special partition, edit the template to change the ARN values to those for your partition.

   For example, for the China Regions, change all cases of `arn:aws` to `arn:aws-cn`.

1. Sign in to the AWS Management Console and open the CloudFormation console at [https://console.aws.amazon.com/cloudformation](https://console.aws.amazon.com/cloudformation/).

1. Choose **Create stack**, **With new resources (standard)**.

1. On the **Create stack** page, for **Prerequisite - Prepare template**, choose **Template is ready**.

1. For **Specify template**, choose **Upload a template file**.

1. Choose **Choose file**, and then browse to and select the `AWSSupport-EC2RescueRole.json` file from the directory where you extracted it.

1. Choose **Next**.

1. On the **Specify stack details** page, for **Stack name** field, enter a name to identify this stack, and then choose **Next**.

1. (Optional) In the **Tags** area, apply one or more tag key name/value pairs to the stack.

   Tags are optional metadata that you assign to a resource. Tags enable you to categorize a resource in different ways, such as by purpose, owner, or environment. For example, you might want to tag a stack to identify the type of tasks it runs, the types of targets or other resources involved, and the environment it runs in.

1. Choose **Next**

1. On the **Review** page, review the stack details, and then scroll down and choose the **I acknowledge that CloudFormation might create IAM resources** option.

1. Choose **Create stack**.

   CloudFormation shows the **CREATE\$1IN\$1PROGRESS** status for a few minutes. The status changes to **CREATE\$1COMPLETE** after the stack has been created. You can also choose the refresh icon to check the status of the create process.

1. In the **Stacks** list, choose the option button the stack you just created, and then choose the **Outputs** tab.

1. Note the **Value**. The is the ARN of the AssumeRole. You specify this ARN when you run the Automation in the next procedure, [Running the Automation](#automation-ec2rescue-executing). 

## Running the Automation
<a name="automation-ec2rescue-executing"></a>

**Important**  
The following automation stops the unreachable instance. Stopping the instance can result in lost data on attached instance store volumes (if present). Stopping the instance can also cause the public IP to change, if no Elastic IP is associated.

**To run the `AWSSupport-ExecuteEC2Rescue` Automation**

1. Open the AWS Systems Manager console at [https://console.aws.amazon.com/systems-manager/](https://console.aws.amazon.com/systems-manager/).

1. In the navigation pane, choose **Automation**.

1. Choose **Execute automation**.

1. In the **Automation document** section, choose **Owned by Amazon** from the list.

1. In the runbooks list, choose the button in the card for `AWSSupport-ExecuteEC2Rescue`, and then choose **Next**.

1. In the **Execute automation document** page, choose **Simple execution**.

1. In the **Document details** section, verify that **Document version** is set to the highest default version. For example, **\$1DEFAULT** or **3 (default)**.

1. In the **Input parameters** section, specify the following parameters: 

   1. For **UnreachableInstanceId**, specify the ID of the unreachable instance. 

   1. (Optional) For **EC2RescueInstanceType**, specify an instance type for the EC2Rescue instance. The default instance type is `t2.medium`.

   1. For **AutomationAssumeRole**, if you created roles for this Automation by using the CloudFormation procedure described earlier in this topic, then choose the ARN of the AssumeRole that you created in the CloudFormation console.

   1. (Optional) For **LogDestination**, specify an S3 bucket if you want to collect operating system-level logs while troubleshooting your instance. Logs are automatically uploaded to the specified bucket.

   1. For **SubnetId**, specify a subnet in an existing VPC in the same availability zone as the unreachable instance. By default, Systems Manager creates a new VPC, but you can specify a subnet in an existing VPC if you want.
**Note**  
If you don't see the option to specify a bucket or a subnet ID, verify that you are using the latest **Default** version of the runbook.

1. (Optional) In the **Tags** area, apply one or more tag key name/value pairs to help identify the automation, for example `Key=Purpose,Value=EC2Rescue`.

1. Choose **Execute**.

The runbook creates a backup AMI as part of the automation. All other resources created by the automation are automatically deleted, but this AMI remains in your account. The AMI is named using the following convention:

Backup AMI: AWSSupport-EC2Rescue:*UnreachableInstanceId*

You can locate this AMI in the Amazon EC2 console by searching on the Automation execution ID.

# Reset passwords and SSH keys on EC2 instances
<a name="automation-ec2reset"></a>

You can use the `AWSSupport-ResetAccess` runbook to automatically re-enable local Administrator password generation on Amazon Elastic Compute Cloud (Amazon EC2) instances for Windows Server and to generate a new SSH key on EC2 instances for Linux. The `AWSSupport-ResetAccess` runbook is designed to perform a combination of AWS Systems Manager actions, AWS CloudFormation actions, and AWS Lambda functions that automate the steps normally required to reset the local administrator password.

You can use Automation, a tool in AWS Systems Manager, with the `AWSSupport-ResetAccess` runbook to solve the following problems:

**Windows**

*You lost the EC2 key pair*: To resolve this problem, you can use the **AWSSupport-ResetAccess** runbook to create a password-enabled AMI from your current instance, launch a new instance from the AMI, and select a key pair you own.

*You lost the local Administrator password*: To resolve this problem, you can use the `AWSSupport-ResetAccess` runbook to generate a new password that you can decrypt with the current EC2 key pair.

**Linux**

*You lost your EC2 key pair, or you configured SSH access to the instance with a key you lost*: To resolve this problem, you can use the `AWSSupport-ResetAccess` runbook to create a new SSH key for your current instance, which enables you to connect to the instance again.

**Note**  
If your EC2 instance for Windows Server is configured for Systems Manager, you can also reset your local Administrator password by using EC2Rescue and AWS Systems Manager Run Command. For more information, see [Using EC2Rescue for Windows Server with Systems Manager Run Command](https://docs.aws.amazon.com/AWSEC2/latest/WindowsGuide/ec2rw-ssm.html) in the *Amazon EC2 User Guide*.

**Related information**  
[Connect to your Linux instance from Windows using PuTTY](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/putty.html) in the *Amazon EC2 User Guide*

## How it works
<a name="automation-ec2reset-how"></a>

Troubleshooting an instance with Automation and the `AWSSupport-ResetAccess` runbook works as follows:
+ You specify the ID of the instance and run the runbook.
+ The system creates a temporary VPC, and then runs a series of Lambda functions to configure the VPC.
+ The system identifies a subnet for your temporary VPC in the same Availability Zone as your original instance.
+ The system launches a temporary, SSM-enabled helper instance.
+ The system stops your original instance, and creates a backup. It then attaches the original root volume to the helper instance.
+ The system uses Run Command to run EC2Rescue on the helper instance. On Windows, EC2Rescue enables password generation for the local Administrator by using EC2Config or EC2Launch on the attached, original root volume. On Linux, EC2Rescue generates and injects a new SSH key and saves the private key, encrypted, in Parameter Store. When finished, EC2Rescue reattaches the root volume back to the original instance.
+ The system creates a new Amazon Machine Image (AMI) of your instance, now that password generation is enabled. You can use this AMI to create a new EC2 instance, and associate a new key pair if needed.
+ The system restarts your original instance, and terminates the temporary instance. The system also terminates the temporary VPC and the Lambda functions created at the start of the automation.
+ **Windows**: Your instance generates a new password you can decode from the Amazon EC2 console using the current key pair assigned to the instance.

  **Linux**: You can SSH to the instance by using the SSH key stored in Systems Manager Parameter Store as **/ec2rl/openssh/*instance ID*/key**.

## Before you begin
<a name="automation-ec2reset-begin"></a>

Before you run the following Automation, do the following:
+ Copy the instance ID of the instance on which you want to reset the Administrator password. You will specify this ID in the procedure.
+ Optionally, collect the ID of a subnet in the same availability zone as your unreachable instance. The EC2Rescue instance will be created in this subnet. If you don’t specify a subnet, then Automation creates a new temporary VPC in your AWS account. Verify that your AWS account has at least one VPC available. By default, you can create five VPCs in a Region. If you already created five VPCs in the Region, the automation fails without making changes to your instance. For more information about Amazon VPC quotas, see [VPC and Subnets](https://docs.aws.amazon.com/vpc/latest/userguide/amazon-vpc-limits.html#vpc-limits-vpcs-subnets) in the *Amazon VPC User Guide*.
+ Optionally, you can create and specify an AWS Identity and Access Management (IAM) role for Automation. If you don't specify this role, then Automation runs in the context of the user who ran the automation.

### Granting AWSSupport-EC2Rescue permissions to perform actions on your instances
<a name="automation-ec2reset-access"></a>

EC2Rescue needs permission to perform a series of actions on your instances during the automation. These actions invoke the AWS Lambda, IAM, and Amazon EC2 services to safely and securely attempt to remediate issues with your instances. If you have Administrator-level permissions in your AWS account and/or VPC, you might be able to run the automation without configuring permissions, as described in this section. If you don't have Administrator-level permissions, then you or an administrator must configure permissions by using one of the following options.
+ [Granting permissions by using IAM policies](#automation-ec2reset-access-iam)
+ [Granting permissions by using an CloudFormation template](#automation-ec2reset-access-cfn)

#### Granting permissions by using IAM policies
<a name="automation-ec2reset-access-iam"></a>

You can either attach the following IAM policy to your user, group, or role as an inline policy; or, you can create a new IAM managed policy and attach it to your user, group, or role. For more information about adding an inline policy to your user, group, or role see [Working With Inline Policies](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_inline-using.html). For more information about creating a new managed policy, see [Working With Managed Policies](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_managed-using.html).

**Note**  
If you create a new IAM managed policy, you must also attach the **AmazonSSMAutomationRole** managed policy to it so that your instances can communicate with the Systems Manager API.

**IAM Policy for `AWSSupport-ResetAccess`**

Replace *account ID* with your own information.

------
#### [ JSON ]

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Action": [
                "lambda:InvokeFunction",
                "lambda:DeleteFunction",
                "lambda:GetFunction"
            ],
            "Resource": "arn:aws:lambda:*:111122223333:function:AWSSupport-EC2Rescue-*",
            "Effect": "Allow"
        },
        {
            "Action": [
                "s3:GetObject",
                "s3:GetObjectVersion"
            ],
            "Resource": [
                "arn:aws:s3:::awssupport-ssm.*/*.template",
                "arn:aws:s3:::awssupport-ssm.*/*.zip"
            ],
            "Effect": "Allow"
        },
        {
            "Action": [
                "iam:CreateRole",
                "iam:CreateInstanceProfile",
                "iam:GetRole",
                "iam:GetInstanceProfile",
                "iam:PutRolePolicy",
                "iam:DetachRolePolicy",
                "iam:AttachRolePolicy",
                "iam:PassRole",
                "iam:AddRoleToInstanceProfile",
                "iam:RemoveRoleFromInstanceProfile",
                "iam:DeleteRole",
                "iam:DeleteRolePolicy",
                "iam:DeleteInstanceProfile"
            ],
            "Resource": [
                "arn:aws:iam::111122223333:role/AWSSupport-EC2Rescue-*",
                "arn:aws:iam::111122223333:instance-profile/AWSSupport-EC2Rescue-*"
            ],
            "Effect": "Allow"
        },
        {
            "Action": [
                "lambda:CreateFunction",
                "ec2:CreateVpc",
                "ec2:ModifyVpcAttribute",
                "ec2:DeleteVpc",
                "ec2:CreateInternetGateway",
                "ec2:AttachInternetGateway",
                "ec2:DetachInternetGateway",
                "ec2:DeleteInternetGateway",
                "ec2:CreateSubnet",
                "ec2:DeleteSubnet",
                "ec2:CreateRoute",
                "ec2:DeleteRoute",
                "ec2:CreateRouteTable",
                "ec2:AssociateRouteTable",
                "ec2:DisassociateRouteTable",
                "ec2:DeleteRouteTable",
                "ec2:CreateVpcEndpoint",
                "ec2:DeleteVpcEndpoints",
                "ec2:ModifyVpcEndpoint",
                "ec2:Describe*"
            ],
            "Resource": "*",
            "Effect": "Allow"
        }
    ]
}
```

------

#### Granting permissions by using an CloudFormation template
<a name="automation-ec2reset-access-cfn"></a>

CloudFormation automates the process of creating IAM roles and policies by using a preconfigured template. Use the following procedure to create the required IAM roles and policies for the EC2Rescue Automation by using CloudFormation.

**To create the required IAM roles and policies for EC2Rescue**

1. Download [https://docs.aws.amazon.com/systems-manager/latest/userguide/samples/AWSSupport-EC2RescueRole.zip](https://docs.aws.amazon.com/systems-manager/latest/userguide/samples/AWSSupport-EC2RescueRole.zip) and extract the `AWSSupport-EC2RescueRole.json` file to a directory on your local machine.

1. If your AWS account is in a special partition, edit the template to change the ARN values to those for your partition.

   For example, for the China Regions, change all cases of `arn:aws` to `arn:aws-cn`.

1. Sign in to the AWS Management Console and open the CloudFormation console at [https://console.aws.amazon.com/cloudformation](https://console.aws.amazon.com/cloudformation/).

1. Choose **Create stack**, **With new resources (standard)**.

1. On the **Create stack** page, for **Prerequisite - Prepare template**, choose **Template is ready**.

1. For **Specify template**, choose **Upload a template file**.

1. Choose **Choose file**, and then browse to and select the `AWSSupport-EC2RescueRole.json` file from the directory where you extracted it.

1. Choose **Next**.

1. On the **Specify stack details** page, for **Stack name** field, enter a name to identify this stack, and then choose **Next**.

1. (Optional) In the **Tags** area, apply one or more tag key name/value pairs to the stack.

   Tags are optional metadata that you assign to a resource. Tags enable you to categorize a resource in different ways, such as by purpose, owner, or environment. For example, you might want to tag a stack to identify the type of tasks it runs, the types of targets or other resources involved, and the environment it runs in.

1. Choose **Next**

1. On the **Review** page, review the stack details, and then scroll down and choose the **I acknowledge that CloudFormation might create IAM resources** option.

1. CloudFormation shows the **CREATE\$1IN\$1PROGRESS** status for a few minutes. The status changes to **CREATE\$1COMPLETE** after the stack has been created. You can also choose the refresh icon to check the status of the create process.

1. In the stack list, choose the option next to the stack you just created, and then choose the **Outputs** tab.

1. Copy the **Value**. The is the ARN of the AssumeRole. You will specify this ARN when you run the Automation. 

## Running the Automation
<a name="automation-ec2reset-executing"></a>

The following procedure describes how to run the `AWSSupport-ResetAccess` runbook by using the AWS Systems Manager console.

**Important**  
The following automation stops the instance. Stopping the instance can result in lost data on attached instance store volumes (if present). Stopping the instance can also cause the public IP to change, if no Elastic IP is associated. To avoid these configuration changes, use Run Command to reset access. For more information, see [Using EC2Rescue for Windows Server with Systems Manager Run Command](https://docs.aws.amazon.com/AWSEC2/latest/WindowsGuide/ec2rw-ssm.html) in the *Amazon EC2 User Guide*.

**To run the AWSSupport-ResetAccess Automation**

1. Open the AWS Systems Manager console at [https://console.aws.amazon.com/systems-manager/](https://console.aws.amazon.com/systems-manager/).

1. In the navigation pane, choose **Automation**.

1. Choose **Execute automation**.

1. In the **Automation document** section, choose **Owned by Amazon** from the list.

1. In the runbooks list, choose the button in the card for **AWSSupport-ResetAccess**, and then choose **Next**.

1. In the **Execute automation document** page, choose **Simple execution**.

1. In the **Document details** section, verify that **Document version** is set to the highest default version. For example, **\$1DEFAULT** or **3 (default)**.

1. In the **Input parameters** section, specify the following parameters: 

   1. For **InstanceID**, specify the ID of the unreachable instance. 

   1. For **SubnetId**, specify a subnet in an existing VPC in the same availability zone as the instance you specified. By default, Systems Manager creates a new VPC, but you can specify a subnet in an existing VPC if you want.
**Note**  
If you don't see the option to specify a subnet ID, verify that you are using the latest **Default** version of the runbook.

   1. For **EC2RescueInstanceType**, specify an instance type for the EC2Rescue instance. The default instance type is `t2.medium`.

   1. For **AssumeRole**, if you created roles for this Automation by using the CloudFormation procedure described earlier in this topic, then specify the AssumeRole ARN that you noted in the CloudFormation console.

1. (Optional) In the **Tags** area, apply one or more tag key name/value pairs to help identify the automation, for example `Key=Purpose,Value=ResetAccess`.

1. Choose **Execute**.

1. To monitor the automation progress, choose the running automation, and then choose the **Steps** tab. When the automation is finished, choose the **Descriptions** tab, and then choose **View output** to view the results. To view the output of individual steps, choose the **Steps** tab, and then choose **View Outputs** next to a step.

The runbook creates a backup AMI and a password-enabled AMI as part of the automation. All other resources created by the automation are automatically deleted, but these AMIs remain in your account. The AMIs are named using the following conventions:
+ Backup AMI: `AWSSupport-EC2Rescue:InstanceID`
+ Password-enabled AMI: AWSSupport-EC2Rescue: Password-enabled AMI from *Instance ID*

You can locate these AMIs by searching on the Automation execution ID.

For Linux, the new SSH private key for your instance is saved, encrypted, in Parameter Store. The parameter name is **/ec2rl/openssh/*instance ID*/key**.

# Passing data to Automation using input transformers
<a name="automation-tutorial-eventbridge-input-transformers"></a>

This AWS Systems Manager Automation tutorial shows how to use the input transformer feature of Amazon EventBridge to extract the `instance-id` of an Amazon Elastic Compute Cloud (Amazon EC2) instance from an instance state change event. Automation is a tool in AWS Systems Manager. We use the input transformer to pass that data to the `AWS-CreateImage` runbook target as the `InstanceId` input parameter. The rule is triggered when any instance changes to the `stopped` state.

For more information about working with input transformers, see [Tutorial: Use Input Transformer to Customize What is Passed to the Event Target](https://docs.aws.amazon.com/eventbridge/latest/userguide/eventbridge-input-transformer-tutorial.html) in the *Amazon EventBridge User Guide*.

**Before you begin**  
Verify that you added the required permissions and trust policy for EventBridge to your Systems Manager Automation service role. For more information, see [Overview of Managing Access Permissions to Your EventBridge Resources](https://docs.aws.amazon.com/eventbridge/latest/userguide/iam-access-control-identity-based-eventbridge.html) in the *Amazon EventBridge User Guide*.

**To use input transformers with Automation**

1. Open the Amazon EventBridge console at [https://console.aws.amazon.com/events/](https://console.aws.amazon.com/events/).

1. In the navigation pane, choose **Rules**.

1. Choose **Create rule**.

1. Enter a name and description for the rule.

   A rule can't have the same name as another rule in the same Region and on the same event bus.

1. For **Event bus**, choose the event bus that you want to associate with this rule. If you want this rule to respond to matching events that come from your own AWS account, select **default**. When an AWS service in your account emits an event, it always goes to your account’s default event bus.

1. For **Rule type**, choose **Rule with an event pattern**.

1. Choose **Next**.

1. For **Event source**, choose **AWS events or EventBridge partner events**.

1. In the **Event pattern** section, choose **Use pattern form**.

1. For **Event source**, choose **AWS services**.

1. For **AWS service**, choose **EC2**.

1. For **Event type**, choose **EC2 Instance State-change Notification**.

1. For **Event Type Specification 1**, select **Specific state(s)**, and then choose **stopped**.

1. For **Event Type Specification 2**, select **Any instance**, or select **Specific instance Id(s)** and enter the IDs of the instances to monitor.

1. Choose **Next**.

1. For **Target types**, choose **AWS service**.

1. For **Select a target**, choose **Systems Manager Automation**.

1. For **Document**, choose **AWS-CreateImage**.

1. In the **Configure automation parameter(s)** section, choose **Input Transformer**.

1. For **Input path**, enter **\$1"instance":"\$1.detail.instance-id"\$1**.

1. For **Template**, enter **\$1"InstanceId":[<instance>]\$1**.

1. For **Execution role**, choose **Use existing role** and choose your Automation service role.

1. Choose **Next**.

1. (Optional) Enter one or more tags for the rule. For more information, see [Tagging Your Amazon EventBridge Resources](https://docs.aws.amazon.com/eventbridge/latest/userguide/eventbridge-tagging.html) in the *Amazon EventBridge User Guide*.

1. Choose **Next**.

1. Review the details of the rule and choose **Create rule**.

# Learn about statuses returned by Systems Manager Automation
<a name="automation-statuses"></a>

AWS Systems Manager Automation reports detailed status information about the various statuses an automation action or step goes through when you run an automation and for the overall automation. Automation is a tool in AWS Systems Manager. You can monitor automation statuses using the following methods:
+ Monitor the **Execution status** in the Systems Manager Automation console.
+ Use your preferred command line tools. For the AWS Command Line Interface (AWS CLI), you can use [describe-automation-step-executions](https://docs.aws.amazon.com/cli/latest/reference/ssm/describe-automation-step-executions.html) or [get-automation-execution](https://docs.aws.amazon.com/cli/latest/reference/ssm/get-automation-execution.html). For the AWS Tools for Windows PowerShell, you can use [Get-SSMAutomationStepExecution](https://docs.aws.amazon.com/powershell/latest/reference/items/Get-SSMAutomationStepExecution.html) or [Get-SSMAutomationExecution](https://docs.aws.amazon.com/powershell/latest/reference/items/Get-SSMAutomationExecution.html).
+ Configure Amazon EventBridge to respond to action or automation status changes.

For more information about handling timeouts in an automation, see [Handling timeouts in runbooks](automation-handling-timeouts.md).

## About automation statuses
<a name="automation-statuses-about"></a>

Automation reports status details for individual automation actions in addition to the overall automation.

The overall automation status can be different than the status reported by an individual action or step as noted in the following tables.


**Detailed status for actions**  

| Status | Details | 
| --- | --- | 
| Pending | The step hasn't started running. If your automation uses conditional actions, steps remain in this state after an automation has completed if the condition wasn't met to run the step. Steps also remain in this state if the automation is canceled before the step runs. | 
| InProgress | The step is running. | 
| Waiting | The step is waiting for input. | 
| Success | The step completed successfully. This is a terminal state. | 
| TimedOut | A step or approval wasn't completed before the specified timeout period. This is a terminal state. | 
| Cancelling | The step is in the process of stopping after being canceled by a requester. | 
| Cancelled | The step was stopped by a requester before it completed. This is a terminal state. | 
| Failed |  The step didn't complete successfully. This is a terminal state.  | 
| Exited |  Only returned by the `aws:loop` action. The loop didn't fully complete. A step inside the loop moved to an outside step using the `nextStep`, `onCancel`, or `onFailure` properties.  | 


**Detailed status for an automation**  

| Status | Details | 
| --- | --- | 
| Pending | The automation hasn't started running. | 
| InProgress | The automation is running. | 
| Waiting | The automation is waiting for input. | 
| Success | The automation completed successfully. This is a terminal state. | 
| TimedOut | A step or approval wasn't completed before the specified timeout period. This is a terminal state. | 
| Cancelling | The automation is in the process of stopping after being canceled by a requester. | 
| Cancelled | The automation was stopped by a requester before it completed. This is a terminal state. | 
| Failed |  The automation didn't complete successfully. This is a terminal state.  | 

# Troubleshooting Systems Manager Automation
<a name="automation-troubleshooting"></a>

Use the following information to help you troubleshoot problems with AWS Systems Manager Automation, a tool in AWS Systems Manager. This topic includes specific tasks to resolve issues based on Automation error messages.

**Topics**
+ [Common Automation errors](#automation-trbl-common)
+ [Automation execution failed to start](#automation-trbl-access)
+ [Execution started, but status is failed](#automation-trbl-exstrt)
+ [Execution started, but timed out](#automation-trbl-to)

## Common Automation errors
<a name="automation-trbl-common"></a>

This section includes information about common Automation errors.

### VPC not defined 400
<a name="automation-trbl-common-vpc"></a>

By default, when Automation runs either the `AWS-UpdateLinuxAmi` runbook or the `AWS-UpdateWindowsAmi` runbook, the system creates a temporary instance in the default VPC (172.30.0.0/16). If you deleted the default VPC, you will receive the following error:

`VPC not defined 400`

To solve this problem, you must specify a value for the `SubnetId` input parameter.

## Automation execution failed to start
<a name="automation-trbl-access"></a>

An automation can fail with an access denied error or an invalid assume role error if you haven't properly configured AWS Identity and Access Management (IAM) roles, and policies for Automation.

### Access denied
<a name="automation-trbl-access-denied"></a>

The following examples describe situations when an automation failed to start with an access denied error.

**Access Denied to Systems Manager API**  
**Error message**: `User: user arn isn't authorized to perform: ssm:StartAutomationExecution on resource: document arn (Service: AWSSimpleSystemsManagement; Status Code: 400; Error Code: AccessDeniedException; Request ID: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx)`
+ Possible cause 1: The user attempting to start the automation doesn't have permission to invoke the `StartAutomationExecution` API. To resolve this issue, attach the required IAM policy to the user that was used to start the automation. 
+ Possible cause 2: The user attempting to start the automation has permission to invoke the `StartAutomationExecution` API but doesn't have permission to invoke the API by using the specific runbook. To resolve this issue, attach the required IAM policy to the user that was used to start the automation. 

**Access denied due to missing PassRole permissions**  
**Error message**: `User: user arn isn't authorized to perform: iam:PassRole on resource: automation assume role arn (Service: AWSSimpleSystemsManagement; Status Code: 400; Error Code: AccessDeniedException; Request ID: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx)`

The user attempting to start the automation doesn't have PassRole permission for the assume role. To resolve this issue, attach the iam:PassRole policy to the role of the user attempting to start the automation. For more information, see [Task 2: Attach the iam:PassRole policy to your Automation role](automation-setup-iam.md#attach-passrole-policy).

### Invalid assume role
<a name="automation-trbl-ar"></a>

When you run an Automation, an assume role is either provided in the runbook or passed as a parameter value for the runbook. Different types of errors can occur if the assume role isn't specified or configured properly.

**Malformed Assume Role**  
**Error message**: `The format of the supplied assume role ARN isn't valid.` The assume role is improperly formatted. To resolve this issue, verify that a valid assume role is specified in your runbook or as a runtime parameter when starting the automation.

**Assume role can't be assumed**  
**Error message**: `The defined assume role is unable to be assumed. (Service: AWSSimpleSystemsManagement; Status Code: 400; Error Code: InvalidAutomationExecutionParametersException; Request ID: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx)`
+ Possible cause 1: The assume role doesn't exist. To resolve this issue, create the role. For more information, see [Setting up Automation](automation-setup.md). Specific details for creating this role are described in the following topic, [Task 1: Create a service role for Automation](automation-setup-iam.md#create-service-role).
+ Possible cause 2: The assume role doesn't have a trust relationship with the Systems Manager service. To resolve this issue, create the trust relationship. For more information, see [I Can't Assume A Role](https://docs.aws.amazon.com/IAM/latest/UserGuide/troubleshoot_roles.html#troubleshoot_roles_cant-assume-role) in the *IAM User Guide*. 

## Execution started, but status is failed
<a name="automation-trbl-exstrt"></a>

### Action-specific failures
<a name="automation-trbl-actspec"></a>

Runbooks contain steps and steps run in order. Each step invokes one or more AWS service APIs. The APIs determine the inputs, behavior, and outputs of the step. There are multiple places where an error can cause a step to fail. Failure messages indicate when and where an error occurred.

To see a failure message in the Amazon Elastic Compute Cloud (Amazon EC2) console, choose the **View Outputs** link of the failed step. To see a failure message from the AWS CLI, call `get-automation-execution` and look for the `FailureMessage` attribute in a failed `StepExecution`.

In the following examples, a step associated with the `aws:runInstance` action failed. Each example explores a different type of error.

**Missing Image**  
**Error message**: `Automation Step Execution fails when it's launching the instance(s). Get Exception from RunInstances API of ec2 Service. Exception Message from RunInstances API: [The image id '[ami id]' doesn't exist (Service: AmazonEC2; Status Code: 400; Error Code: InvalidAMIID.NotFound; Request ID: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx)]. Please refer to Automation Service Troubleshooting Guide for more diagnosis details.`

The `aws:runInstances` action received input for an `ImageId` that doesn't exist. To resolve this problem, update the runbook or parameter values with the correct AMI ID.

**Assume role policy lacks sufficient permissions**  
**Error message**: `Automation Step Execution fails when it's launching the instance(s). Get Exception from RunInstances API of ec2 Service. Exception Message from RunInstances API: [You aren't authorized to perform this operation. Encoded authorization failure message: xxxxxxx (Service: AmazonEC2; Status Code: 403; Error Code: UnauthorizedOperation; Request ID: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx)]. Please refer to Automation Service Troubleshooting Guide for more diagnosis details.`

The assume role doesn't have sufficient permission to invoke the `RunInstances` API on EC2 instances. To resolve this problem, attach an IAM policy to the assume role that has permission to invoke the `RunInstances` API. For more information, see the [Create the service roles for Automation using the console](automation-setup-iam.md).

**Unexpected State**  
**Error message**: `Step fails when it's verifying launched instance(s) are ready to be used. Instance i-xxxxxxxxx entered unexpected state: shutting-down. Please refer to Automation Service Troubleshooting Guide for more diagnosis details.`
+ Possible cause 1: There is a problem with the instance or the Amazon EC2 service. To resolve this problem, login to the instance or review the instance system log to understand why the instance started shutting down.
+ Possible cause 2: The user data script specified for the `aws:runInstances` action has a problem or incorrect syntax. Verify the syntax of the user data script. Also, verify that the user data scripts doesn't shut down the instance, or invoke other scripts that shut down the instance.

**Action-Specific Failures Reference**  
When a step fails, the failure message might indicate which service was being invoked when the failure occurred. The following table lists the services invoked by each action. The table also provides links to information about each service.


****  

| Action | AWS services invoked by this action | For information about this service | Troubleshooting content | 
| --- | --- | --- | --- | 
|  `aws:runInstances`  |  Amazon EC2  |  [ Amazon EC2 User Guide](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/)  |  [Troubleshooting EC2 Instances](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-instance-troubleshoot.html)  | 
|  `aws:changeInstanceState`  |  Amazon EC2  |  [Amazon EC2 User Guide](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/)  |  [Troubleshooting EC2 instances](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-instance-troubleshoot.html)  | 
|  `aws:runCommand`  |  Systems Manager  |   [AWS Systems Manager Run Command](run-command.md)  |   [Troubleshooting Systems Manager Run Command](troubleshooting-remote-commands.md)  | 
|  `aws:createImage`  |  Amazon EC2  |  [https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/AMIs.html](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/AMIs.html)  |  | 
|  `aws:createStack`  |  CloudFormation  |  [AWS CloudFormation User Guide](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/Welcome.html)  |  [Troubleshooting CloudFormation](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/troubleshooting.html)  | 
|  `aws:deleteStack`  |  CloudFormation  |  [AWS CloudFormation User Guide](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/Welcome.html)  |  [Troubleshooting CloudFormation](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/troubleshooting.html)  | 
|  `aws:deleteImage`  |  Amazon EC2  |  [Amazon Machines Images](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/AMIs.html)  |  | 
|  `aws:copyImage`  |  Amazon EC2  |  [https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/AMIs.html](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/AMIs.html)  |  | 
|  `aws:createTag`  |  Amazon EC2, Systems Manager  |  [EC2 Resource and Tags](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/EC2_Resources.html)  |  | 
|  `aws:invokeLambdaFunction`  |  AWS Lambda  |  [AWS Lambda Developer Guide](https://docs.aws.amazon.com/lambda/latest/dg/)  |  [Troubleshooting Lambda](https://docs.aws.amazon.com/lambda/latest/dg/monitoring-functions.html)  | 

### Automation service internal error
<a name="automation-trbl-err"></a>

**Error message**: `Internal Server Error. Please refer to Automation Service Troubleshooting Guide for more diagnosis details.`

A problem with the Automation service is preventing the specified runbook from running correctly. To resolve this issue, contact AWS Support. Provide the execution ID and customer ID, if available.

## Execution started, but timed out
<a name="automation-trbl-to"></a>

**Error message**: `Step timed out while step is verifying launched instance(s) are ready to be used. Please refer to Automation Service Troubleshooting Guide for more diagnosis details.`

A step in the `aws:runInstances` action timed out. This can happen if the step action takes longer to run than the value specified for `timeoutSeconds` in the step. To resolve this issue, specify a longer value for the `timeoutSeconds` parameter in the `aws:runInstances` action. If that doesn't solve the problem, investigate why the step takes longer to run than expected

# AWS Systems Manager Change Calendar
<a name="systems-manager-change-calendar"></a>

Change Calendar, a tool in AWS Systems Manager, allows you to set up date and time ranges when actions you specify (for example, in [Systems Manager Automation](systems-manager-automation.md) runbooks) might or might not be performed in your AWS account. In Change Calendar, these ranges are called *events*. When you create a Change Calendar entry, you're creating a [Systems Manager document](documents.md) of the type `ChangeCalendar`. In Change Calendar, the document stores [iCalendar 2.0](https://icalendar.org/) data in plaintext format. Events that you add to the Change Calendar entry become part of the document. To get started with Change Calendar, open the [Systems Manager console](https://console.aws.amazon.com//systems-manager/change-calendar). In the navigation pane, choose **Change Calendar**.

You can create a calendar and its events in the Systems Manager console. You can also import an iCalendar (`.ics`) file that you have exported from a supported third-party calendar provider to add its events to your calendar. Supported providers include Google Calendar, Microsoft Outlook, and iCloud Calendar.

A Change Calendar entry can be one of two types:

**`DEFAULT_OPEN`**, or Open by default  
All actions can run by default, except during calendar events. During events, the state of a `DEFAULT_OPEN` calendar is `CLOSED` and events are blocked from running.

**`DEFAULT_CLOSED`**, or Closed by default  
All actions are blocked by default, except during calendar events. During events, the state of a `DEFAULT_CLOSED` calendar is `OPEN` and actions are permitted to run.

You can choose to have all scheduled Automation workflows, maintenance windows, and State Manager associations added automatically to a calendar. You can also remove any of those individual types from the calendar display. 

## Who should use Change Calendar?
<a name="systems-manager-change-calendar-who"></a>

**Change Manager availability change**  
AWS Systems Manager Change Manager will no longer be open to new customers starting November 7, 2025. If you would like to use Change Manager, sign up prior to that date. Existing customers can continue to use the service as normal. For more information, see [AWS Systems Manager Change Manager availability change](https://docs.aws.amazon.com/systems-manager/latest/userguide/change-manager-availability-change.html). 
+ AWS customers who perform the following action types:
  + Create or run Automation runbooks.
  + Create change requests in Change Manager.
  + Run maintenance windows.
  + Create associations in State Manager.

  Automation, Change Manager, Maintenance Windows, and State Manager are all tools AWS Systems Manager. By integrating these tools with Change Calendar, you can allow or block these action types depending on the current state of the change calendar you associate with each one.
+ Administrators who are responsible for keeping the configurations of Systems Manager managed nodes consistent, stable, and functional.

## Benefits of Change Calendar
<a name="systems-manager-change-calendar-benefits"></a>

The following are some benefits of Change Calendar.
+ **Review changes before they're applied**

  A Change Calendar entry can help ensure that potentially destructive changes to your environment are reviewed before they're applied.
+ **Apply changes only during appropriate times**

  Change Calendar entries help keep your environment stable during event times. For example, you can create a Change Calendar entry to block changes when you expect high demand on your resources, such as during a conference or public marketing promotion. A calendar entry can also block changes when you expect limited administrator support, such as during vacations or holidays. You can use a calendar entry to allow changes except for certain times of the day or week when there is limited administrator support to troubleshoot failed actions or deployments.
+ **Get the current or upcoming state of the calendar**

  You can run the Systems Manager `GetCalendarState` API operation to show you the current state of the calendar, the state at a specified time, or the next time that the calendar state is scheduled to change.
**Note**  
The `GetCalendarState` API has a quota of 10 requests per second. For more information about Systems Manager quotas, see [Systems Manager service quotas](https://docs.aws.amazon.com/general/latest/gr/ssm.html#limits_ssm) in the *Amazon Web Services General Reference*.
+ 

**EventBridge support**  
This Systems Manager tool is supported as an *event* type in Amazon EventBridge rules. For information, see [Monitoring Systems Manager events with Amazon EventBridge](monitoring-eventbridge-events.md) and [Reference: Amazon EventBridge event patterns and types for Systems Manager](reference-eventbridge-events.md).

**Topics**
+ [Who should use Change Calendar?](#systems-manager-change-calendar-who)
+ [Benefits of Change Calendar](#systems-manager-change-calendar-benefits)
+ [Setting up Change Calendar](systems-manager-change-calendar-prereqs.md)
+ [Working with Change Calendar](systems-manager-change-calendar-working.md)
+ [Adding Change Calendar dependencies to Automation runbooks](systems-manager-change-calendar-automations.md)
+ [Troubleshooting Change Calendar](change-calendar-troubleshooting.md)

# Setting up Change Calendar
<a name="systems-manager-change-calendar-prereqs"></a>

Complete the following before using Change Calendar, a tool in AWS Systems Manager.

## Install latest command line tools
<a name="change-calendar-prereqs-tools"></a>

Install the latest command line tools to get state information about calendars.


| Requirement | Description | 
| --- | --- | 
|  AWS CLI  |  (Optional) To use the AWS Command Line Interface (AWS CLI) to get state information about calendars, install the newest release of the AWS CLI on your local computer. For more information about how to install or upgrade the CLI, see [Installing, updating, and uninstalling the AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-install.html) in the *AWS Command Line Interface User Guide*.  | 
|  AWS Tools for PowerShell  |  (Optional) To use the Tools for PowerShell to get state information about calendars, install the newest release of Tools for PowerShell on your local computer. For more information about how to install or upgrade the Tools for PowerShell, see [Installing the AWS Tools for PowerShell](https://docs.aws.amazon.com/powershell/latest/userguide/pstools-getting-set-up.html) in the *AWS Tools for PowerShell User Guide*.  | 

## Set up permissions
<a name="change-calendar-prereqs-permissions"></a>

If your user, group, or role is assigned administrator permissions, then you have full access to Change Calendar. If you don't have administrator permissions, then an administrator must give you permission by either assigning the `AmazonSSMFullAccess` managed policy, or assigning a policy that provides the necessary permissions to your user, group, or role.

The following permissions are required to work with Change Calendar.

**Change Calendar entries**  
To create, update, or delete a Change Calendar entry, including adding and removing events from the entry, a policy attached to your user, group, or role must allow the following actions:  
+ `ssm:CreateDocument`
+ `ssm:DeleteDocument`
+ `ssm:DescribeDocument`
+ `ssm:DescribeDocumentPermission`
+ `ssm:GetCalendar`
+ `ssm:ListDocuments`
+ `ssm:ModifyDocumentPermission`
+ `ssm:PutCalendar`
+ `ssm:UpdateDocument`
+ `ssm:UpdateDocumentDefaultVersion`

**Calendar state**  
To get information about the current or upcoming state of the calendar, a policy attached to your user, group, or role must allow the following action:  
+ `ssm:GetCalendarState`

**Operational events**  
To view operational events, such as maintenance windows, associations, and planned automations, the policy attached to your user, group, or role must allow the following actions:  
+ `ssm:DescribeMaintenanceWindows`
+ `ssm:DescribeMaintenanceWindowExecution`
+ `ssm:DescribeAutomationExecutions`
+ `ssm:ListAssociations`

**Note**  
Change Calendar entries that are owned by (that is, created by) accounts other than yours are read-only, even if they're shared with your account. Maintenance windows, State Manager associations, and automations aren't shared.

# Working with Change Calendar
<a name="systems-manager-change-calendar-working"></a>

You can use the AWS Systems Manager console to add, manage, or delete entries in Change Calendar, a tool in AWS Systems Manager. You can also import events from supported third-party calendar providers by importing an iCalendar (`.ics`) file that you exported from the source calendar. And, you can use the `GetCalendarState` API operation or the `get-calendar-state` AWS Command Line Interface (AWS CLI) command to get information about the state of Change Calendar at a specific time.

**Topics**
+ [Creating a change calendar](change-calendar-create.md)
+ [Creating and managing events in Change Calendar](change-calendar-events.md)
+ [Importing and managing events from third-party calendars](third-party-events.md)
+ [Updating a change calendar](change-calendar-update.md)
+ [Sharing a change calendar](change-calendar-share.md)
+ [Deleting a change calendar](change-calendar-delete.md)
+ [Getting the state of a change calendar](change-calendar-getstate.md)

# Creating a change calendar
<a name="change-calendar-create"></a>

When you create an entry in Change Calendar, a tool in AWS Systems Manager, you're creating a Systems Manager document (SSM document) that uses the `text` format.

**To create a change calendar**

1. Open the AWS Systems Manager console at [https://console.aws.amazon.com/systems-manager/](https://console.aws.amazon.com/systems-manager/).

1. In the navigation pane, choose **Change Calendar**.

1. Choose **Create calendar**.

   -or-

   If the **Change Calendar** home page opens first, choose **Create change calendar**.

1. On the **Create calendar** page, in **Calendar details**, enter a name for your calendar entry. Calendar entry names can contain letters, numbers, periods, dashes, and underscores. The name should be specific enough to identify the purpose of the calendar entry at a glance. An example is **support-off-hours**. You can't update this name after you create the calendar entry.

1. (Optional) For **Description**, enter a description for your calendar entry.

1. (Optional) In the **Import calendar** area, choose **Choose file** to select an iCalendar (`.ics`) file that you have exported from a third-party calendar provider. Importing the file will add its events to your calendar.

   Supported providers include Google Calendar, Microsoft Outlook, and iCloud Calendar.

   For more information, see [Importing events from third-party calendar providers](change-calendar-import.md).

1. In **Calendar type**, choose one of the following.
   + **Open by default** - The calendar is open (Automation actions can run until an event starts), then closed for the duration of an associated event.
   + **Closed by default** - The calendar is closed (Automation actions can't run until an event starts) but open for the duration of an associated event.

1. (Optional) In **Change management events**, select **Add change management events to the calendar**. This selection displays all scheduled maintenance windows, State Manager associations, Automation workflows, and Change Manager change requests in your monthly calendar display.
**Tip**  
If later you want to permanently remove these events types from the calendar display, edit the calendar, clear this check box, and then choose **Save**.

1. Choose **Create calendar**.

   After the calendar entry is created, Systems Manager displays your calendar entry in the **Change Calendar** list. The columns show the calendar version and the calendar owner's AWS account number. Your calendar entry can't prevent or allow any actions until you have created or imported at least one event. For information about creating an event, see [Creating a Change Calendar event](change-calendar-create-event.md). For information about importing events, see [Importing events from third-party calendar providers](change-calendar-import.md).

# Creating and managing events in Change Calendar
<a name="change-calendar-events"></a>

After you create a calendar in AWS Systems Manager Change Calendar, you can create, update, and delete events that are included in your open or closed calendar. Change Calendar is a tool in AWS Systems Manager.

**Tip**  
As an alternative to creating events directly in the Systems Manager console, you can import an iCalendar (`.ics`) file from a supported third-party calendar application. For information, see [Importing and managing events from third-party calendars](third-party-events.md).

**Topics**
+ [Creating a Change Calendar event](change-calendar-create-event.md)
+ [Updating a Change Calendar event](change-calendar-update-event.md)
+ [Deleting a Change Calendar event](change-calendar-delete-event.md)

# Creating a Change Calendar event
<a name="change-calendar-create-event"></a>

When you add an event to an entry in Change Calendar, a tool in AWS Systems Manager, you're specifying a period of time during which the default action of the calendar entry is suspended. For example, if the calendar entry type is closed by default, the calendar is open to changes during events. (Alternatively, you can create an advisory event, which serves an informational role on the calendar only.)

Currently, you can only create a Change Calendar event by using the console. Events are added to the Change Calendar document that you create when you create a Change Calendar entry.

**To create a Change Calendar event**

1. Open the AWS Systems Manager console at [https://console.aws.amazon.com/systems-manager/](https://console.aws.amazon.com/systems-manager/).

1. In the navigation pane, choose **Change Calendar**.

1. In the list of calendars, choose the name of the calendar entry to which you want to add an event.

1. On the calendar entry's details page, choose **Create event**.

1. On the **Create scheduled event** page, in **Event details**, enter a display name for your event. Event names can contain letters, numbers, periods, dashes, and underscores. The name should be specific enough to identify the purpose of the event. An example is **nighttime-hours**.

1. For **Description**, enter a description for your event. For example, **The support team isn't available during these hours**.

1. (Optional) If you want this event to serve as a visual notification or reminder only, select the **Advisory** check box. Advisory events play no functional role on your calendar. They serve informational purposes only for those who view your calendar.

1. For **Event start date**, enter or choose a day in the format `MM/DD/YYYY` to start the event, and enter a time on the specified day in the format `hh:mm:ss` (hours, minutes, and seconds) to start the event.

1. For **Event end date**, enter or choose a day in the format `MM/DD/YYYY` to end the event, and enter a time on the specified day in the format `hh:mm:ss` (hours, minutes, and seconds) to end the event.

1. For **Schedule time zone**, choose a time zone that applies to the start and end times of the event. You can enter part of a city name or time zone difference from Greenwich Mean Time (GMT) to find a time zone faster. The default is Coordinated Universal Time (UTC).

1. (Optional) To create an event that recurs daily, weekly, or monthly, turn on **Recurrence**, and then specify the frequency and optional end date for the recurrence.

1. Choose **Create scheduled event**. The new event is added to your calendar entry, and is displayed on the **Events** tab of the calendar entry's details page.

# Updating a Change Calendar event
<a name="change-calendar-update-event"></a>

Use the following procedure to update a Change Calendar event in the AWS Systems Manager console. Change Calendar is a tool in AWS Systems Manager.

**To update a Change Calendar event**

1. Open the AWS Systems Manager console at [https://console.aws.amazon.com/systems-manager/](https://console.aws.amazon.com/systems-manager/).

1. In the navigation pane, choose **Change Calendar**.

1. In the list of calendars, choose the name of the calendar entry for which you want to edit an event.

1. On the calendar entry's details page, choose **Events**.

1. In the calendar page, choose the event that you want to edit.
**Tip**  
Use the buttons on the upper left to move back or forward one year, or back or forward one month. Change the time zone, if required, by choosing the correct time zone from the list on the upper right.

1. In **Event details**, choose **Edit**.

   To change the event name and description, add to or replace the current text values.

1. To change the **Event start date** value, choose the current start date, and then choose a new date from the calendar. To change the start time, choose the current start time, and then choose a new time from the list.

1. To change the **Event end date** value, choose the current date, and then choose a new end date from the calendar. To change the end time, choose the current end time, and then choose a new time from the list.

1. To change the **Schedule time zone** value, choose a time zone to apply to the start and end times of the event. You can enter part of a city name or time zone difference from Greenwich Mean Time (GMT) to find a time zone faster. The default is Coordinated Universal Time (UTC).

1. (Optional) If you want this event to serve as a visual notification or reminder only, select the **Advisory** check box. Advisory events play no functional role on your calendar. They serve informational purposes only for those who view your calendar.

1. Choose **Save**. Your changes are displayed on the **Events** tab of the calendar entry's details page. Choose the event that you updated to view your changes.

# Deleting a Change Calendar event
<a name="change-calendar-delete-event"></a>

You can delete one event at a time in Change Calendar, a tool in AWS Systems Manager, by using the AWS Management Console. 

**Tip**  
If you selected **Add change management events to the calendar** when you created the calendar, you can do the following:  
To *temporarily* hide a change management event type from the calendar display, choose the **X** for the type at the top of the monthly preview.
To *permanently* remove these types from the calendar display, edit the calendar, clear the **Add change management events to the calendar** check box, and then choose **Save**. Removing the types from the calendar display doesn't delete them from your account.

**To delete a Change Calendar event**

1. Open the AWS Systems Manager console at [https://console.aws.amazon.com/systems-manager/](https://console.aws.amazon.com/systems-manager/).

1. In the navigation pane, choose **Change Calendar**.

1. In the list of calendars, choose the name of the calendar entry from which you want to delete an event.

1. On the calendar entry's details page, choose **Events**.

1. In the calendar page, choose the event that you want to delete.
**Tip**  
Use the buttons on the upper left to move the calendar back or forward one year, or back or forward one month. Change the time zone, if required, by choosing the correct time zone from the list on the upper right.

1. On the **Event details** page, choose **Delete**. When you're prompted to confirm that you want to delete the event, choose **Confirm**.

# Importing and managing events from third-party calendars
<a name="third-party-events"></a>

As an alternative to creating events directly in the AWS Systems Manager console, you can import an iCalendar (`.ics`) file from a supported third-party calendar application. Your calendar can include both imported events and events that you create in Change Calendar, which is a tool in AWS Systems Manager.

**Before you begin**  
Before you attempt to import a calendar file, review the following requirements and constraints:

Calendar file format  
Only valid iCalendar files (`.ics`) are supported.

Supported calendar providers  
Only `.ics` files exported from the following third-party calendar providers are supported:  
+ Google Calendar ([Export instructions](https://support.google.com/calendar/answer/37111))
+ Microsoft Outlook ([Export instructions](https://support.microsoft.com/en-us/office/export-an-outlook-calendar-to-google-calendar-662fa3bb-0794-4b18-add8-9968b665f4e6))
+ iCloud Calendar ([Export instructions](https://support.apple.com/guide/calendar/import-or-export-calendars-icl1023/mac))

File size  
You can import any number of valid `.ics` files. However, the total size of all imported files for each calendar can't exceed 64KB.  
To minimize the size of the `.ics` file, ensure that you are exporting only basic details about your calendar entries. If necessary, reduce the length of the time period that you are exporting.

Time zone  
In addition to a calendar name, a calendar provider, and at least one event, your exported `.ics` file should also indicate the time zone for the calendar. If it does not, or there is a problem identifying the time zone, you will be prompted to specify one after you import the file.

Recurring event limitation  
Your exported `.ics` file can include recurring events. However, if one or more occurrences of a recurring event had been deleted in the source calendar, the import fails.

**Topics**
+ [Importing events from third-party calendar providers](change-calendar-import.md)
+ [Updating all events from a third-party calendar provider](change-calendar-import-add-remove.md)
+ [Deleting all events imported from a third-party calendar](change-calendar-delete-ics.md)

# Importing events from third-party calendar providers
<a name="change-calendar-import"></a>

Use the following procedure to import an iCalendar (`.ics`) file from a supported third-party calendar application. The events contained in the file are incorporated into the rules for your open or closed calendar. You can import a file into a new calendar you are creating with Change Calendar (a tool in AWS Systems Manager) or into an existing calendar.

After you import the `.ics` file, you can remove individual events from it using the Change Calendar interface. For information, see [Deleting a Change Calendar event](change-calendar-delete-event.md). You can also delete all events from the source calendar by deleting the `.ics` file. For information, see [Deleting all events imported from a third-party calendar](change-calendar-delete-ics.md).

**To import events from third-party calendar providers**

1. Open the AWS Systems Manager console at [https://console.aws.amazon.com/systems-manager/](https://console.aws.amazon.com/systems-manager/).

1. In the navigation pane, choose **Change Calendar**.

1. To start with a new calendar, choose **Create calendar**. In the **Import calendar** area, choose **Choose file**. For information about other steps to create a new calendar, see [Creating a change calendar](change-calendar-create.md).

   -or-

   To import third-party events into an existing calendar, choose the name of an existing calendar to open it.

1. Choose **Actions, Edit**, and then in the **Import calendar** area, choose **Choose file**.

1. Navigate to and select the exported `.ics` file on your local computer.

1. If prompted, for **Select a time zone**, select which time zone applies to the calendar.

1. Choose **Save**.

# Updating all events from a third-party calendar provider
<a name="change-calendar-import-add-remove"></a>

If several events are added to or removed from your source calendar after you have imported its iCalendar `.ics` file, you can reflect those changes in Change Calendar. First, re-export the source calendar, and then import the new file into Change Calendar, which is a tool in AWS Systems Manager. Events in your change calendar will be updated to reflect the contents of the newer file.

**To update all events from a third-party calendar provider**

1. In your third-party calendar, add or remove events as you want them to be reflected in Change Calendar, and then re-export the calendar to a new `.ics` file.

1. Open the AWS Systems Manager console at [https://console.aws.amazon.com/systems-manager/](https://console.aws.amazon.com/systems-manager/).

1. In the navigation pane, choose **Change Calendar**.

1. From the list of calendars, choose the calendar name from the list.

1. Choose **Choose file**, and then navigate to and select the replacement `.ics` file.

1. In response to the notification about overwriting the existing file, choose **Confirm**.

# Deleting all events imported from a third-party calendar
<a name="change-calendar-delete-ics"></a>

If you no longer want any of the events that you imported from a third-party provider included in your calendar, you can delete the imported iCalendar `.ics` file.

**To delete all events imported from a third-party calendar**

1. Open the AWS Systems Manager console at [https://console.aws.amazon.com/systems-manager/](https://console.aws.amazon.com/systems-manager/).

1. In the navigation pane, choose **Change Calendar**.

1. From the list of calendars, choose the calendar name from the list.

1. In the **Import calendar** area, under **My imported calendars**, locate the name of the imported calendar, and then choose the **X** in its card.

1. Choose **Save**.

# Updating a change calendar
<a name="change-calendar-update"></a>

You can update the description of a change calendar, but not its name. Although you can change the default state of a calendar, be aware that this reverses the behavior of change actions during events that are associated with the calendar. For example, if you change the state of a calendar from **Open by default** to **Closed by default**, unwanted changes might be made during event periods when the users who created the associated events aren't expecting changes.

When you update a change calendar, you're editing the Change Calendar document that you created when you created the entry. Change Calendar is a tool in AWS Systems Manager.

**To update a change calendar**

1. Open the AWS Systems Manager console at [https://console.aws.amazon.com/systems-manager/](https://console.aws.amazon.com/systems-manager/).

1. In the navigation pane, choose **Change Calendar**.

1. In the list of calendars, choose the name of the calendar that you want to update.

1. On the calendar's details page, choose **Actions, Edit**.

1. In **Description**, you can change the description text. You can't edit the name of a change calendar.

1. To change the calendar state, in **Calendar type**, choose a different value. Be aware that this reverses the behavior of change actions during events that are associated with the calendar. Before you change the calendar type, you should verify with other Change Calendar users that changing the calendar type doesn't allow unwanted changes during events that they have created.
   + **Open by default** – The calendar is open (Automation actions can run until an event starts) then closed for the duration of an associated event.
   + **Closed by default** – The calendar is closed (Automation actions can't run until an event starts) but open for the duration of an associated event.

1. Choose **Save**.

   Your calendar can't prevent or allow any actions until you add at least one event. For information about how to add an event, see [Creating a Change Calendar event](change-calendar-create-event.md).

# Sharing a change calendar
<a name="change-calendar-share"></a>

You can share a calendar in Change Calendar, a tool in AWS Systems Manager, with other AWS accounts by using the AWS Systems Manager console. When you share a calendar, the calendar is read-only to users in the shared account. Maintenance windows, State Manager associations, and automations aren't shared.

**To share a change calendar**

1. Open the AWS Systems Manager console at [https://console.aws.amazon.com/systems-manager/](https://console.aws.amazon.com/systems-manager/).

1. In the navigation pane, choose **Change Calendar**.

1. In the list of calendars, choose the name of the calendar that you want to share.

1. On the calendar's details page, choose the **Sharing** tab.

1. Choose **Actions, Share**.

1. In **Share calendar**, for **Account ID**, enter the ID number of a valid AWS account, and then choose **Share**.

   Users of the shared account can read the change calendar, but they can't make changes.

# Deleting a change calendar
<a name="change-calendar-delete"></a>

You can delete a calendar in Change Calendar, a tool in AWS Systems Manager, by using either the Systems Manager console or the AWS Command Line Interface (AWS CLI). Deleting a change calendar deletes all associated events.

**To delete a change calendar**

1. Open the AWS Systems Manager console at [https://console.aws.amazon.com/systems-manager/](https://console.aws.amazon.com/systems-manager/).

1. In the navigation pane, choose **Change Calendar**.

1. In the list of calendars, choose the name of the calendar that you want to delete.

1. On the calendar's details page, choose **Actions, Delete**. When you're prompted to confirm that you want to delete the calendar, choose **Delete**.

# Getting the state of a change calendar
<a name="change-calendar-getstate"></a>

You can get the overall state of a calendar or the state of a calendar at a specific time in Change Calendar, a tool in AWS Systems Manager. You can also show the next time that the calendar state changes from `OPEN` to `CLOSED`, or the reverse.

**Note**  
For information about integrating Change Calendar with Amazon EventBridge for automated monitoring of calendar state changes, see [Change Calendar integration with Amazon EventBridge](monitoring-systems-manager-event-examples.md#change-calendar-eventbridge-integration). EventBridge integration provides event-driven notifications when calendar states transition, complementing the polling-based approach of the `GetCalendarState` API action.

You can do this task only by using the `GetCalendarState` API operation. The procedure in this section uses the AWS Command Line Interface (AWS CLI).

**To get the state of a change calendar**
+ Run the following command to show the state of one or more calendars at a specific time. The `--calendar-names` parameter is required, but `--at-time` is optional. Replace each *example resource placeholder* with your own information.

------
#### [ Linux & macOS ]

  ```
  aws ssm get-calendar-state \
      --calendar-names "Calendar_name_or_document_ARN_1" "Calendar_name_or_document_ARN_2" \
      --at-time "ISO_8601_time_format"
  ```

  The following is an example.

  ```
  aws ssm get-calendar-state \
      --calendar-names "arn:aws:ssm:us-east-2:123456789012:document/MyChangeCalendarDocument" "arn:aws:ssm:us-east-2:123456789012:document/SupportOffHours" \
      --at-time "2020-07-30T11:05:14-0700"
  ```

------
#### [ Windows ]

  ```
  aws ssm get-calendar-state ^
      --calendar-names "Calendar_name_or_document_ARN_1" "Calendar_name_or_document_ARN_2" ^
      --at-time "ISO_8601_time_format"
  ```

  The following is an example.

  ```
  aws ssm get-calendar-state ^
      --calendar-names "arn:aws:ssm:us-east-2:123456789012:document/MyChangeCalendarDocument" "arn:aws:ssm:us-east-2:123456789012:document/SupportOffHours" ^
      --at-time "2020-07-30T11:05:14-0700"
  ```

------

  The command returns information like the following.

  ```
  {
      "State": "OPEN",
      "AtTime": "2020-07-30T16:18:18Z",
      "NextTransitionTime": "2020-07-31T00:00:00Z"
  }
  ```

  The results show the state of the calendar (whether the calendar is of type `DEFAULT_OPEN` or `DEFAULT_CLOSED`) for the specified calendar entries that are owned by or shared with your account, at the time specified as the value of `--at-time`, and the time of the next transition. If you don't add the `--at-time` parameter, the current time is used.
**Note**  
If you specify more than one calendar in a request, the command returns the status of `OPEN` only if all calendars in the request are open. If one or more calendars in the request are closed, the status returned is `CLOSED`.

# Adding Change Calendar dependencies to Automation runbooks
<a name="systems-manager-change-calendar-automations"></a>

To make Automation actions adhere to Change Calendar, a tool in AWS Systems Manager, add a step in an Automation runbook that uses the [`aws:assertAwsResourceProperty`](automation-action-assertAwsResourceProperty.md) action. Configure the action to run `GetCalendarState` to verify that a specified calendar entry is in the state that you want (`OPEN` or `CLOSED`). The Automation runbook is only allowed to continue to the next step if the calendar state is `OPEN`. The following is a YAML-based sample excerpt of an Automation runbook that can't advance to the next step, `LaunchInstance`, unless the calendar state matches `OPEN`, the state specified in `DesiredValues`.

The following is an example.

```
mainSteps:
  - name: MyCheckCalendarStateStep
    action: 'aws:assertAwsResourceProperty'
    inputs:
      Service: ssm
      Api: GetCalendarState
      CalendarNames: ["arn:aws:ssm:us-east-2:123456789012:document/SaleDays"]
      PropertySelector: '$.State'
      DesiredValues:
      - OPEN
    description: "Use GetCalendarState to determine whether a calendar is open or closed."
    nextStep: LaunchInstance
  - name: LaunchInstance
    action: 'aws:executeScript'
    inputs:
      Runtime: python3.11 
...
```

# Troubleshooting Change Calendar
<a name="change-calendar-troubleshooting"></a>

Use the following information to help you troubleshoot problems with Change Calendar, a tool in AWS Systems Manager.

**Topics**
+ ['Calendar import failed' error](#change-manager-troubleshooting-1)

## 'Calendar import failed' error
<a name="change-manager-troubleshooting-1"></a>

**Problem**: When importing an iCalendar (`.ics`) file, the system reports that the calendar import failed.
+ **Solution 1** – Ensure that you are importing a file that was exported from a supported third-party calendar provider, which include the following:
  + Google Calendar ([Export instructions](https://support.google.com/calendar/answer/37111))
  + Microsoft Outlook ([Export instructions](https://support.microsoft.com/en-us/office/export-an-outlook-calendar-to-google-calendar-662fa3bb-0794-4b18-add8-9968b665f4e6))
  + iCloud Calendar ([Export instructions](https://support.apple.com/guide/calendar/import-or-export-calendars-icl1023/mac))
+ **Solution 2** – If your source calendar contains any recurring events, ensure that no individual occurrences of the event have been canceled or deleted. Currently, Change Calendar doesn't support importing recurring events with individual cancellations. To resolve the issue, remove the recurring event from the source calendar, re-export the calendar and re-import it into Change Calendar, and then add the recurring event using the Change Calendar interface. For information, see [Creating a Change Calendar event](change-calendar-create-event.md).
+ **Solution 3** – Ensure that your source calendar contains at least one event. Uploads of `.ics` files that don't contain events don't succeed.
+ **Solution 4** – If the system reports that the import failed because the `.ics` is too large, ensure that you are exporting only basic details about your calendar entries. If necessary, reduce the length of the time period that you export.
+ **Solution 5** – If Change Calendar is unable to determine the time zone of your exported calendar when you attempt to import it from the **Events** tab, you might receive this message: "Calendar import failed. Change Calendar couldn't locate a valid time zone. You can import the calendar from the Edit menu." In this case, choose **Actions, Edit**, and then try importing the file from the **Edit calendar** page.
+ **Solution 6** – Don't edit the `.ics` file before import. Attempting to modify the contents of the file can corrupt the calendar data. If you have modified the file before attempting the import, export the calendar from the source calendar again, and then re-attempt the upload.

# AWS Systems Manager Change Manager
<a name="change-manager"></a>

**Change Manager availability change**  
AWS Systems Manager Change Manager will no longer be open to new customers starting November 7, 2025. If you would like to use Change Manager, sign up prior to that date. Existing customers can continue to use the service as normal. For more information, see [AWS Systems Manager Change Manager availability change](https://docs.aws.amazon.com/systems-manager/latest/userguide/change-manager-availability-change.html). 

Change Manager, a tool in AWS Systems Manager, is an enterprise change management framework for requesting, approving, implementing, and reporting on operational changes to your application configuration and infrastructure. From a single *delegated administrator account*, if you use AWS Organizations, you can manage changes across multiple AWS accounts and across AWS Regions. Alternatively, using a *local account*, you can manage changes for a single AWS account. Use Change Manager for managing changes to both AWS resources and on-premises resources. To get started with Change Manager, open the [Systems Manager console](https://console.aws.amazon.com//systems-manager/change-manager). In the navigation pane, choose **Change Manager**.

With Change Manager, you can use pre-approved *change templates* to help automate change processes for your resources and help avoid unintentional results when making operational changes. Each change template specifies the following:
+ One or more Automation runbooks for a user to choose from when creating a change request. The changes that are made to your resources are defined in Automation runbooks. You can include custom runbooks or [AWS managed runbooks](automation-documents-reference.md) in the change templates you create. When a user creates a change request, they can choose which one of the available runbooks to include in the request. Additionally, you can create change templates that let the user making the request specify any runbook in the change request.
+ The users in the account who must review change requests that were made using that change template.
+ The Amazon Simple Notification Service (Amazon SNS) topic that is used to notify assigned approvers that a change request is ready for review.
+ The Amazon CloudWatch alarm that is used to monitor the runbook workflow.
+ The Amazon SNS topic that is used to send notifications about status changes for change requests that are created using the change template.
+ The tags to apply to the change template for use in categorizing and filtering your change templates.
+ Whether change requests created from the change template can be run without an approval step (auto-approved requests).

Through its integration with Change Calendar, which is another tool in Systems Manager, Change Manager also helps you safely implement changes while avoiding schedule conflicts with important business events. Change Manager integration with AWS Organizations and AWS IAM Identity Center helps you manage changes across your organization from a single account using your existing identity management system. You can monitor change progress from Change Manager and audit operational changes across your organization, providing improved visibility and accountability.

Change Manager complements the safety controls of your [continuous integration](https://aws.amazon.com/devops/continuous-integration) (CI) practices and [continuous delivery](https://aws.amazon.com/devops/continuous-delivery) (CD) methodology. Change Manager isn't intended for changes made as part of an automated release process, such as a CI/CD pipeline, unless there is an exception or approval required.

## How Change Manager works
<a name="how-change-manager-works"></a>

When the need for a standard or emergency operational change is identified, someone in the organization creates a change request that is based on one of the change templates created for use in your organization or account.

If the requested change requires manual approvals, Change Manager notifies the designated approvers through an Amazon SNS notification that a change request is ready for their review. You can designate approvers for change requests in the change template, or let users designate approvers in the change request itself. You can assign different reviewers to different templates. For example, assign one user, user group, or AWS Identity and Access Management (IAM) role who must approve requests for changes to managed nodes, and another user, group, or IAM role for database changes. If the change template allows auto-approvals, and a requester's user policy doesn't prohibit it, the user can also choose to run the Automation runbook for their request without a review step (with the exception of change freeze events).

For each change template, you can add up to five levels of approvers. For example, you might require technical reviewers to approve a change request created from a change template first, and then require a second level of approvals from one or more managers.

Change Manager is integrated with [AWS Systems Manager Change Calendar](systems-manager-change-calendar.md). When a requested change is approved, the system first determines whether the request conflicts with other scheduled business activities. If a conflict is detected, Change Manager can block the change or require additional approvals before starting the runbook workflow. For example, you might allow changes only during business hours to ensure that teams are available to manage any unexpected problems. For any changes requested to run outside those hours, you can require higher-level management approval in the form of *change freeze approvers*. For emergency changes, Change Manager can skip the step of checking Change Calendar for conflicts or blocking events after a change request is approved.

When it's time to implement an approved change, Change Manager runs the Automation runbook that is specified in the associated change request. Only the operations defined in approved change requests are permitted when runbook workflows run. This approach helps you avoid unintentional results while changes are being implemented.

In addition to restricting the changes that can be made when a runbook workflow runs, Change Manager also helps you control concurrency and error thresholds. You choose how many resources a runbook workflow can run on at once, how many accounts the change can run in at once, and how many failures to allow before the process is stopped and (if the runbook includes a rollback script) rolled back. You can also monitor the progress of changes being made by using CloudWatch alarms.

After a runbook workflow has completed, you can review details about the changes made. These details include the reason for a change request, which change template was used, who requested and approved the changes, and how the changes were implemented.

**More info**  
[Introducing AWS Systems Manager Change Manager](https://aws.amazon.com/blogs/aws/introducing-systems-manager-change-manager/) on the *AWS News Blog*

## How can Change Manager benefit my operations?
<a name="change-manager-benefits"></a>

Benefits of Change Manager include the following:
+ **Reduce risk of service disruption and downtime**

  Change Manager can make operational changes safer by ensuring that only approved changes are implemented when a runbook workflow runs. You can block unplanned and unreviewed changes. Change Manager helps you avoid the types of unintentional results caused by human error that require costly hours of research and backtracking.
+ **Get detailed auditing and reporting on change histories**

  Change Manager provides accountability with a consistent way to report and audit changes made across your organization, the intent of the changes, and details about who approved and implemented them.
+ **Avoid schedule conflicts or violations**

  Change Manager can detect schedule conflicts such as holiday events or new product launches, based on the active change calendar for your organization. You can allow runbook workflows to run only during business hours, or allow them only with additional approvals.
+ **Adapt change requirements to your changing business**

  During different business periods, you can implement different change management requirements. For example, during end-of-month reporting, tax season, or other critical business periods, you can block changes or require director-level approval for changes that could introduce unnecessary operational risks.
+ **Centrally manage changes across accounts**

  Through its integration with Organizations, Change Manager makes it possible for you to manage changes throughout all of your organizational units (OUs) from a single delegated administrator account. You can turn on Change Manager for use with your entire organization or with only some of your OUs.

## Who should use Change Manager?
<a name="change-manager-who"></a>

Change Manager is appropriate for the following AWS customers and organizations:
+ Any AWS customer who wants to improve the safety and governance of operational changes made to their cloud or on-premises environments.
+ Organizations that want to increase collaboration and visibility across teams, improve application availability by avoiding downtime, and reduce the risk associated with manual and repetitive tasks.
+ Organizations that must comply with best practices for change management. 
+ Customers who need a fully auditable history of changes made to their application configuration and infrastructure.

## What are the main features of Change Manager?
<a name="change-manager-features"></a>

Primary features of Change Manager include the following:
+ **Integrated support for change management best practices**

  With Change Manager, you can apply select change management best practices to your operations. You can choose to turn on the following options:
  + Check Change Calendar to see if events are currently restricted so changes are made only during open calendar periods.
  + Allow changes during restricted events with extra approvals from change freeze approvers.
  + Require CloudWatch alarms to be specified for all change templates.
  + Require all change templates created in your account to be reviewed and approved before they can be used to create change requests.
+ **Different approval paths for closed calendar periods and emergency change requests**

  You can allow an option to check Change Calendar for restricted events and block approved change requests until the event is complete. However, you can also designate a second group of approvers, change freeze approvers, who can permit the change to be made even if the calendar is closed. You can also create emergency change templates. Change requests created from an emergency change template still require regular approvals but aren't subject to calendar restrictions and don't require change freeze approvals.
+ **Control how and when runbook workflows are started**

  Runbook workflows can be started according to a schedule, or as soon as approvals are complete (subject to calendar restriction rules).
+ **Built-in notification support**

  Specify who in your organization should review and approve change templates and change requests. Assign an Amazon SNS topic to a change template to send notifications to the topic's subscribers about status changes for change requests created with that change template.
+ **Integration with AWS Systems Manager Change Calendar**

  Change Manager allows administrators to restrict scheduling changes during specified time periods. For instance, you can create a policy that allows changes only during business hours to ensure that the team is available to handle any issues. You can also restrict changes during important business events. For example, retail businesses might restrict changes during large sales events. You can also require additional approvals during restricted periods. 
+ **Integration with AWS IAM Identity Center and Active Directory support**

  With IAM Identity Center integration, members of your organization can access AWS accounts and manage their resources using Systems Manager based on a common user identity. Using IAM Identity Center, you can assign your users access to accounts across AWS.

  Integration with Active Directory makes it possible to assign users in your Active Directory account as approvers for change templates created for your Change Manager operations.
+ **Integration with Amazon CloudWatch alarms**

  Change Manager is integrated with CloudWatch alarms. Change Manager listens for CloudWatch alarms during the runbook workflow and takes any actions, including sending notifications, that are defined for the alarm.
+ **Integration with AWS CloudTrail Lake**

  By creating an event data store in AWS CloudTrail Lake, you can view auditable information about the changes made by change requests that run in your account or organization. The event information stored includes such details as the following:
  + The API actions that were run
  + Tthe request parameters included for those actions
  + The user that ran the action
  + The resources that were updated during the process
+ **Integration with AWS Organizations**

  Using the cross-account capabilities provided by Organizations, you can use a delegated administrator account for managing Change Manager operations in OUs in your organization. In your Organizations management account, you can specify which account is to be the delegated administrator account. You can also control which of your OUs Change Manager can be used in.

## Is there a charge to use Change Manager?
<a name="change-manager-cost"></a>

Yes. Change Manager is priced on a pay-per-use basis. You pay only for what you use. For more information, see [AWS Systems Manager Pricing](https://aws.amazon.com/systems-manager/pricing/).

## What are the primary components of Change Manager?
<a name="change-manager-primary-components"></a>

Change Manager components that you use to manage the change process in your organization or account include the following:

### Delegated administrator account
<a name="change-manager-what-is-delegated-account"></a>

If you use Change Manager across an organization, you use a delegated administrator account. This is the AWS account designated as the account for managing operations activities across Systems Manager, including Change Manager. The delegated administrator account manages change activities across your organization. When you set up your organization for use with Change Manager, you specify which of your accounts serves in this role. The delegated administrator account must be the only member of the organizational unit (OU) to which it's assigned. The delegated administrator account isn't required if you use Change Manager with a single AWS account only.

**Important**  
If you use Change Manager across an organization, we recommend always making changes from the delegated administrator account. Although you can make changes from other accounts in the organization, those changes won't be reported in or viewable from the delegated administrator account.

### Change template
<a name="change-manager-what-is-change-template"></a>

A change template is a collection of configuration settings in Change Manager that define such things as required approvals, available runbooks, and notification options for change requests.

You can require that the change templates created by users in your organization or account go through an approval process before they can be used.

Change Manager supports two types of change templates. For an approved change request that is based on an *emergency change template*, the requested change can be made even if there are blocking events in Change Calendar. For an approved change request that is based on a *standard change template*, the requested change can't be made if there are blocking events in Change Calendar unless additional approvals are received from designated *change freeze event * approvers.

### Change request
<a name="change-manager-what-is-change-request"></a>

A change request is a request in Change Manager to run an Automation runbook that updates one or more resources in your AWS or on-premises environments. A change request is created using a change template.

When you create a change request, one or more approvers in your organization or account must review and approve the request. Without the required approvals, the runbook workflow, which applies the changes you request, isn't permitted to run.

In the system, change requests are a type of OpsItem in AWS Systems Manager OpsCenter. However, OpsItems of the type `/aws/changerequest` aren't displayed in OpsCenter. As OpsItems, change requests are subject to the same enforced quotas as other types of OpsItems. 

Additionally, to create a change request programmatically, you don't call the `CreateOpsItem` API operation. Instead, you use the `[https://docs.aws.amazon.com/systems-manager/latest/APIReference/API_StartChangeRequestExecution.html](https://docs.aws.amazon.com/systems-manager/latest/APIReference/API_StartChangeRequestExecution.html)` API operation. But rather than running immediately, the change request must be approved, and there must not any blocking events in Change Calendar to prevent the workflow from running. When approvals have been received and the calendar isn't blocked (or permission has been given to bypass blocking calendar events), the `StartChangeRequestExecution` action is able to complete.

### Runbook workflow
<a name="change-manager-what-is-runbook-workflow"></a>

A runbook workflow is the process of requested changes being made to the targeted resources in your cloud or on-premises environment. Each change request designates a single Automation runbook to use to make the requested change. The runbook workflow occurs after all required approvals have been granted and there are no blocking events in Change Calendar. If the change has been scheduled for a specific date and time, the runbook workflow doesn't begin until scheduled, even if all approvals have been received and the calendar isn't blocked.

**Topics**
+ [How Change Manager works](#how-change-manager-works)
+ [How can Change Manager benefit my operations?](#change-manager-benefits)
+ [Who should use Change Manager?](#change-manager-who)
+ [What are the main features of Change Manager?](#change-manager-features)
+ [Is there a charge to use Change Manager?](#change-manager-cost)
+ [What are the primary components of Change Manager?](#change-manager-primary-components)
+ [Setting up Change Manager](change-manager-setting-up.md)
+ [Working with Change Manager](working-with-change-manager.md)
+ [Auditing and logging Change Manager activity](change-manager-auditing.md)
+ [Troubleshooting Change Manager](change-manager-troubleshooting.md)

# Setting up Change Manager
<a name="change-manager-setting-up"></a>

**Change Manager availability change**  
AWS Systems Manager Change Manager will no longer be open to new customers starting November 7, 2025. If you would like to use Change Manager, sign up prior to that date. Existing customers can continue to use the service as normal. For more information, see [AWS Systems Manager Change Manager availability change](https://docs.aws.amazon.com/systems-manager/latest/userguide/change-manager-availability-change.html). 

You can use Change Manager, a tool in AWS Systems Manager, to manage changes for an entire organization, as configured in AWS Organizations, or for a single AWS account.

If you're using Change Manager with an organization, begin with the topic [Setting up Change Manager for an organization (management account)](change-manager-organization-setup.md), and then proceed to [Configuring Change Manager options and best practices](change-manager-account-setup.md).

If you're using Change Manager with a single account, proceed directly to [Configuring Change Manager options and best practices](change-manager-account-setup.md).

**Note**  
If you begin using Change Manager with a single account, but that account is later added to an organizational unit for which Change Manager is allowed, your single account settings are disregarded.

**Topics**
+ [Setting up Change Manager for an organization (management account)](change-manager-organization-setup.md)
+ [Configuring Change Manager options and best practices](change-manager-account-setup.md)
+ [Configuring roles and permissions for Change Manager](change-manager-permissions.md)
+ [Controlling access to auto-approval runbook workflows](change-manager-auto-approval-access.md)

# Setting up Change Manager for an organization (management account)
<a name="change-manager-organization-setup"></a>

**Change Manager availability change**  
AWS Systems Manager Change Manager will no longer be open to new customers starting November 7, 2025. If you would like to use Change Manager, sign up prior to that date. Existing customers can continue to use the service as normal. For more information, see [AWS Systems Manager Change Manager availability change](https://docs.aws.amazon.com/systems-manager/latest/userguide/change-manager-availability-change.html). 

The tasks in this topic apply if you're using Change Manager, a tool in AWS Systems Manager, with an organization that is set up in AWS Organizations. If you want to use Change Manager only with a single AWS account, skip to the topic [Configuring Change Manager options and best practices](change-manager-account-setup.md).

Perform the tasks in this section in an AWS account that is serving as the *management account* in Organizations. For information about the management account and other Organizations concepts, see [AWS Organizations terminology and concepts](https://docs.aws.amazon.com/organizations/latest/userguide/orgs_getting-started_concepts.html).

If you need to turn on Organizations and specify your account as the management account before proceeding, see [Creating and managing an organization](https://docs.aws.amazon.com/organizations/latest/userguide/orgs_manage_org.html) in the *AWS Organizations User Guide*. 

**Note**  
This setup process can't be performed in the following AWS Regions:  
Europe (Milan) (eu-south-1)
Middle East (Bahrain) (me-south-1)
Africa (Cape Town) (af-south-1)
Asia Pacific (Hong Kong) (ap-east-1)
Ensure that you're working in a different Region in your management account for this procedure.

During the setup procedure, you perform the following major tasks in Quick Setup, a tool in AWS Systems Manager.
+ **Task 1: Register the delegated administrator account for your organization**

  The change-related tasks that are performed using Change Manager are managed in one of your member accounts, which you specify to be the *delegated administrator account*. The delegated administrator account you register for Change Manager becomes the delegated administrator account for all your Systems Manager operations. (You might have delegated administrator accounts for other AWS services). Your delegated administrator account for Change Manager, which isn't the same as your management account, manages change activities across your organization, including change templates, change requests, and approvals for each. In the delegated administrator account, you also specify other configuration options for your Change Manager operations. 
**Important**  
The delegated administrator account must be the only member of the organizational unit (OU) to which it's assigned in Organizations.
+ **Task 2: Define and specify runbook access policies for change requester roles, or custom job functions, that you want to use for your Change Manager operations**

  In order to create change requests in Change Manager, users in your member accounts must be granted AWS Identity and Access Management (IAM) permissions that allow them to access only the Automation runbooks and change templates you choose to make available to them. 
**Note**  
When a user creates a change request, they first select a change template. This change template might make multiple runbooks available, but the user can select only one runbook for each change request. Change templates can also be configured to allow users to include any available runbook in their requests.

  To grant the needed permissions, Change Manager uses the concept of *job functions*, which is also used by IAM. However, unlike the [AWS managed policies for job functions](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_job-functions.html) in IAM, you specify both the names of your Change Manager job functions and the IAM permissions for those job functions. 

  When you configure a job function, we recommend creating a custom policy and providing only the permissions needed to perform change management tasks. For instance, you might specify permissions that limit users to that specific set of runbooks based on *job functions* that you define. 

  For example, you might create a job function with the name `DBAdmin`. For this job function, you might grant only permissions needed for runbooks related to Amazon DynamoDB databases, such as `AWS-CreateDynamoDbBackup` and `AWSConfigRemediation-DeleteDynamoDbTable`. 

  As another example, you might want to grant some users only the permissions needed to work with runbooks related to Amazon Simple Storage Service (Amazon S3) buckets, such as `AWS-ConfigureS3BucketLogging` and `AWSConfigRemediation-ConfigureS3BucketPublicAccessBlock`. 

  The configuration process in Quick Setup for Change Manager also makes a set of full Systems Manager administrative permissions available for you to apply to an administrative role you create. 

  Each Change Manager Quick Setup configuration you deploy creates a job function in your delegated administrator account with permissions to run Change Manager templates and Automation runbooks in the organizational units you have selected. You can create up to 15 Quick Setup configurations for Change Manager. 
+ **Task 3: Choose which member accounts in your organization to use with Change Manager**

  You can use Change Manager with all the member accounts in all your organizational units that are set up in Organizations, and in all the AWS Regions they operate in. If you prefer, you can instead use Change Manager with only some of your organizational units.

**Important**  
We strongly recommend, before you begin this procedure, that you read through its steps to understand the configuration choices you're making and the permissions you're granting. In particular, plan the custom job functions you will create and the permissions you assign to each job function. This ensures that when later you attach the job function policies you create to individual users, user groups, or IAM roles, they're being granted only the permissions you intend for them to have.  
As a best practice, begin by setting up the delegated administrator account using the login for an AWS account administrator. Then configure job functions and their permissions after you have created change templates and identified the runbooks that each one uses.

To set up Change Manager for use with an organization, perform the following task in the Quick Setup area of the Systems Manager console.

You repeat this task for each job function you want to create for your organization. Each job function you create can have permissions for a different set of organizational units.

**To set up an organization for Change Manager in the Organizations management account**

1. Open the AWS Systems Manager console at [https://console.aws.amazon.com/systems-manager/](https://console.aws.amazon.com/systems-manager/).

1. In the navigation pane, choose **Quick Setup**.

1. On the **Change Manager** card, choose **Create**.

1. For **Delegated administrator account**, enter the ID of the AWS account you want to use for managing change templates, change requests, and runbook workflows in Change Manager. 

   If you have previously specified a delegated administrator account for Systems Manager, its ID is already reported in this field. 
**Important**  
The delegated administrator account must be the only member of the organizational unit (OU) to which it's assigned in Organizations.  
If the delegated administrator account you register is later deregistered from that role, the system removes its permissions for managing Systems Manager operations at the same time. Keep in mind that it will be necessary for you return to Quick Setup, designate a different delegated administrator account, and specify all job functions and permissions again.  
If you use Change Manager across an organization, we recommend always making changes from the delegated administrator account. Although you can make changes from other accounts in the organization, those changes won't be reported in or viewable from the delegated administrator account.

1. In the **Permissions to request and make changes** section, do the following.
**Note**  
Each deployment configuration you create provides the permissions policy for just one job function. You can return to Quick Setup later to create more job functions when you have created change templates to use in your operations.

   **To create an administrative role** – For an administrator job function that has IAM permissions for all AWS actions, do the following.
**Important**  
Granting users full administrative permissions should be done sparingly, and only if their roles require full Systems Manager access. For important information about security considerations for Systems Manager access, see [Identity and access management for AWS Systems Manager](security-iam.md) and [Security best practices for Systems Manager](security-best-practices.md).

   1. For **Job function**, enter a name to identify this role and its permissions, such as **MyAWSAdmin**.

   1. For **Role and permissions option**, choose **Administrator permissions**.

   **To create other job functions** – To create a non-administrative role, do the following:

   1. For **Job function**, enter a name to identify this role and suggest its permissions. The name you choose should represent scope of the runbooks for which you will provide permissions, such as `DBAdmin` or `S3Admin`. 

   1. For **Role and permissions option**, choose **Custom permissions**.

   1. In the **Permissions policy editor**, enter the IAM permissions, in JSON format, to grant to this job function.
**Tip**  
We recommend that you use the IAM policy editor to construct your policy and then paste the policy JSON into the **Permissions policy** field.

**Sample policy: DynamoDB database management**  
For example, you might begin with policy content that provides permissions for working with the Systems Manager documents (SSM documents) the job function needs access to. Here is a sample policy content that grants access to all the AWS managed Automation runbooks related to DynamoDB databases and two change templates that have been created in the sample AWS account `123456789012`, in the US East (Ohio) Region (`us-east-2`). 

   The policy also includes permission for the [https://docs.aws.amazon.com/systems-manager/latest/APIReference/API_StartChangeRequestExecution.html](https://docs.aws.amazon.com/systems-manager/latest/APIReference/API_StartChangeRequestExecution.html) operation, which is required for creating a change request in Change Calendar. 
**Note**  
This example isn't comprehensive. Additional permissions might be needed for working with other AWS resources, such as databases and nodes.

------
#### [ JSON ]

****  

   ```
   {
       "Version":"2012-10-17",		 	 	 
       "Statement": [
           {
               "Effect": "Allow",
               "Action": [
                   "ssm:CreateDocument",
                   "ssm:DescribeDocument",
                   "ssm:DescribeDocumentParameters",
                   "ssm:DescribeDocumentPermission",
                   "ssm:GetDocument",
                   "ssm:ListDocumentVersions",
                   "ssm:ModifyDocumentPermission",
                   "ssm:UpdateDocument",
                   "ssm:UpdateDocumentDefaultVersion"
               ],
               "Resource": [
                   "arn:aws:ssm:us-east-1:*:document/AWS-CreateDynamoDbBackup",
                   "arn:aws:ssm:us-east-1:*:document/AWS-AWS-DeleteDynamoDbBackup",
                   "arn:aws:ssm:us-east-1:*:document/AWS-DeleteDynamoDbTableBackups",
                   "arn:aws:ssm:us-east-1:*:document/AWSConfigRemediation-DeleteDynamoDbTable",
                   "arn:aws:ssm:us-east-1:*:document/AWSConfigRemediation-EnableEncryptionOnDynamoDbTable",
                   "arn:aws:ssm:us-east-1:*:document/AWSConfigRemediation-EnablePITRForDynamoDbTable",
                   "arn:aws:ssm:us-east-1:111122223333:document/MyFirstDBChangeTemplate",
                   "arn:aws:ssm:us-east-1:111122223333:document/MySecondDBChangeTemplate"
               ]
           },
           {
               "Effect": "Allow",
               "Action": "ssm:ListDocuments",
               "Resource": "*"
           },
           {
               "Effect": "Allow",
               "Action": "ssm:StartChangeRequestExecution",
               "Resource": [
                   "arn:aws:ssm:us-east-1:111122223333:document/*",
                   "arn:aws:ssm:us-east-1:111122223333:automation-execution/*"
               ]
           }
       ]
   }
   ```

------

   For more information about IAM policies, see [Access management for AWS resources](https://docs.aws.amazon.com/IAM/latest/UserGuide/access.html) and [Creating IAM policies](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_create.html) in the *IAM User Guide.*

1. In the **Targets** section, choose whether to grant permissions for the job function you're creating to your entire organization or only some of your organizational units.

   If you choose **Entire organization**, continue to step 9.

   If you choose **Custom**, continue to step 8.

1. In the **Target OUs** section, select the check boxes of the organizational units to use with Change Manager.

1. Choose **Create**.

After the system finishes setting up Change Manager for your organization, it displays a summary of your deployments. This summary information includes the name of the role that was created for the job function you configured. For example, `AWS-QuickSetup-SSMChangeMgr-DBAdminInvocationRole`.

**Note**  
Quick Setup uses AWS CloudFormation StackSets to deploy your configurations. You can also view information about a completed deployment configuration in the CloudFormation console. For information about StackSets, see [Working with AWS CloudFormation StackSets](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/what-is-cfnstacksets.html) in the *AWS CloudFormation User Guide*.

Your next step is to configure additional Change Manager options. You can complete this task in either your delegated administrator account or any account in an organization unit that you have allowed for use with Change Manager. You configure options such as choosing a user identity management option, specifying which users can review and approve or reject change templates and change requests, and choosing which best practice options to allow for your organization. For information, see [Configuring Change Manager options and best practices](change-manager-account-setup.md).

# Configuring Change Manager options and best practices
<a name="change-manager-account-setup"></a>

**Change Manager availability change**  
AWS Systems Manager Change Manager will no longer be open to new customers starting November 7, 2025. If you would like to use Change Manager, sign up prior to that date. Existing customers can continue to use the service as normal. For more information, see [AWS Systems Manager Change Manager availability change](https://docs.aws.amazon.com/systems-manager/latest/userguide/change-manager-availability-change.html). 

The tasks in this section must be performed whether you're using Change Manager, a tool in AWS Systems Manager, across an organization or in a single AWS account.

If you're using Change Manager for an organization, you can perform the following tasks in either your delegated administrator account or any account in an organization unit that you have allowed for use with Change Manager.

**Topics**
+ [Task 1: Configuring Change Manager user identity management and template reviewers](#cm-configure-account-task-1)
+ [Task 2: Configuring Change Manager change freeze event approvers and best practices](#cm-configure-account-task-2)
+ [Configuring Amazon SNS topics for Change Manager notifications](change-manager-sns-setup.md)

## Task 1: Configuring Change Manager user identity management and template reviewers
<a name="cm-configure-account-task-1"></a>

Perform the task in this procedure the first time you access Change Manager. You can update these configuration settings later by returning to Change Manager and choosing **Edit** on the **Settings** tab.

**To configure Change Manager user identity management and template reviewers**

1. Sign in to the AWS Management Console.

   If you're using Change Manager for an organization, sign in using your credentials for your delegated administrator account. The user must have the necessary AWS Identity and Access Management (IAM) permissions for making updates to your Change Manager settings.

1. Open the AWS Systems Manager console at [https://console.aws.amazon.com/systems-manager/](https://console.aws.amazon.com/systems-manager/).

1. In the navigation pane, choose **Change Manager**.

1. On the service home page, depending on the available options, do one of the following:
   + If you're using Change Manager with AWS Organizations , choose **Set up delegated account**.
   + If you're using Change Manager with a single AWS account, choose **Set up Change Manager**.

     -or-

     Choose **Create sample change request**, **Skip**, and then choose the **Settings** tab.

1. For **User identity management**, choose one of the following.
   + **AWS Identity and Access Management (IAM)** – Identify the users who make and approve requests and perform other actions in Change Manager by using your existing user, groups, and roles.
   + **AWS IAM Identity Center (IAM Identity Center)** – Allow [IAM Identity Center](https://docs.aws.amazon.com/singlesignon/latest/userguide/) to create and manage identities, or connect to your existing identity source to identify the users who perform actions in Change Manager.

1. In the **Template reviewer notification** section, specify the Amazon Simple Notification Service (Amazon SNS) topics to use to notify template reviewers that a new change template or change template version is ready for review. Ensure that the Amazon SNS topic you choose is configured to send notifications to your template reviewers. 

   For information about creating and configuring Amazon SNS topics for change template reviewer notifications, see [Configuring Amazon SNS topics for Change Manager notifications](change-manager-sns-setup.md).

   1. To specify the Amazon SNS topic for template reviewer notification, choose one of the following:
      + **Enter an SNS Amazon Resource Name (ARN)** – For **Topic ARN**, enter the ARN of an existing Amazon SNS topic. This topic can be in any of your organization's accounts.
      + **Select an existing SNS topic** – For **Target notification topic**, select the ARN of an existing Amazon SNS topic in your current AWS account. (This option isn't available if you haven't yet created any Amazon SNS topics in your current AWS account and AWS Region.)
**Note**  
The Amazon SNS topic you select must be configured to specify the notifications it sends and the subscribers they're sent to. Its access policy must also grant permissions to Systems Manager so Change Manager can send notifications. For information, see [Configuring Amazon SNS topics for Change Manager notifications](change-manager-sns-setup.md). 

   1. Choose **Add notification**.

1. In the **Change template reviewers** section, select the users in your organization or account to review new change templates or change template versions before they can be used in your operations. 

   Change template reviewers are responsible for verifying the suitability and security of templates other users have submitted for use in Change Manager runbook workflows.

   Select change template reviewers by doing the following:

   1. Choose **Add**.

   1. Select the check box next to the name of each user, group, or IAM role you want to assign as a change template reviewer.

   1. Choose **Add approvers**.

1. Choose **Submit**.

 After you complete this initial setup process, configure additional Change Manager settings and best practices by following the steps in [Task 2: Configuring Change Manager change freeze event approvers and best practices](#cm-configure-account-task-2).

## Task 2: Configuring Change Manager change freeze event approvers and best practices
<a name="cm-configure-account-task-2"></a>

After you complete the steps in [Task 1: Configuring Change Manager user identity management and template reviewers](#cm-configure-account-task-1), you can designate extra reviewers for change requests during *change freeze events* and specify which available best practices you want to allow for your Change Manager operations.

A change freeze event means that restrictions are in place in the current change calendar (the calendar state in AWS Systems Manager Change Calendar is `CLOSED`). In these cases, in addition to regular approvers for change requests, or if the change request is created using a template that allow auto-approvals, change freeze approvers must grant permission for this change request to run. If they don't, the change won't be processed until the calendar state is again `OPEN`.

**To configure Change Manager change freeze event approvers and best practices**

1. In the navigation pane, choose **Change Manager**.

1. Choose the **Settings** tab, and then choose **Edit**.

1. In the **Approvers for change freeze events** section, select the users in your organization or account who can approve changes to run even when the calendar in use in Change Calendar is currently CLOSED.
**Note**  
To allow change freeze reviews, you must turn on the **Check Change Calendar for restricted change events** option in **Best practices**.

   Select approvers for change freeze events by doing the following:

   1. Choose **Add**.

   1. Select the check box next to the name of each user, group, or IAM role you want to assign as an approver for change freeze events.

   1. Choose **Add approvers**.

1. In the **Best practices** section near the bottom of the page, turn on the best practices you want to enforce for each of the following options.
   + Option: **Check Change Calendar for restricted change events**

     To specify that Change Manager checks a calendar in Change Calendar to make sure changes aren't blocked by scheduled events, first select the **Enabled** check box, and then select the calendar to check for restricted events from the **Change Calendar** list.

     For more information about Change Calendar, see [AWS Systems Manager Change Calendar](systems-manager-change-calendar.md).
   + Option: **SNS topic for approvers for closed events**

     1. Choose one of the following to specify the Amazon Simple Notification Service (Amazon SNS) topic in your account to use for sending notifications to approvers during change freeze events. (Note that you must also specify approvers in the **Approvers for change freeze events** section above **Best practices**.)
        + **Enter an SNS Amazon Resource Name (ARN)** – For **Topic ARN**, enter the ARN of an existing Amazon SNS topic. This topic can be in any of your organization's accounts.
        + **Select an existing SNS topic** – For **Target notification topic**, select the ARN of an existing Amazon SNS topic in your current AWS account. (This option isn't available if you haven't yet created any Amazon SNS topics in your current AWS account and AWS Region.)
**Note**  
The Amazon SNS topic you select must be configured to specify the notifications it sends and the subscribers they're sent to. Its access policy must also grant permissions to Systems Manager so Change Manager can send notifications. For information, see [Configuring Amazon SNS topics for Change Manager notifications](change-manager-sns-setup.md). 

     1. Choose **Add notification**.
   + Option: **Require monitors for all templates**

     If you want to ensure that all templates for your organization or account specify an Amazon CloudWatch alarm to monitor your change operation, select the **Enabled** check box.
   + Option: **Require template review and approval before use**

     To ensure that no change requests are created, and no runbook workflows run, without being based on a template that has been reviewed and approved, select the **Enabled** check box.

1. Choose **Save**.

# Configuring Amazon SNS topics for Change Manager notifications
<a name="change-manager-sns-setup"></a>

**Change Manager availability change**  
AWS Systems Manager Change Manager will no longer be open to new customers starting November 7, 2025. If you would like to use Change Manager, sign up prior to that date. Existing customers can continue to use the service as normal. For more information, see [AWS Systems Manager Change Manager availability change](https://docs.aws.amazon.com/systems-manager/latest/userguide/change-manager-availability-change.html). 

You can configure Change Manager, a tool in AWS Systems Manager, to send notifications to an Amazon Simple Notification Service (Amazon SNS) topic for events related to change requests and change templates. Complete the following tasks to receive notifications for the Change Manager events you add a topic to.

**Topics**
+ [Task 1: Create and subscribe to an Amazon SNS topic](#change-manager-sns-setup-create-topic)
+ [Task 2: Update the Amazon SNS access policy](#change-manager-sns-setup-encryption-policy)
+ [Task 3: (Optional) Update the AWS Key Management Service access policy](#change-manager-sns-setup-KMS-policy)

## Task 1: Create and subscribe to an Amazon SNS topic
<a name="change-manager-sns-setup-create-topic"></a>

First, you must create and subscribe to an Amazon SNS topic. For more information, see [Creating a Amazon SNS topic](https://docs.aws.amazon.com/sns/latest/dg/sns-create-topic.html) and [Subscribing to an Amazon SNS topic](https://docs.aws.amazon.com/sns/latest/dg/sns-tutorial-create-subscribe-endpoint-to-topic.html) in the *Amazon Simple Notification Service Developer Guide*.

**Note**  
To receive notifications, you must specify the Amazon Resource Name (ARN) of an Amazon SNS topic that is in the same AWS Region and AWS account as the delegated administrator account. 

## Task 2: Update the Amazon SNS access policy
<a name="change-manager-sns-setup-encryption-policy"></a>

Use the following procedure to update the Amazon SNS access policy so that Systems Manager can publish Change Manager notifications to the Amazon SNS topic you created in Task 1. Without completing this task, Change Manager doesn't have permission to send notifications for the events you add the topic for.

1. Sign in to the AWS Management Console and open the Amazon SNS console at [https://console.aws.amazon.com/sns/v3/home](https://console.aws.amazon.com/sns/v3/home).

1. In the navigation pane, choose **Topics**.

1. Choose the topic you created in Task 1, and then choose **Edit**.

1. Expand **Access policy**.

1. Add and update the following `Sid` block to the existing policy and replace each *user input placeholder* with your own information .

   ```
   {
       "Sid": "Allow Change Manager to publish to this topic",
       "Effect": "Allow",
       "Principal": {
           "Service": "ssm.amazonaws.com"
       },
       "Action": "sns:Publish",
       "Resource": "arn:aws:sns:region:account-id:topic-name",
       "Condition": {
           "StringEquals": {
               "aws:SourceAccount": [
                   "account-id"
               ]
           }
       }
   }
   ```

   Enter this block after the existing `Sid` block, and replace *region*, *account-id*, and *topic-name* with the appropriate values for the topic you created.

1. Choose **Save changes**.

The system now sends notifications to the Amazon SNS topic when the event type you add to topic for occurs.

**Important**  
If you configured the Amazon SNS topic with an AWS Key Management Service (AWS KMS) server-side encryption key, then you must complete Task 3.

## Task 3: (Optional) Update the AWS Key Management Service access policy
<a name="change-manager-sns-setup-KMS-policy"></a>

If you turned on AWS Key Management Service (AWS KMS) server-side encryption for your Amazon SNS topic, then you must also update the access policy of the AWS KMS key you chose when you configured the topic. Use the following procedure to update the access policy so that Systems Manager can publish Change Manager approval notifications to the Amazon SNS topic you created in Task 1.

1. Open the AWS KMS console at [https://console.aws.amazon.com/kms](https://console.aws.amazon.com/kms).

1. In the navigation pane, choose **Customer managed keys**.

1. Choose the ID of the customer managed key you chose when you created the topic.

1. In the **Key policy** section, choose **Switch to policy view**.

1. Choose **Edit**.

1. Enter the following `Sid` block after one of the existing `Sid` blocks in the existing policy. Replace each *user input placeholder* with your own information.

   ```
   {
       "Sid": "Allow Change Manager to decrypt the key",
       "Effect": "Allow",
       "Principal": {
           "Service": "ssm.amazonaws.com"
       },
       "Action": [
           "kms:Decrypt",
           "kms:GenerateDataKey*"
       ],
       "Resource": "arn:aws:kms:region:account-id:key/key-id",
       "Condition": {
           "StringEquals": {
               "aws:SourceAccount": [
                   "account-id"
               ]
           }
       }
   }
   ```

1. Now enter the following `Sid` block after one of the existing `Sid` blocks in the resource policy to help prevent the [cross-service confused deputy problem](https://docs.aws.amazon.com/IAM/latest/UserGuide/confused-deputy.html). 

   This block uses the [https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_condition-keys.html#condition-keys-sourcearn](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_condition-keys.html#condition-keys-sourcearn) and [https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_condition-keys.html#condition-keys-sourceaccount](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_condition-keys.html#condition-keys-sourceaccount) global condition context keys to limit the permissions that Systems Manager gives another service to the resource.

   Replace each *user input placeholder* with your own information.

------
#### [ JSON ]

****  

   ```
   {
       "Version":"2012-10-17",		 	 	 
       "Statement": [
           {
               "Sid": "Configure confused deputy protection for AWS KMS keys used in Amazon SNS topic when called from Systems Manager",
               "Effect": "Allow",
               "Principal": {
                   "Service": "ssm.amazonaws.com"
               },
               "Action": [
                   "sns:Publish"
               ],
               "Resource": "arn:aws:sns:us-east-1:111122223333:topic-name",
               "Condition": {
                   "ArnLike": {
                       "aws:SourceArn": "arn:aws:ssm:us-east-1:111122223333:*"
                   },
                   "StringEquals": {
                       "aws:SourceAccount": "111122223333"
                   }
               }
           }
       ]
   }
   ```

------

1. Choose **Save changes**.

# Configuring roles and permissions for Change Manager
<a name="change-manager-permissions"></a>

**Change Manager availability change**  
AWS Systems Manager Change Manager will no longer be open to new customers starting November 7, 2025. If you would like to use Change Manager, sign up prior to that date. Existing customers can continue to use the service as normal. For more information, see [AWS Systems Manager Change Manager availability change](https://docs.aws.amazon.com/systems-manager/latest/userguide/change-manager-availability-change.html). 

By default, Change Manager doesn't have permission to perform actions on your resources. You must grant access by using an AWS Identity and Access Management (IAM) service role, or *assume role*. This role enables Change Manager to securely run the runbook workflows specified in an approved change request on your behalf. The role grants AWS Security Token Service (AWS STS) [AssumeRole](https://docs.aws.amazon.com/STS/latest/APIReference/API_AssumeRole.html) trust to Change Manager.

By providing these permissions to a role to act on behalf of users in an organization, users don't need to be granted that array of permissions themselves. The actions allowed by the permissions are limited to approved operations only.

When users in your account or organization create a change request, they can select this assume role to perform the change operations.

You can create a new assume role for Change Manager or update an existing role with the needed permissions.

If you need to create a service role for Change Manager, complete the following tasks. 

**Topics**
+ [Task 1: Creating an assume role policy for Change Manager](#change-manager-role-policy)
+ [Task 2: Creating an assume role for Change Manager](#change-manager-role)
+ [Task 3: Attaching the `iam:PassRole` policy to other roles](#change-manager-passpolicy)
+ [Task 4: Adding inline policies to an assume role to invoke other AWS services](#change-manager-role-add-inline-policy)
+ [Task 5: Configuring user access to Change Manager](#change-manager-passrole)

## Task 1: Creating an assume role policy for Change Manager
<a name="change-manager-role-policy"></a>

Use the following procedure to create the policy that you will attach to your Change Manager assume role.

**To create an assume role policy for Change Manager**

1. Open the IAM console at [https://console.aws.amazon.com/iam/](https://console.aws.amazon.com/iam/).

1. In the navigation pane, choose **Policies**, and then choose **Create Policy**.

1. On the **Create policy** page, choose the **JSON** tab and replace the default content with the following, which you will modify for your own Change Manager operations in following steps.
**Note**  
If you're creating a policy to use with a single AWS account, and not an organization with multiple accounts and AWS Regions, you can omit the first statement block. The `iam:PassRole` permission isn't required in the case of a single account using Change Manager.

------
#### [ JSON ]

****  

   ```
   {
       "Version":"2012-10-17",		 	 	 
       "Statement": [
           {
               "Effect": "Allow",
               "Action": "iam:PassRole",
               "Resource": "arn:aws:iam::111122223333:role/AWS-SystemsManager-job-functionAdministrationRole",
               "Condition": {
                   "StringEquals": {
                       "iam:PassedToService": "ssm.amazonaws.com"
                   }
               }
           },
           {
               "Effect": "Allow",
               "Action": [
                   "ssm:DescribeDocument",
                   "ssm:GetDocument",
                   "ssm:StartChangeRequestExecution"
               ],
               "Resource": [
                   "arn:aws:ssm:us-east-1::document/template-name",
                   "arn:aws:ssm:us-east-1:111122223333:automation-execution/*"
               ]
           },
           {
               "Effect": "Allow",
               "Action": [
                   "ssm:ListOpsItemEvents",
                   "ssm:GetOpsItem",
                   "ssm:ListDocuments",
                   "ssm:DescribeOpsItems"
               ],
               "Resource": "*"
           }
       ]
   }
   ```

------

1. For the `iam:PassRole` action, update the `Resource` value to include the ARNs of all job functions defined for your organization that you want to grant permissions to initiate runbook workflows.

1. Replace the *region*, *account-id*, *template-name*, *delegated-admin-account-id*, and *job-function* placeholders with values for your Change Manager operations.

1. For the second `Resource` statement, modify the list to include all change templates that you want to grant permissions for. Alternatively, specify `"Resource": "*"` to grant permissions for all change templates in your organization.

1. Choose **Next: Tags**.

1. (Optional) Add one or more tag-key value pairs to organize, track, or control access for this policy. 

1. Choose **Next: Review**.

1. On the **Review policy** page, enter a name in the **Name** box, such as **MyChangeManagerAssumeRole**, and then enter an optional description.

1. Choose **Create policy**, and continue to [Task 2: Creating an assume role for Change Manager](#change-manager-role).

## Task 2: Creating an assume role for Change Manager
<a name="change-manager-role"></a>

Use the following procedure to create a Change Manager assume role, a type of service role, for Change Manager.

**To create an assume role for Change Manager**

1. Open the IAM console at [https://console.aws.amazon.com/iam/](https://console.aws.amazon.com/iam/).

1. In the navigation pane, choose **Roles**, and then choose **Create role**.

1. For **Select trusted entity**, make the following choices:

   1. For **Trusted entity type**, choose **AWS service**

   1. For **Use cases for other AWS services**, choose **Systems Manager**

   1. Choose **Systems Manager**, as shown in the following image.  
![\[Screenshot illustrating the Systems Manager option selected as a use case.\]](http://docs.aws.amazon.com/systems-manager/latest/userguide/images/iam_use_cases_for_MWs.png)

1. Choose **Next**.

1. On the **Attached permissions policy** page, search for the assume role policy you created in [Task 1: Creating an assume role policy for Change Manager](#change-manager-role-policy), such as **MyChangeManagerAssumeRole**. 

1. Select the check box next to the assume role policy name, and then choose **Next: Tags**.

1. For **Role name**, enter a name for your new instance profile, such as **MyChangeManagerAssumeRole**.

1. (Optional) For **Description**, update the description for this instance role.

1. (Optional) Add one or more tag-key value pairs to organize, track, or control access for this role. 

1. Choose **Next: Review**.

1. (Optional) For **Tags**, add one or more tag-key value pairs to organize, track, or control access for this role, and then choose **Create role**. The system returns you to the **Roles** page.

1. Choose **Create role**. The system returns you to the **Roles** page.

1. On the **Roles** page, choose the role you just created to open the **Summary** page. 

## Task 3: Attaching the `iam:PassRole` policy to other roles
<a name="change-manager-passpolicy"></a>

Use the following procedure to attach the `iam:PassRole` policy to an IAM instance profile or IAM service role. (The Systems Manager service uses IAM instance profiles to communicate with EC2 instances. For non-EC2 managed nodes in a [hybrid and multicloud](operating-systems-and-machine-types.md#supported-machine-types) environment, an IAM service role is used instead.)

By attaching the `iam:PassRole` policy, the Change Manager service can pass assume role permissions to other services or Systems Manager tools when running runbook workflows.

**To attach the `iam:PassRole` policy to an IAM instance profile or service role**

1. Open the IAM console at [https://console.aws.amazon.com/iam/](https://console.aws.amazon.com/iam/).

1. In the navigation pane, choose **Roles**.

1. Search for the Change Manager assume role you created, such as **MyChangeManagerAssumeRole**, and choose its name.

1. In the **Summary** page for the assume role, choose the **Permissions** tab.

1. Choose **Add permissions, Create inline policy**.

1. On the **Create policy** page, choose the **Visual editor** tab.

1. Choose **Service**, and then choose **IAM**.

1. In the **Filter actions** text box, enter **PassRole**, and then choose the **PassRole** option.

1. Expand **Resources**. Verify that **Specific** is selected, and then choose **Add ARN**.

1. In the **Specify ARN for role** field, enter the ARN of the IAM instance profile role or IAM service role to which you want to pass assume role permissions. The system populates the **Account** and **Role name with path** fields. 

1. Choose **Add**.

1. Choose **Review policy**.

1. For **Name**, enter a name to identify this policy, and then choose **Create policy**.

**More info**  
+ [Configure instance permissions required for Systems Manager](setup-instance-permissions.md)
+ [Create the IAM service role required for Systems Manager in hybrid and multicloud environments](hybrid-multicloud-service-role.md)

## Task 4: Adding inline policies to an assume role to invoke other AWS services
<a name="change-manager-role-add-inline-policy"></a>

When a change request invokes other AWS services by using the Change Manager assume role, the assume role must be configured with permission to invoke those services. This requirement applies to all AWS Automation runbooks (AWS-\$1 runbooks) that might be used in a change request, such as the `AWS-ConfigureS3BucketLogging`, `AWS-CreateDynamoDBBackup`, and `AWS-RestartEC2Instance` runbooks. This requirement also applies to any custom runbooks you create that invoke other AWS services by using actions that call other services. For example, if you use the `aws:executeAwsApi`, `aws:CreateStack`, or `aws:copyImage` actions, then you must configure the service role with permission to invoke those services. You can enable permissions to other AWS services by adding an IAM inline policy to the role. 

**To add an inline policy to an assume role to invoke other AWS services (IAM console)**

1. Sign in to the AWS Management Console and open the IAM console at [https://console.aws.amazon.com/iam/](https://console.aws.amazon.com/iam/).

1. In the navigation pane, choose **Roles**.

1. In the list, choose the name of the assume role that you want to update, such as `MyChangeManagerAssumeRole`.

1. Choose the **Permissions** tab.

1. Choose **Add permissions, Create inline policy**.

1. Choose the **JSON** tab.

1. Enter a JSON policy document for the AWS services you want to invoke. Here are two example JSON policy documents.

   **Amazon S3 `PutObject` and `GetObject` example**

------
#### [ JSON ]

****  

   ```
   {
       "Version":"2012-10-17",		 	 	 
       "Statement": [
           {
               "Effect": "Allow",
               "Action": [
                   "s3:PutObject",
                   "s3:GetObject"
               ],
               "Resource": "arn:aws:s3:::amzn-s3-demo-bucket/*"
           }
       ]
   }
   ```

------

   **Amazon EC2 `CreateSnapshot` and `DescribeSnapShots` example**

------
#### [ JSON ]

****  

   ```
   {
      "Version":"2012-10-17",		 	 	 
      "Statement":[
         {
            "Effect":"Allow",
            "Action":"ec2:CreateSnapshot",
            "Resource":"*"
         },
         {
            "Effect":"Allow",
            "Action":"ec2:DescribeSnapshots",
            "Resource":"*"
         }
      ]
   }
   ```

------

    For details about the IAM policy language, see [IAM JSON policy reference](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies.html) in the *IAM User Guide*.

1. When you're finished, choose **Review policy**. The [Policy Validator](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_policy-validator.html) reports any syntax errors.

1. For **Name**, enter a name to identify the policy that you're creating. Review the policy **Summary** to see the permissions that are granted by your policy. Then choose **Create policy** to save your work.

1. After you create an inline policy, it's automatically embedded in your role.

## Task 5: Configuring user access to Change Manager
<a name="change-manager-passrole"></a>

If your user, group, or role is assigned administrator permissions, then you have access to Change Manager. If you don't have administrator permissions, then an administrator must assign the `AmazonSSMFullAccess` managed policy, or a policy that provides comparable permissions, to your user, group, or role.

Use the following procedure to configure a user to use Change Manager. The user you choose will have permission to configure and run Change Manager. 

Depending on the identity application that you are using in your organization, you can select any of the three options available to configure user access. While configuring the user access, assign or add the following: 

1. Assign the `AmazonSSMFullAccess` policy or a comparable policy that gives permission to access Systems Manager.

1. Assign the `iam:PassRole` policy.

1. Add the ARN for the Change Manager assume role you copied at the end of [Task 2: Creating an assume role for Change Manager](#change-manager-role).

To provide access, add permissions to your users, groups, or roles:
+ Users and groups in AWS IAM Identity Center:

  Create a permission set. Follow the instructions in [Create a permission set](https://docs.aws.amazon.com//singlesignon/latest/userguide/howtocreatepermissionset.html) in the *AWS IAM Identity Center User Guide*.
+ Users managed in IAM through an identity provider:

  Create a role for identity federation. Follow the instructions in [Create a role for a third-party identity provider (federation)](https://docs.aws.amazon.com//IAM/latest/UserGuide/id_roles_create_for-idp.html) in the *IAM User Guide*.
+ IAM users:
  + Create a role that your user can assume. Follow the instructions in [Create a role for an IAM user](https://docs.aws.amazon.com//IAM/latest/UserGuide/id_roles_create_for-user.html) in the *IAM User Guide*.
  + (Not recommended) Attach a policy directly to a user or add a user to a user group. Follow the instructions in [Adding permissions to a user (console)](https://docs.aws.amazon.com//IAM/latest/UserGuide/id_users_change-permissions.html#users_change_permissions-add-console) in the *IAM User Guide*.

You have finished configuring the required roles for Change Manager. You can now use the Change Manager assume role ARN in your Change Manager operations.

# Controlling access to auto-approval runbook workflows
<a name="change-manager-auto-approval-access"></a>

**Change Manager availability change**  
AWS Systems Manager Change Manager will no longer be open to new customers starting November 7, 2025. If you would like to use Change Manager, sign up prior to that date. Existing customers can continue to use the service as normal. For more information, see [AWS Systems Manager Change Manager availability change](https://docs.aws.amazon.com/systems-manager/latest/userguide/change-manager-availability-change.html). 

In each change template created for your organization or account, you can specify whether change requests created from that template can run as auto-approved change requests, meaning that they run automatically without a review step (with the exception of change freeze events).

However, you might want to prevent certain users, groups, or AWS Identity and Access Management (IAM) roles from running auto-approved change requests even if a change template allows it. You can do this through the use of the `ssm:AutoApprove` condition key for the `StartChangeRequestExecution` operation in an IAM policy assigned to the user, group, or IAM role. 

You can add the following policy as an inline policy, where the condition is specified as `false`, to prevent users from running auto-approvable change requests.

------
#### [ JSON ]

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
            {
            "Effect": "Allow",
            "Action": "ssm:StartChangeRequestExecution",
            "Resource": "*",
            "Condition": {
                "BoolIfExists": {
                    "ssm:AutoApprove": "false"
                }
            }
        }
    ]
}
```

------

For information about specifying inline policies, see [Inline policies](https://docs.aws.amazon.com//IAM/latest/UserGuide/access_policies_managed-vs-inline.html#inline-policies) and [Adding and removing IAM identity permissions](https://docs.aws.amazon.com//IAM/latest/UserGuide/access_policies_manage-attach-detach.html) in the *IAM User Guide*.

For more information about condition keys for Systems Manager policies, see [Condition keys for Systems Manager](security_iam_service-with-iam.md#policy-conditions).

# Working with Change Manager
<a name="working-with-change-manager"></a>

**Change Manager availability change**  
AWS Systems Manager Change Manager will no longer be open to new customers starting November 7, 2025. If you would like to use Change Manager, sign up prior to that date. Existing customers can continue to use the service as normal. For more information, see [AWS Systems Manager Change Manager availability change](https://docs.aws.amazon.com/systems-manager/latest/userguide/change-manager-availability-change.html). 

With Change Manager, a tool in AWS Systems Manager, users across your organization or in a single AWS account can perform change-related tasks for which they have been granted the necessary permissions. Change Manager tasks include the following:
+ Create, review, and approve or reject change templates. 

  A change template is a collection of configuration settings in Change Manager that define such things as required approvals, available runbooks, and notification options for change requests.
+ Create, review, and approve or reject change requests.

  A change request is a request in Change Manager to run an Automation runbook that updates one or more resources in your AWS or on-premises environments. A change request is created using a change template.
+ Specify which users in your organization or account can be made reviewers for change templates and change requests.
+ Edit configuration settings, such as how user identities are managed in Change Manager and which of the available *best practice* options are enforced in your Change Manager operations. For information about configuring these settings, see [Configuring Change Manager options and best practices](change-manager-account-setup.md).

**Topics**
+ [Working with change templates](change-templates.md)
+ [Working with change requests](change-requests.md)
+ [Reviewing change request details, tasks, and timelines (console)](reviewing-changes.md)
+ [Viewing aggregated counts of change requests (command line)](change-requests-review-aggregate-command-line.md)

# Working with change templates
<a name="change-templates"></a>

**Change Manager availability change**  
AWS Systems Manager Change Manager will no longer be open to new customers starting November 7, 2025. If you would like to use Change Manager, sign up prior to that date. Existing customers can continue to use the service as normal. For more information, see [AWS Systems Manager Change Manager availability change](https://docs.aws.amazon.com/systems-manager/latest/userguide/change-manager-availability-change.html). 

A change template is a collection of configuration settings in Change Manager that define such things as required approvals, available runbooks, and notification options for change requests.

**Note**  
AWS provides a sample [Hello World](change-templates-aws-managed.md) change template you can use to try out Change Manager, a tool in AWS Systems Manager. However, you create your own change templates to define the changes you want to allow to the resources in your organization or account. 

The changes that are made when a runbook workflow runs are based on the contents an Automation runbook. In each change template you create, you can include one or more Automation runbooks that the user making a change request can choose from to run during the update. You can also create change templates that allow requesters to choose any available Automation runbook for the change request.

To create a change template, you can use the **Builder** option in the **Create template** console page to build a change template. Alternatively, using the **Editor** option, you can manually author JSON or YAML content with the configuration you want for your runbook workflow. You can also use a command line tool to create a change template, with JSON content for the change template stored in an external file.

**Topics**
+ [Try out the AWS managed `Hello World` change template](change-templates-aws-managed.md)
+ [Creating change templates](change-templates-create.md)
+ [Reviewing and approving or rejecting change templates](change-templates-review.md)
+ [Deleting change templates](change-templates-delete.md)

# Try out the AWS managed `Hello World` change template
<a name="change-templates-aws-managed"></a>

**Change Manager availability change**  
AWS Systems Manager Change Manager will no longer be open to new customers starting November 7, 2025. If you would like to use Change Manager, sign up prior to that date. Existing customers can continue to use the service as normal. For more information, see [AWS Systems Manager Change Manager availability change](https://docs.aws.amazon.com/systems-manager/latest/userguide/change-manager-availability-change.html). 

You can use the sample change template `AWS-HelloWorldChangeTemplate`, which uses the sample Automation runbook `AWS-HelloWorld`, to test the review and approval process after you have finished setting up Change Manager, a tool in AWS Systems Manager. This template is designed for testing or verifying your configured permissions, approver assignments, and approval process. Approval to use this change template in your organization or account has already been provided by AWS. Any change request based on this change template, however, must still be approved by reviewers in your organization or account.

Rather than make changes to a resource, the result of the runbook workflow associated with this template is to print a message in the output of an Automation step.

**Before you begin**  
Before you begin, ensure you have completed the following tasks:
+ If you're using AWS Organizations to manage change across an organization, complete the organization setup tasks described in [Setting up Change Manager for an organization (management account)](change-manager-organization-setup.md).
+ Configure Change Manager for your delegated administrator account or single account, as described in [Configuring Change Manager options and best practices](change-manager-account-setup.md). 
**Note**  
If you turned on the best practice option **Require monitors for all templates** in your Change Manager settings, turn it off temporarily while you test the Hello World change template.

**To try out the AWS managed Hello World change template**

1. Open the AWS Systems Manager console at [https://console.aws.amazon.com/systems-manager/](https://console.aws.amazon.com/systems-manager/).

1. In the navigation pane, choose **Change Manager**.

1. Choose **Create request**.

1. Choose the change template named `AWS-HelloWorldChangeTemplate`, and then choose **Next**.

1. For **Name**, enter a name for the change request that makes its purpose easy to identify, such as **MyChangeRequestTest**.

1. For the remainder of the steps to create your change request, see [Creating change requestsCreating change requests (console)](change-requests-create.md).

**Next steps**  
For information about approving change requests, see [Reviewing and approving or rejecting change requests](change-requests-review.md).

To view the status and results of your change request, choose the name of your change request on the **Requests** tab in Change Manager. 

# Creating change templates
<a name="change-templates-create"></a>

**Change Manager availability change**  
AWS Systems Manager Change Manager will no longer be open to new customers starting November 7, 2025. If you would like to use Change Manager, sign up prior to that date. Existing customers can continue to use the service as normal. For more information, see [AWS Systems Manager Change Manager availability change](https://docs.aws.amazon.com/systems-manager/latest/userguide/change-manager-availability-change.html). 

A change template is a collection of configuration settings in Change Manager that define such things as required approvals, available runbooks, and notification options for change requests.

You can create change templates for your operations in Change Manager, a tool in AWS Systems Manager, using the console, which includes Builder and Editor options, or command line tools.

**Topics**
+ [About approvals in your change templates](cm-approvals-templates.md)
+ [Creating change templates using Builder](change-templates-custom-builder.md)
+ [Creating change templates using Editor](change-templates-custom-editor.md)
+ [Creating change templates using command line tools](change-templates-tools.md)

# About approvals in your change templates
<a name="cm-approvals-templates"></a>

**Change Manager availability change**  
AWS Systems Manager Change Manager will no longer be open to new customers starting November 7, 2025. If you would like to use Change Manager, sign up prior to that date. Existing customers can continue to use the service as normal. For more information, see [AWS Systems Manager Change Manager availability change](https://docs.aws.amazon.com/systems-manager/latest/userguide/change-manager-availability-change.html). 

For each change template that you create, you can specify up to five approval *levels* for change requests created from it. For each of those levels, you can designate up to five potential *approvers*. An approver isn't limited to a single user. You can also specify an IAM group or IAM role as an individual approver. For IAM groups and IAM roles, one or more users belonging to the group or role can provide approvals toward receiving the total number of approvals required for a change request. You can also specify more approvers than your change template requires.

Change Manager supports two main approaches to approvals: *per-level approvals* and *per-line approvals*. A combination of the two types is also possible in some situations. We recommend using only per-level approvals in your Change Manager operations.

------
#### [ Per-level approvals ]

*Recommended*. As of January 23, 2023, Change Manager supports per-level approvals. In this model, for each approval level in your change template, you first specify how many approvals are required for that level. Then you specify at least that many approvers for the level and can specify more approvers. However, only the number of per-level approvers that you specify need to approve the change request. For example, you could specify five approvers but require three approvals.

For console-view and JSON samples of this approval type, see [Sample per-level approval configuration](approval-type-samples.md#per-level-approvals).

------
#### [ Per-line approvals ]

*Supported for backward compatibility*. The original release of Change Manager supported only per-line approvals. In this model, every approver specified for an approval level is represented as an approval line. Each approver had to approve a change request for it to be approved at that level. Prior to January 23, 2023, this was the only supported model for approvals. Change templates created before this date continue to support per-line approvals, but we recommend using per-level approvals instead.

For console-view and JSON samples of this approval type, see [Sample per-line approval configuration](approval-type-samples.md#per-line-approvals).

------
#### [ Combined per-line and per-level approvals ]

*Not recommended*. In the console, the **Builder** tab no longer supports adding per-line approvals. However, in some cases you might end up with both per-line and per-level approvals in a change template. This can occur if you update a change template that was created before January 23, 2023, or if you create or update a change template by editing its YAML content manually,

For console-view and JSON samples of this approval type, see [Sample combined per-level and per-line approval configuration](approval-type-samples.md#combined-approval-levels).

------

**Important**  
Although it's possible to create a change template that combines per-line and per-level approvals, this configuration isn't recommended or necessary. Whichever approval type requires more approvals (per-line or per-level approvals) takes precedence. For example:  
If a change template specifies three per-level approvals but five per-line approvals, then five approvals are required.
If a change template specifies four per-level approvals but two per-line approvals, then four approvals are required.

You can create a level that includes both per-line and per-level approvals by editing the YAML or JSON content manually. Then, the **Builder** tab displays controls for specifying the required number of approvals for both the level and for individual lines. However, new levels that you add using the console still support only per-level approval configurations.

## Change request notifications and rejections
<a name="notifications-and-rejections"></a>

Amazon SNS notifications  
When a change request is created using your change template, notifications are sent to subscribers of the Amazon Simple Notification Service (Amazon SNS) topic that has been designated for approval notifications at that level. You can specify the notification topic in the change template or allow the user creating the change request to specify one.  
After the minimum number of required approvals is received at one level, notifications are sent to approvers subscribed to the Amazon SNS topic for the next level, and so on.  
Ensure that the IAM roles, groups, and users you designate together provide enough approvers to meet the required number of approvals you specify. For example, if you designate only a single IAM group as an approver that contains three users, you can't specify that five approvals are mandatory at that level, only three or less.

Change request rejections  
No matter how many approval levels and approvers you specify, only one rejection to a change request is required to prevent the runbook workflow for that request from occurring.

# Change Manager approval type examples
<a name="approval-type-samples"></a>

**Change Manager availability change**  
AWS Systems Manager Change Manager will no longer be open to new customers starting November 7, 2025. If you would like to use Change Manager, sign up prior to that date. Existing customers can continue to use the service as normal. For more information, see [AWS Systems Manager Change Manager availability change](https://docs.aws.amazon.com/systems-manager/latest/userguide/change-manager-availability-change.html). 

The following samples demonstrate the console view and JSON content for the three types of approval types in Change Manager.

**Topics**
+ [Sample per-level approval configuration](#per-level-approvals)
+ [Sample per-line approval configuration](#per-line-approvals)
+ [Sample combined per-level and per-line approval configuration](#combined-approval-levels)

## Sample per-level approval configuration
<a name="per-level-approvals"></a>

In the per-level approval level setup shown in the following image, three approvals are required. Those approvals can come from any combination of IAM users, groups, and roles that are specified as approvers. Specified approvers include two IAM users (John Stiles and Ana Carolina Silva), a user group that contains three members (`GroupOfThree`), and a user role that represents ten users (`RoleOfTen`). 

If all three users in the `GroupOfThree` group approve the change request, it is approved for that level. It's not necessary to receive an approval from each user, group, or role. The minimum number of approvals can come from any combination of specified approvers. We recommend per-level approvals for your Change Manager operations.

![\[Approval level showing three approvals are required and four specified approvers.\]](http://docs.aws.amazon.com/systems-manager/latest/userguide/images/Add-approval-2.png)


The following sample illustrates part of the YAML code for this configuration. 

**Note**  
This version of the YAML code include an additional input, `MinRequiredApprovals` (with an initial capital `M`). The value for this input indicates how many approvals are required from among all available reviewers. Note also that the `minRequiredApprovals` (lowercase initial `m`) value for each approver in the `Approvers` list is `0` (zero). This indicates that the approver can contribute to the overall approvals but is not required to do so.

```
schemaVersion: "0.3"
emergencyChange: false
autoApprovable: false
mainSteps:
  - name: ApproveAction1
    action: aws:approve
    timeoutSeconds: 604800
    inputs:
      Message: Please approve this change request
      MinRequiredApprovals: 3
      EnhancedApprovals:
        Approvers:
          - approver: John Stiles
            type: IamUser
            minRequiredApprovals: 0
          - approver: Ana Carolina Silva
            type: IamUser
            minRequiredApprovals: 0
          - approver: GroupOfThree
            type: IamGroup
            minRequiredApprovals: 0
          - approver: RoleOfTen
            type: IamRole
            minRequiredApprovals: 0
templateInformation: >
  #### What is the purpose of this change?
    //truncated
```

## Sample per-line approval configuration
<a name="per-line-approvals"></a>

In the approval level setup shown in the following image, four approvers are specified. These include two IAM users (John Stiles and Ana Carolina Silva), a user group that contains three members (`GroupOfThree`), and a user role that represents ten users (`RoleOfTen`). Per-line approvals are supported for backwards compatibility but not recommended.

![\[Approval level showing four required per-line approvers.\]](http://docs.aws.amazon.com/systems-manager/latest/userguide/images/Add-approval-1.png)


For the change request to be approved in this per-line approval configuration, it must be approved by all approver lines: John Stiles, Ana Carolina Silva, one member of the `GroupOfThree` group, and one member of the `RoleOfTen` role.

The following sample illustrates part of the YAML code for this configuration.

**Note**  
Observe that the value for each `minRequiredApprovals` approver is `1`. This indicates that one approval is required from each approver.

```
schemaVersion: "0.3"
emergencyChange: false
autoApprovable: false
mainSteps:
  - name: ApproveAction1
    action: aws:approve
    timeoutSeconds: 10000
    inputs:
      Message: Please approve this change request
      EnhancedApprovals:
        Approvers:
          - approver: John Stiles
            type: IamUser
            minRequiredApprovals: 1
          - approver: Ana Carolina Silva
            type: IamUser
            minRequiredApprovals: 1
          - approver: GroupOfThree
            type: IamGroup
            minRequiredApprovals: 1
          - approver: RoleOfTen
            type: IamRole
            minRequiredApprovals: 1
executableRunBooks:
  - name: AWS-HelloWorld
    version: $DEFAULT
templateInformation: >
  #### What is the purpose of this change?
    //truncated
```

## Sample combined per-level and per-line approval configuration
<a name="combined-approval-levels"></a>

In the combined per-level and per-line approval setup shown in the following image, three approvals are specified for the level, but four approvals are specified for the line-item approvals. Whichever approval type requires more approvals takes precedence over the other, so four approvals are required by this configuration. Combined per-level and per-line approval are not recommended.

![\[Approval level showing three approvals required for the level but four required at the line level.\]](http://docs.aws.amazon.com/systems-manager/latest/userguide/images/Add-approval-3.png)


```
schemaVersion: "0.3"
emergencyChange: false
autoApprovable: false
mainSteps:
  - name: ApproveAction1
    action: aws:approve
    timeoutSeconds: 604800
    inputs:
      Message: Please approve this change request
      MinRequiredApprovals: 3
      EnhancedApprovals:
        Approvers:
          - approver: John Stiles
            type: IamUser
            minRequiredApprovals: 1
          - approver: Ana Carolina Silva
            type: IamUser
            minRequiredApprovals: 1
          - approver: GroupOfThree
            type: IamGroup
            minRequiredApprovals: 1
          - approver: RoleOfTen
            type: IamRole
            minRequiredApprovals: 1
templateInformation: >
  #### What is the purpose of this change?
    //truncated
```

**Topics**
+ [About approvals in your change templates](cm-approvals-templates.md)
+ [Creating change templates using Builder](change-templates-custom-builder.md)
+ [Creating change templates using Editor](change-templates-custom-editor.md)
+ [Creating change templates using command line tools](change-templates-tools.md)

# Creating change templates using Builder
<a name="change-templates-custom-builder"></a>

**Change Manager availability change**  
AWS Systems Manager Change Manager will no longer be open to new customers starting November 7, 2025. If you would like to use Change Manager, sign up prior to that date. Existing customers can continue to use the service as normal. For more information, see [AWS Systems Manager Change Manager availability change](https://docs.aws.amazon.com/systems-manager/latest/userguide/change-manager-availability-change.html). 

Using the Builder for change templates in Change Manager, a tool in AWS Systems Manager, you can configure the runbook workflow defined in your change template without having to use JSON or YAML syntax. After you specify your options, the system converts your input into the YAML format that Systems Manager can use to run runbook workflows.

**To create a change template using Builder**

1. Open the AWS Systems Manager console at [https://console.aws.amazon.com/systems-manager/](https://console.aws.amazon.com/systems-manager/).

1. In the navigation pane, choose **Change Manager**.

1. Choose **Create template**.

1. For **Name**, enter a name for the template that makes its purpose easy to identify, such as **UpdateEC2LinuxAMI**.

1. In the **Change template details** section, do the following:
   + For **Description**, provide a brief explanation of how and when the change template you're creating is to be used. 

     This description helps users who create change requests determine whether they're using the correct change template. It helps those who review change requests understand whether the request should be approved.
   + For **Change template type**, specify whether you're creating a standard change template or an emergency change template.

     An emergency change template is used for situations when a change must be made even if changes are otherwise blocked by an event in the calendar in use by AWS Systems Manager Change Calendar. Change requests created from an emergency change template must still be approved by its designated approvers, but the requested changes can still run even when the calendar is blocked.
   + For **Runbook options**, specify the runbooks that users can choose from when creating a change request. You can add a single runbook or multiple runbooks. Alternatively, you can allow requesters to specify which runbook to use. In any of these cases, only one runbook can be included in the change request.
   + For **Runbook**, select the names of the runbooks and the versions of those runbooks that users can choose from for their change requests. No matter how many runbooks you add to the change template, only one can be selected per change request.

     You don't specify a runbook if you chose **Any runbook can be used** earlier.
**Tip**  
Select a runbook and runbook version, and then choose **View** to examine the contents of the runbook in the Systems Manager Documents interface.

1. In the **Template information** section, use Markdown to enter information for users who create change requests from this change template. We have provided a set of questions that you can include for users who create change requests, or you can add other information and questions instead. 
**Note**  
Markdown is a markup language that allows you to add wiki-style descriptions to documents and individual steps within the document. For more information about using Markdown, see [Using Markdown in AWS](https://docs.aws.amazon.com/general/latest/gr/aws-markdown.html).

   We recommend providing questions for users to answer about their change requests to help approvers decide whether or not to grant each change request, such as listing any manual steps required to run as part of the change and a rollback plan. 
**Tip**  
Toggle between **Hide preview** and **Show preview** to see what your content looks like as you compose.

1. In the **Change request approvals** section, do the following:
   + (Optional) If you want to allow change requests that are created from this change template to run automatically, without review by any approvers (with the exception of change freeze events), select **Enable auto-approval**.
**Note**  
Enabling auto-approvals in a change template provides users with the *option* of bypassing reviewers. They can still choose to specify reviewers when creating a change request. Therefore, you must still specify reviewer options in the change template.
**Important**  
If you enable auto-approval for a change template, users can submit change requests using that template that do not require review by reviewers before they run (with the exception of change freeze event approvers). If you want to restrict a particular user, group, or IAM role from submitting auto-approval requests, you can use a condition in an IAM policy for this purpose. For more information, see [Controlling access to auto-approval runbook workflows](change-manager-auto-approval-access.md).
   + For **Number of approvals required at this level**, choose the number of approvals that change requests created from this change template must receive for this level.
   + To add mandatory first-level approvers, choose **Add approver**, and then choose from the following:
     + **Template specified approvers** – Choose one or more users, groups, or AWS Identity and Access Management (IAM) roles from your account to approve change requests created from this change template. Any change requests that are created using this template must be reviewed and approved by each approver you specify.
     + **Request specified approvers** – The user who makes the change request specifies reviewers at the time they make the request and can choose from a list of users in your account. 

       The number you enter in the **Required** column determines how many reviewers must be specified by a change request that uses this change template. 
**Important**  
Prior to January 23, 2023, the **Builder** tab supported specifying per-line approvals only. New change templates and new levels you add to existing change templates using the **Builder** tab support per-level approvals only. We recommend using only per-level approvals in your Change Manager operations.  
For more information, see [About approvals in your change templates](cm-approvals-templates.md).
   + For **SNS topic to notify approvers**, do the following:

     1. Choose one of the following to specify the Amazon Simple Notification Service (Amazon SNS) topic in your account to use for sending notifications to approvers that a change request is ready for their review:
        + **Enter an SNS Amazon Resource Name (ARN)** – For **Topic ARN**, enter the ARN of an existing Amazon SNS topic. This topic can be in any of your organization's accounts.
        + **Select an existing SNS topic** – For **Target notification topic**, select the ARN of an existing Amazon SNS topic in your current AWS account. (This option isn't available if you haven't yet created any Amazon SNS topics in your current AWS account and AWS Region.)
        + **Specify SNS topic when the change request is created **– The user who creates a change request can specify the Amazon SNS topic to use for notifications.
**Note**  
The Amazon SNS topic you select must be configured to specify the notifications it sends and the subscribers they're sent to. Its access policy must also grant permissions to Systems Manager so Change Manager can send notifications. For information, see [Configuring Amazon SNS topics for Change Manager notifications](change-manager-sns-setup.md). 

     1. Choose **Add notification**.

1. (Optional) To add an additional level of approvers, choose **Add approval level** and choose between template-specified approvers and request-specified approvers for this level. Then choose an SNS topic to notify this level of approvers.

   After all approvals have been received by first-level approvers, second-level approvers are notified, and so on.

   You can add a maximum of five levels of approvers in each template. You might, for example, require approvals from users in technical roles for the first level, then managerial approval for the second level.

1. In the **Monitoring** section, for **CloudWatch alarm to monitor**, enter the name of an Amazon CloudWatch alarm in the current account to monitor the progress of runbook workflows that are based on this template. 
**Tip**  
To create a new alarm, or to review the settings of an alarm you want to specify, choose **Open the Amazon CloudWatch console**. For information about working with CloudWatch alarms, see [Using CloudWatch Alarms](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/AlarmThatSendsEmail.html) in the *Amazon CloudWatch User Guide*.

1. In the **Notifications** section, do the following:

   1. Choose one of the following to specify the Amazon SNS topic in your account to use for sending notifications about change requests that are created using this change template: 
      + **Enter an SNS Amazon Resource Name (ARN)** – For **Topic ARN**, enter the ARN of an existing Amazon SNS topic. This topic can be in any of your organization's accounts.
      + **Select an existing SNS topic** – For **Target notification topic**, select the ARN of an existing Amazon SNS topic in your current AWS account. (This option isn't available if you haven't yet created any Amazon SNS topics in your current AWS account and AWS Region.)
**Note**  
The Amazon SNS topic you select must be configured to specify the notifications it sends and the subscribers they're sent to. Its access policy must also grant permissions to Systems Manager so Change Manager can send notifications. For information, see [Configuring Amazon SNS topics for Change Manager notifications](change-manager-sns-setup.md). 

   1. Choose **Add notification**.

1. (Optional) In the **Tags** section, apply one or more tag key name/value pairs to the change template.

   Tags are optional metadata that you assign to a resource. By using tags, you can categorize a resource in different ways, such as by purpose, owner, or environment. For example, you might want to tag a change template to identify the type of change it makes and the environment it runs in. In this case, you could specify the following key name/value pairs:
   + `Key=TaskType,Value=InstanceRepair`
   + `Key=Environment,Value=Production`

1. Choose **Save and preview**.

1. Review the details of the change template you're creating.

   If you want to make change to the change template before submitting it for review, choose **Actions, Edit**.

   If you're satisfied with the contents of the change template, choose **Submit for review**. The users in your organization or account who have been specified as template reviewers on the **Settings** tab in Change Manager are notified that a new change template is pending their review. 

   If an Amazon SNS topic has been specified for change templates, notifications are sent when the change template is rejected or approved. If you don't receive notifications related to this change template, you can return to Change Manager later to check on its status.

# Creating change templates using Editor
<a name="change-templates-custom-editor"></a>

**Change Manager availability change**  
AWS Systems Manager Change Manager will no longer be open to new customers starting November 7, 2025. If you would like to use Change Manager, sign up prior to that date. Existing customers can continue to use the service as normal. For more information, see [AWS Systems Manager Change Manager availability change](https://docs.aws.amazon.com/systems-manager/latest/userguide/change-manager-availability-change.html). 

Use the steps in this topic to configure a change template in Change Manager, a tool in AWS Systems Manager, by entering JSON or YAML instead of using the console controls.

**To create a change template using Editor**

1. In the navigation pane, choose **Change Manager**.

1. Choose **Create template**.

1. For **Name**, enter a name for the template that makes its purpose easy to identify, such as **RestartEC2LinuxInstance**.

1. Above **Change template details**, choose **Editor**.

1. In the **Document editor** section, choose **Edit**, and then enter the JSON or YAML content for your change template. 

   The following is an example.
**Note**  
The parameter `minRequiredApprovals` is used to specify how many reviewers at a specified level must approve a change request that is created using this template.  
This example demonstrates two levels of approvals. You can specify up to five levels of approvals, but only one level is required.   
In the first level, the specific user "John-Doe" must approve each change request. After that, any three members of the IAM role `Admin` must approve the change request.  
For more information about approvals for change templates, see [About approvals in your change templates](cm-approvals-templates.md).

------
#### [ YAML ]

   ```
   description: >-
     This change template demonstrates the feature set available for creating
     change templates for Change Manager. This template starts a Runbook workflow
     for the Automation runbook called AWS-HelloWorld.
   templateInformation: >
     ### Document Name: HelloWorldChangeTemplate
   
     ## What does this document do?
   
     This change template demonstrates the feature set available for creating
     change templates for Change Manager. This template starts a Runbook workflow
     for the Automation runbook called AWS-HelloWorld.
   
     ## Input Parameters
   
     * ApproverSnsTopicArn: (Required) Amazon Simple Notification Service ARN for
     approvers.
   
     * Approver: (Required) The name of the approver to send this request to.
   
     * ApproverType: (Required) The type of reviewer.
       * Allowed Values: IamUser, IamGroup, IamRole, SSOGroup, SSOUser
   
     ## Output Parameters
   
     This document has no outputs
   schemaVersion: '0.3'
   parameters:
     ApproverSnsTopicArn:
       type: String
       description: Amazon Simple Notification Service ARN for approvers.
     Approver:
       type: String
       description: IAM approver
     ApproverType:
       type: String
       description: >-
         Approver types for the request. Allowed values include IamUser, IamGroup,
         IamRole, SSOGroup, and SSOUser.
   executableRunBooks:
     - name: AWS-HelloWorld
       version: '1'
   emergencyChange: false
   autoApprovable: false
   mainSteps:
     - name: ApproveAction1
       action: 'aws:approve'
       timeoutSeconds: 3600
       inputs:
         Message: >-
           A sample change request has been submitted for your review in Change
           Manager. You can approve or reject this request.
         EnhancedApprovals:
           NotificationArn: '{{ ApproverSnsTopicArn }}'
           Approvers:
             - approver: John-Doe
               type: IamUser
               minRequiredApprovals: 1
     - name: ApproveAction2
       action: 'aws:approve'
       timeoutSeconds: 3600
       inputs:
         Message: >-
           A sample change request has been submitted for your review in Change
           Manager. You can approve or reject this request.
         EnhancedApprovals:
           NotificationArn: '{{ ApproverSnsTopicArn }}'
           Approvers:
             - approver: Admin
               type: IamRole
               minRequiredApprovals: 3
   ```

------
#### [ JSON ]

   ```
   {
      "description": "This change template demonstrates the feature set available for creating
     change templates for Change Manager. This template starts a Runbook workflow
     for the Automation runbook called AWS-HelloWorld",
      "templateInformation": "### Document Name: HelloWorldChangeTemplate\n\n
       ## What does this document do?\n
       This change template demonstrates the feature set available for creating change templates for Change Manager. 
       This template starts a Runbook workflow for the Automation runbook called AWS-HelloWorld.\n\n
       ## Input Parameters\n* ApproverSnsTopicArn: (Required) Amazon Simple Notification Service ARN for approvers.\n
       * Approver: (Required) The name of the approver to send this request to.\n
       * ApproverType: (Required) The type of reviewer.  * Allowed Values: IamUser, IamGroup, IamRole, SSOGroup, SSOUser\n\n
       ## Output Parameters\nThis document has no outputs\n",
      "schemaVersion": "0.3",
      "parameters": {
         "ApproverSnsTopicArn": {
            "type": "String",
            "description": "Amazon Simple Notification Service ARN for approvers."
         },
         "Approver": {
            "type": "String",
            "description": "IAM approver"
         },
         "ApproverType": {
            "type": "String",
            "description": "Approver types for the request. Allowed values include IamUser, IamGroup, IamRole, SSOGroup, and SSOUser."
         }
      },
      "executableRunBooks": [
         {
            "name": "AWS-HelloWorld",
            "version": "1"
         }
      ],
      "emergencyChange": false,
      "autoApprovable": false,
      "mainSteps": [
         {
            "name": "ApproveAction1",
            "action": "aws:approve",
            "timeoutSeconds": 3600,
            "inputs": {
               "Message": "A sample change request has been submitted for your review in Change Manager. You can approve or reject this request.",
               "EnhancedApprovals": {
                  "NotificationArn": "{{ ApproverSnsTopicArn }}",
                  "Approvers": [
                     {
                        "approver": "John-Doe",
                        "type": "IamUser",
                        "minRequiredApprovals": 1
                     }
                  ]
               }
            }
         },
           {
            "name": "ApproveAction2",
            "action": "aws:approve",
            "timeoutSeconds": 3600,
            "inputs": {
               "Message": "A sample change request has been submitted for your review in Change Manager. You can approve or reject this request.",
               "EnhancedApprovals": {
                  "NotificationArn": "{{ ApproverSnsTopicArn }}",
                  "Approvers": [
                     {
                        "approver": "Admin",
                        "type": "IamRole",
                        "minRequiredApprovals": 3                  
                     }
                  ]
               }
            }
         }
      ]
   }
   ```

------

1. Choose **Save and preview**.

1. Review the details of the change template you're creating.

   If you want to make change to the change template before submitting it for review, choose **Actions, Edit**.

   If you're satisfied with the contents of the change template, choose **Submit for review**. The users in your organization or account who have been specified as template reviewers on the **Settings** tab in Change Manager are notified that a new change template is pending their review. 

   If an Amazon Simple Notification Service (Amazon SNS) topic has been specified for change templates, notifications are sent when the change template is rejected or approved. If you don't receive notifications related to this change template, you can return to Change Manager later to check on its status.

# Creating change templates using command line tools
<a name="change-templates-tools"></a>

**Change Manager availability change**  
AWS Systems Manager Change Manager will no longer be open to new customers starting November 7, 2025. If you would like to use Change Manager, sign up prior to that date. Existing customers can continue to use the service as normal. For more information, see [AWS Systems Manager Change Manager availability change](https://docs.aws.amazon.com/systems-manager/latest/userguide/change-manager-availability-change.html). 

The following procedures describe how to use the AWS Command Line Interface (AWS CLI) (on Linux, macOS, or Windows Server) or AWS Tools for Windows PowerShell to create a change request in Change Manager, a tool in AWS Systems Manager. 

**To create a change template**

1. Install and configure the AWS CLI or the AWS Tools for PowerShell, if you haven't already.

   For information, see [Installing or updating the latest version of the AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html) and [Installing the AWS Tools for PowerShell](https://docs.aws.amazon.com/powershell/latest/userguide/pstools-getting-set-up.html).

1. Create a JSON file on your local machine with a name such as `MyChangeTemplate.json`, and then paste the content for your change template into it.
**Note**  
Change templates use a version of schema 0.3 that doesn't include all the same support as for Automation runbooks.

   The following is an example.
**Note**  
The parameter `minRequiredApprovals` is used to specify how many reviewers at a specified level must approve a change request that is created using this template.  
This example demonstrates two levels of approvals. You can specify up to five levels of approvals, but only one level is required.   
In the first level, the specific user "John-Doe" must approve each change request. After that, any three members of the IAM role `Admin` must approve the change request.  
For more information about approvals for change templates, see [About approvals in your change templates](cm-approvals-templates.md).

   ```
   {
      "description": "This change template demonstrates the feature set available for creating
     change templates for Change Manager. This template starts a Runbook workflow
     for the Automation runbook called AWS-HelloWorld",
      "templateInformation": "### Document Name: HelloWorldChangeTemplate\n\n
       ## What does this document do?\n
       This change template demonstrates the feature set available for creating change templates for Change Manager. 
       This template starts a Runbook workflow for the Automation runbook called AWS-HelloWorld.\n\n
       ## Input Parameters\n* ApproverSnsTopicArn: (Required) Amazon Simple Notification Service ARN for approvers.\n
       * Approver: (Required) The name of the approver to send this request to.\n
       * ApproverType: (Required) The type of reviewer.  * Allowed Values: IamUser, IamGroup, IamRole, SSOGroup, SSOUser\n\n
       ## Output Parameters\nThis document has no outputs\n",
      "schemaVersion": "0.3",
      "parameters": {
         "ApproverSnsTopicArn": {
            "type": "String",
            "description": "Amazon Simple Notification Service ARN for approvers."
         },
         "Approver": {
            "type": "String",
            "description": "IAM approver"
         },
         "ApproverType": {
            "type": "String",
            "description": "Approver types for the request. Allowed values include IamUser, IamGroup, IamRole, SSOGroup, and SSOUser."
         }
      },
      "executableRunBooks": [
         {
            "name": "AWS-HelloWorld",
            "version": "1"
         }
      ],
      "emergencyChange": false,
      "autoApprovable": false,
      "mainSteps": [
         {
            "name": "ApproveAction1",
            "action": "aws:approve",
            "timeoutSeconds": 3600,
            "inputs": {
               "Message": "A sample change request has been submitted for your review in Change Manager. You can approve or reject this request.",
               "EnhancedApprovals": {
                  "NotificationArn": "{{ ApproverSnsTopicArn }}",
                  "Approvers": [
                     {
                        "approver": "John-Doe",
                        "type": "IamUser",
                        "minRequiredApprovals": 1
                     }
                  ]
               }
            }
         },
           {
            "name": "ApproveAction2",
            "action": "aws:approve",
            "timeoutSeconds": 3600,
            "inputs": {
               "Message": "A sample change request has been submitted for your review in Change Manager. You can approve or reject this request.",
               "EnhancedApprovals": {
                  "NotificationArn": "{{ ApproverSnsTopicArn }}",
                  "Approvers": [
                     {
                        "approver": "Admin",
                        "type": "IamRole",
                        "minRequiredApprovals": 3                  
                     }
                  ]
               }
            }
         }
      ]
   }
   ```

1. Run the following command to create the change template. 

------
#### [ Linux & macOS ]

   ```
   aws ssm create-document \
       --name MyChangeTemplate \
       --document-format JSON \
       --document-type Automation.ChangeTemplate \
       --content file://MyChangeTemplate.json \
       --tags Key=tag-key,Value=tag-value
   ```

------
#### [ Windows ]

   ```
   aws ssm create-document ^
       --name MyChangeTemplate ^
       --document-format JSON ^
       --document-type Automation.ChangeTemplate ^
       --content file://MyChangeTemplate.json ^
       --tags Key=tag-key,Value=tag-value
   ```

------
#### [ PowerShell ]

   ```
   $json = Get-Content -Path "C:\path\to\file\MyChangeTemplate.json" | Out-String
   New-SSMDocument `
       -Content $json `
       -Name "MyChangeTemplate" `
       -DocumentType "Automation.ChangeTemplate" `
       -Tags "Key=tag-key,Value=tag-value"
   ```

------

   For information about other options you can specify, see [https://docs.aws.amazon.com/cli/latest/reference/ssm/create-document.html](https://docs.aws.amazon.com/cli/latest/reference/ssm/create-document.html).

   The system returns information like the following.

   ```
   {
      "DocumentDescription":{
         "CreatedDate":1.585061751738E9,
         "DefaultVersion":"1",
         "Description":"Use this template to update an EC2 Linux AMI. Requires one
         approver specified in the template and an approver specified in the request.",
         "DocumentFormat":"JSON",
         "DocumentType":"Automation",
         "DocumentVersion":"1",
         "Hash":"0d3d879b3ca072e03c12638d0255ebd004d2c65bd318f8354fcde820dEXAMPLE",
         "HashType":"Sha256",
         "LatestVersion":"1",
         "Name":"MyChangeTemplate",
         "Owner":"123456789012",
         "Parameters":[
            {
               "DefaultValue":"",
               "Description":"Level one approvers",
               "Name":"LevelOneApprovers",
               "Type":"String"
            },
            {
               "DefaultValue":"",
               "Description":"Level one approver type",
               "Name":"LevelOneApproverType",
               "Type":"String"
            },
      "cloudWatchMonitors": {
         "monitors": [
            "my-cloudwatch-alarm"
         ]
      }
         ],
         "PlatformTypes":[
            "Windows",
            "Linux"
         ],
         "SchemaVersion":"0.3",
         "Status":"Creating",
         "Tags":[
   
         ]
      }
   }
   ```

The users in your organization or account who have been specified as template reviewers on the **Settings** tab in Change Manager are notified that a new change template is pending their review. 

If an Amazon Simple Notification Service (Amazon SNS) topic has been specified for change templates, notifications are sent when the change template is rejected or approved. If you don't receive notifications related to this change template, you can return to Change Manager later to check on its status.

# Reviewing and approving or rejecting change templates
<a name="change-templates-review"></a>

**Change Manager availability change**  
AWS Systems Manager Change Manager will no longer be open to new customers starting November 7, 2025. If you would like to use Change Manager, sign up prior to that date. Existing customers can continue to use the service as normal. For more information, see [AWS Systems Manager Change Manager availability change](https://docs.aws.amazon.com/systems-manager/latest/userguide/change-manager-availability-change.html). 

If you're specified as a reviewer for change templates in Change Manager, a tool in AWS Systems Manager, you're notified when a new change template, or new version of a change template, is awaiting your review. An Amazon Simple Notification Service (Amazon SNS) topic sends the notifications.

**Note**  
This functionality depends on whether your account has been configured to use an Amazon SNS topic to send change template review notifications. For information about specifying a template reviewer notification topic, see [Task 1: Configuring Change Manager user identity management and template reviewers](change-manager-account-setup.md#cm-configure-account-task-1).

To review the change template, follow the link in your notification, sign in to the AWS Management Console, and follow the steps in this procedure.

**To review and approve or reject a change template**

1. Open the AWS Systems Manager console at [https://console.aws.amazon.com/systems-manager/](https://console.aws.amazon.com/systems-manager/).

1. In the navigation pane, choose **Change Manager**.

1. In the **Change templates** section at the bottom of the **Overview** tab, choose the number in **Pending review**.

1. In the **Change templates** list, locate and choose the name of change template to review.

1. In the summary page, review the proposed content of the change template and do one of the following:
   + To approve the change template, which allows it to be used in change requests, choose **Approve**.
   + To reject the change template, which prevents it from being used in change requests, choose **Reject**.

# Deleting change templates
<a name="change-templates-delete"></a>

**Change Manager availability change**  
AWS Systems Manager Change Manager will no longer be open to new customers starting November 7, 2025. If you would like to use Change Manager, sign up prior to that date. Existing customers can continue to use the service as normal. For more information, see [AWS Systems Manager Change Manager availability change](https://docs.aws.amazon.com/systems-manager/latest/userguide/change-manager-availability-change.html). 

This topic describes how to delete templates that you have created in Change Manager, a tool in Systems Manager. If you are using Change Manager for an organization, this procedure is performed in your delegated administrator account.

1. Open the AWS Systems Manager console at [https://console.aws.amazon.com/systems-manager/](https://console.aws.amazon.com/systems-manager/).

1. In the navigation pane, choose **Change Manager**.

1. Choose the **Templates** tab.

1. Choose the name of the template to delete.

1. Choose **Actions, Delete template**.

1. In the confirmation dialog, enter the word **DELETE**, and then choose **Delete**.

# Working with change requests
<a name="change-requests"></a>

**Change Manager availability change**  
AWS Systems Manager Change Manager will no longer be open to new customers starting November 7, 2025. If you would like to use Change Manager, sign up prior to that date. Existing customers can continue to use the service as normal. For more information, see [AWS Systems Manager Change Manager availability change](https://docs.aws.amazon.com/systems-manager/latest/userguide/change-manager-availability-change.html). 

A change request is a request in Change Manager to run an Automation runbook that updates one or more resources in your AWS or on-premises environments. A change request is created using a change template.

When you create a change request in Change Manager, a tool in AWS Systems Manager, one or more approvers in your organization or account must review and approve the request. Without the required approvals, the runbook workflow, which makes the changes you request, isn't permitted to run.

**Topics**
+ [Creating change requests](change-requests-create.md)
+ [Reviewing and approving or rejecting change requests](change-requests-review.md)

# Creating change requests
<a name="change-requests-create"></a>

**Change Manager availability change**  
AWS Systems Manager Change Manager will no longer be open to new customers starting November 7, 2025. If you would like to use Change Manager, sign up prior to that date. Existing customers can continue to use the service as normal. For more information, see [AWS Systems Manager Change Manager availability change](https://docs.aws.amazon.com/systems-manager/latest/userguide/change-manager-availability-change.html). 

When you create a change request in Change Manager, a tool in AWS Systems Manager, the change template you select typically does the following:
+ Designates approvers for the change request or specifies how many approvals are required
+ Specifies the Amazon Simple Notification Service (Amazon SNS) topic to use to notify approvers about your change request
+ Specifies an Amazon CloudWatch alarm to monitor the runbook workflow for the change request
+ Identifies which Automation runbooks you can choose from to make the requested change

In some cases, a change template might be configured so you specify your own Automation runbook to use, and to specify who should review and approve the request.

**Important**  
If you use Change Manager across an organization, we recommend always making changes from the delegated administrator account. Although you can make changes from other accounts in the organization, those changes won't be reported in or viewable from the delegated administrator account.

**Topics**
+ [About change request approvals](#cm-approvals-requests)
+ [Creating change requests (console)](#change-requests-create-console)
+ [Creating change requests (AWS CLI)](#change-requests-create-cli)

## About change request approvals
<a name="cm-approvals-requests"></a>

Depending on the requirements specified in a change template, change requests that you create from it can require approvals from up to five *levels* before the runbook workflow for the request can occur. For each of those levels, the template creator could specify up to five potential *approvers*. An approver isn't limited to a single user. An approver in this sense can also be an IAM group or IAM role. For IAM groups and IAM roles, one or more users belonging to the group or role can provide approvals toward receiving the total number of approvals required for a change request. Template creators can also specify more approvers than the change template requires.

**Original approval workflows and updated and/or approvals**  
Using change templates created before January 23, 2023, an approval must be received from each specified approver for the change request to be approved at that level. For example, in the approval level setup shown in the following image, four approvers are specified. Specified approvers include two users (John Stiles and Ana Carolina Silva), a user group that contains three members (GroupOfThree), and a user role that represents ten users (RoleOfTen).

![\[Approval level showing four required per-line approvers.\]](http://docs.aws.amazon.com/systems-manager/latest/userguide/images/Add-approval-1.png)


For the change request to be approved at this level, it must be approved by John Stiles, Ana Carolina Silva, one member of the `GroupOfThree` group, and one member of the `RoleOfTen` role.

Using change templates created on or after January 23, 2023, for each approval level, template creators can specify an overall total number of required approvals. Those approvals can come from any combination of users, groups, and roles that have been specified as approvers. A change template could require only one approval for a level but specify, for example, two individual users, two groups, and one role as potential approvers.

For example, in the approval level area shown in the following image, three approvals are required. The template-specified approvers include two users (John Stiles and Ana Carolina Silva), a user group that contains three members (`GroupOfThree`), and a user role that represents ten users (`RoleOfTen`).

![\[Approval level showing three approvals are required and four specified approvers.\]](http://docs.aws.amazon.com/systems-manager/latest/userguide/images/Add-approval-2.png)


If all three users in the `GroupOfThree` group approve your change request, it is approved for that level. It's not necessary to receive an approval from each user, group, or role. The minimum number of approvals can come from any combination of potential approvers.

When your change request is created, notifications are sent to subscribers of the Amazon SNS topic that has been specified for approval notifications at that level. The change template creator might have specified the notification topic that must be used or allowed you to specify one.

After the minimum number of required approvals is received at one level, notifications are sent to approvers that are subscribed to the Amazon SNS topic for the next level, and so on.

No matter how many approval levels and approvers are specified, only one rejection to a change request is required to prevent the runbook workflow for that request from occurring.

## Creating change requests (console)
<a name="change-requests-create-console"></a>

The following procedure describes how to create a change request by using the Systems Manager console.

**To create a change request (console)**

1. Open the AWS Systems Manager console at [https://console.aws.amazon.com/systems-manager/](https://console.aws.amazon.com/systems-manager/).

1. In the navigation pane, choose **Change Manager**.

1. Choose **Create request**.

1. Search for and select a change template that you want to use for this change request.

1. Choose **Next**.

1. For **Name**, enter a name for the change request that makes its purpose easy to identify, such as **UpdateEC2LinuxAMI-us-east-2**.

1. For **Runbook**, select the runbook you want to use to make your requested change.
**Note**  
If the option to select a runbook isn't available, the change template author has specified which runbook must be used.

1. For **Change request information**, use Markdown to provide additional information about the change request to help reviewers decide whether to approve or reject the change request. The author of the template you're using might have provided instructions or questions for you to answer.
**Note**  
Markdown is a markup language that allows you to add wiki-style descriptions to documents and individual steps within the document. For more information about using Markdown, see [Using Markdown in AWS](https://docs.aws.amazon.com/general/latest/gr/aws-markdown.html).

1. In the **Workflow start time** section, choose one of the following:
   + **Run the operation at a scheduled time** – For **Requested start time**, enter the date and time you propose for running the runbook workflow for this request. For **Estimated end time**, enter the date and time that you expect the runbook workflow to complete. (This time is an estimate only that you're providing for reviewers.)
**Tip**  
Choose **View Change Calendar** to check for any blocking events for the time you specify.
   + **Run the operation as soon as possible after approval** – If the change request is approved, the runbook workflow runs as soon as there is a non-restricted period when changes can be made.

1. In the **Change request approvals** section, do the following:

   1. If **Approval type** options are presented, choose one of the following:
      + **Automatic approval **– The change template you selected is configured to allow change requests to run automatically without review by any approvers. Continue to Step 11.
**Note**  
The permissions specified in the IAM policies that govern your use of Systems Manager must not restrict you from submitting auto-approval change requests in order for them to run automatically.
      + **Specify approvers** – You must add one or more users, groups, or IAM roles to review and approve this change request.
**Note**  
You can choose to specify reviewers even if the permissions specified in the IAM policies that govern your use of Systems Manager allow you to run auto-approval change requests.

   1. Choose **Add approver**, and then select one or more users, groups, or AWS Identity and Access Management (IAM) roles from the lists of available reviewers.
**Note**  
One or more approvers might already be specified. This means that mandatory approvers are already specified in the change template you have selected. These approvers can't be removed from the request. If the **Add approver** button isn't available, the template you have chosen doesn't allow additional reviewers to be added to requests.

      For more information about approvals for change requests, see [About change request approvals](#cm-approvals-requests).

   1. Under **SNS topic to notify approvers**, choose one of the following to specify the Amazon SNS topic in your account to use for sending notifications to the approvers you are adding to this change request.
**Note**  
If the option to specify an Amazon SNS topic isn't available, the change template you selected already specifies the Amazon SNS topic to use.
      + **Enter an SNS Amazon Resource Name (ARN)** – For **Topic ARN**, enter the ARN of an existing Amazon SNS topic. This topic can be in any of your organization's accounts.
      + **Select an existing SNS topic** – For **Target notification topic**, select the ARN of an existing Amazon SNS topic in your current account. (This option isn't available if you haven't yet created any Amazon SNS topics in your current AWS account and AWS Region.)
**Note**  
The Amazon SNS topic you select must be configured to specify the notifications it sends and the subscribers they're sent to. Its access policy must also grant permissions to Systems Manager so Change Manager can send notifications. For information, see [Configuring Amazon SNS topics for Change Manager notifications](change-manager-sns-setup.md). 

   1. Choose **Add notification**.

1. Choose **Next**.

1. For **IAM role**, select an IAM role *in your current account * that has the permissions needed to run the runbooks that are specified for this change request.

   This role is also referred to as the service role, or assume role, for Automation. For more information about this role, see [Setting up Automation](automation-setup.md).

1. In the **Deployment location** section, choose one of the following:
**Note**  
If you're using Change Manager with a single AWS account only and not with an organization set up in AWS Organizations, you don't need to specify a deployment location.
   + **Apply change to this account** – The runbook workflow runs in the current account only. For an organization, this means the delegated administrator account.
   + **Apply change to multiple organizational units (OUs)** – Do the following: 

     1. For **Accounts and organizational units (OUs)**, enter the ID of a member account in your organization, in the format **123456789012**, or the ID of an organizational unit, in the format **o-o96EXAMPLE**. 

     1. (Optional) For **Execution role name**, enter the name of the IAM role *in the target account* or OU that has the permissions needed to run the runbooks that are specified for this change request. All accounts in any OU you specify should use the same name for this role.

     1. (Optional) Choose **Add another target location** for each additional account or OU you want to specify and repeat steps a and b. 

     1. For **Target AWS Region**, select the Region to make the change in, such as `Ohio (us-east-2)` for the US East (Ohio) Region.

     1. Expand **Rate control**. 

        For **Concurrency**, enter a number, then from the list select whether this represents the number or percentage of accounts the runbook workflow can run in at the same time. 

        For **Error threshold**, enter a number, then from the list select whether this represents the number or percentage of accounts where runbook workflow can fail before the operation is stopped. 

1. In the **Deployment targets** section, do the following:

   1. Choose one of the following:
      + **Single resource** – The change is to be made for just one resource. For example, a single node or a single Amazon Machine Image (AMI), depending on the operation defined in the runbooks for this change request.
      + **Multiple resources** – For **Parameter**, select from the available parameters from the runbooks for this change request. This selection reflects the type of resource being updated.

        For example, if the runbook for this change request is `AWS-RetartEC2Instance`, you might choose `InstanceId`, and then define which instances are updated by selecting from the following:
        + **Specify tags** – Enter a key-value pair that all resources to be updated are tagged with.
        + **Choose a resource group** – Choose the name of the resource group that all resources to be updated belong to.
        + **Specify parameter values** – Identify the resources to update in the **Runbook parameters** section.
        + **Target all instances** – Make the change on all managed nodes in the target locations.

   1. If you chose **Multiple resources**, expand **Rate control**. 

      For **Concurrency**, enter a number, then from the list select whether this represents the number or percentage of targets the runbook workflow can update at the same time. 

      For **Error threshold**, enter a number, then from the list select whether this represents the number or percentage of targets where the update can fail before the operation is stopped. 

1. If you chose **Specify parameter values** to update multiple resources in the previous step: In the **Runbook parameters** section, specify values for the required input parameters. The parameter values you must supply are based on the contents of the Automation runbooks associated with the change template you chose. 

   For example, if the change template uses the `AWS-RetartEC2Instance` runbook, then you must enter one or more instance IDs for the **InstanceId** parameter. Alternatively, choose **Show interactive instance picker** and select available instances one by one. 

1. Choose **Next**.

1. In the **Review and submit** page, double-check the resources and options you have specified for this change request.

   Choose the **Edit** button for any section you want to make changes to.

   When you're satisfied with the change request details, choose **Submit for approval**.

If an Amazon SNS topic has been specified in the change template you chose for the request, notifications are sent when the request is rejected or approved. If you don't receive notifications for the request, you can return to Change Manager to check the status of your request. 

## Creating change requests (AWS CLI)
<a name="change-requests-create-cli"></a>

You can create a change request using the AWS Command Line Interface (AWS CLI) by specifying options and parameters for the change request in a JSON file and using the `--cli-input-json` option to include it in your command.

**To create a change request (AWS CLI)**

1. Install and configure the AWS CLI or the AWS Tools for PowerShell, if you haven't already.

   For information, see [Installing or updating the latest version of the AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html) and [Installing the AWS Tools for PowerShell](https://docs.aws.amazon.com/powershell/latest/userguide/pstools-getting-set-up.html).

1. Create a JSON file on your local machine with a name such as `MyChangeRequest.json` and paste the following content into it.

   Replace *placeholders* with values for your change request.
**Note**  
This sample JSON creates a change request using the `AWS-HelloWorldChangeTemplate` change template and `AWS-HelloWorld` runbook. To help you adapt this sample for your own change requests, see [https://docs.aws.amazon.com/systems-manager/latest/APIReference/API_StartChangeRequestExecution.html](https://docs.aws.amazon.com/systems-manager/latest/APIReference/API_StartChangeRequestExecution.html) in the *AWS Systems Manager API Reference* for information about all available parameters  
For more information about approvals for change requests, see [About change request approvals](#cm-approvals-requests).

   ```
   {
       "ChangeRequestName": "MyChangeRequest",
       "DocumentName": "AWS-HelloWorldChangeTemplate",
       "DocumentVersion": "$DEFAULT",
       "ScheduledTime": "2021-12-30T03:00:00",
       "ScheduledEndTime": "2021-12-30T03:05:00",
       "Tags": [
           {
               "Key": "Purpose",
               "Value": "Testing"
           }
       ],
       "Parameters": {
           "Approver": [
               "JohnDoe"
           ],
           "ApproverType": [
               "IamUser"
           ],
           "ApproverSnsTopicArn": [
               "arn:aws:sns:us-east-2:123456789012:MyNotificationTopic"
           ]
       },
       "Runbooks": [
           {
               "DocumentName": "AWS-HelloWorld",
               "DocumentVersion": "1",
               "MaxConcurrency": "1",
               "MaxErrors": "1",
               "Parameters": {
                   "AutomationAssumeRole": [
                       "arn:aws:iam::123456789012:role/MyChangeManagerAssumeRole"
                   ]
               }
           }
       ],
       "ChangeDetails": "### Document Name: HelloWorldChangeTemplate\n\n## What does this document do?\nThis change template demonstrates the feature set available for creating change templates for Change Manager. This template starts a Runbook workflow for the Automation document called AWS-HelloWorld.\n\n## Input Parameters\n* ApproverSnsTopicArn: (Required) Amazon Simple Notification Service ARN for approvers.\n* Approver: (Required) The name of the approver to send this request to.\n* ApproverType: (Required) The type of reviewer.\n  * Allowed Values: IamUser, IamGroup, IamRole, SSOGroup, SSOUser\n\n## Output Parameters\nThis document has no outputs \n"
   }
   ```

1. In the directory where you created the JSON file, run the following command.

   ```
   aws ssm start-change-request-execution --cli-input-json file://MyChangeRequest.json
   ```

   The system returns information like the following.

   ```
   {
       "AutomationExecutionId": "b3c1357a-5756-4839-8617-2d2a4EXAMPLE"
   }
   ```

# Reviewing and approving or rejecting change requests
<a name="change-requests-review"></a>

**Change Manager availability change**  
AWS Systems Manager Change Manager will no longer be open to new customers starting November 7, 2025. If you would like to use Change Manager, sign up prior to that date. Existing customers can continue to use the service as normal. For more information, see [AWS Systems Manager Change Manager availability change](https://docs.aws.amazon.com/systems-manager/latest/userguide/change-manager-availability-change.html). 

If you're specified as a reviewer for a change request in Change Manager, a tool in AWS Systems Manager, you're notified through an Amazon Simple Notification Service (Amazon SNS) topic when a new change request is awaiting your review. 

**Note**  
This functionality depends on whether an Amazon SNS was specified in the change template for sending review notifications. For information, see [Configuring Amazon SNS topics for Change Manager notifications](change-manager-sns-setup.md). 

To review the change request, you can follow the link in your notification, or sign in to the AWS Management Console directly and follow the steps in this procedure.

**Note**  
If an Amazon SNS topic is assigned for reviewers in a change template, notifications are sent to the topic's subscribers when the change request changes status.  
For more information about approvals for change requests, see [About change request approvals](change-requests-create.md#cm-approvals-requests).

## Reviewing and approving or rejecting change requests (console)
<a name="change-requests-review-console"></a>

The following procedures describe how to use the Systems Manager console to review and approve or reject change requests.

**To review and approve or reject a single change request**

1. Open the link in the email notification you received and sign in to the AWS Management Console, which directs you to the change request for your review.

1. In the summary page, review the proposed content of the change request.

   To approve the change request, choose **Approve**. In the dialog box, provide any comments you want to add for this approval, and then choose **Approve**. The runbook workflow represented by this request starts to run either when scheduled, or as soon as changes aren't blocked by any restrictions.

   -or-

   To reject the change request, choose **Reject**. In the dialog box, provide any comments you want to add for this rejection, and then choose **Reject**.

**To review and approve or reject change requests in bulk**

1. Open the AWS Systems Manager console at [https://console.aws.amazon.com/systems-manager/](https://console.aws.amazon.com/systems-manager/).

1. In the navigation pane, choose **Change Manager**.

1. Choose the **Approvals** tab.

1. (Optional) Review the details of requests pending your approval by choosing the name of each request, and then return to the **Approvals** tab.

1. Select the check box of each change request that you want to approve.

   -or-

   Select the check box of each change request that you want to reject.

1. In the dialog box, provide any comments you want to add for this approval or rejection.

1. Depending on whether you're approving or rejecting the selected change requests, choose **Approve** or **Reject**.

## Reviewing and approving or rejecting a change request (command line)
<a name="change-requests-review-command-line"></a>

The following procedure describes how to use the AWS Command Line Interface (AWS CLI) (on Linux, macOS, or Windows Server) to review and approve or reject a change request.

**To review and approve or reject a change request**

1. Install and configure the AWS Command Line Interface (AWS CLI), if you haven't already.

   For information, see [Installing or updating the latest version of the AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html).

1. Create a JSON file on your local machine that specifies the parameters for your AWS CLI call. 

   ```
   {
     "OpsItemFilters": 
     [
       {
         "Key": "OpsItemType",
         "Values": ["/aws/changerequest"],
         "Operator": "Equal"
       }
     ],
     "MaxResults": number
   }
   ```

   You can filter the results for a specific approver by specifying the approver's Amazon Resource Name (ARN) in the JSON file. Here is an example.

   ```
   {
     "OpsItemFilters": 
     [
       {
         "Key": "OpsItemType",
         "Values": ["/aws/changerequest"],
         "Operator": "Equal"
       },
       {
         "Key": "ChangeRequestByApproverArn",
         "Values": ["arn:aws:iam::account-id:user/user-name"],
         "Operator": "Equal"
       }
     ],
     "MaxResults": number
   }
   ```

1. Run the following command to view the maximum number of change requests you specified in the JSON file.

------
#### [ Linux & macOS ]

   ```
   aws ssm describe-ops-items \
   --cli-input-json file://filename.json
   ```

------
#### [ Windows ]

   ```
   aws ssm describe-ops-items ^
   --cli-input-json file://filename.json
   ```

------

1. Run the following command to approve or reject a change request.

------
#### [ Linux & macOS ]

   ```
   aws ssm send-automation-signal \
       --automation-execution-id ID \
       --signal-type Approve_or_Reject \
       --payload Comment="message"
   ```

------
#### [ Windows ]

   ```
   aws ssm send-automation-signal ^
   --automation-execution-id ID ^
       --signal-type Approve_or_Reject ^
       --payload Comment="message"
   ```

------

   If an Amazon SNS topic has been specified in the change template you chose for the request, notifications are sent when the request is rejected or approved. If you don't receive notifications for the request, you can return to Change Manager to check the status of your request. For information about other options when using this command, see [https://docs.aws.amazon.com/cli/latest/reference/ssm/send-automation-signal.html](https://docs.aws.amazon.com/cli/latest/reference/ssm/send-automation-signal.html) in the AWS Systems Manager section of the *AWS CLI Command Reference*.

# Reviewing change request details, tasks, and timelines (console)
<a name="reviewing-changes"></a>

**Change Manager availability change**  
AWS Systems Manager Change Manager will no longer be open to new customers starting November 7, 2025. If you would like to use Change Manager, sign up prior to that date. Existing customers can continue to use the service as normal. For more information, see [AWS Systems Manager Change Manager availability change](https://docs.aws.amazon.com/systems-manager/latest/userguide/change-manager-availability-change.html). 

You can view information about a change request, including requests for which changes have already been processed, in the dashboard of Change Manager, a tool in AWS Systems Manager. These details include a link to the Automation operation that runs the runbooks that make the change. An Automation execution ID is generated when the request is created, but the process doesn't run until all approvals have been given and no restrictions are in place to block the change.

**To review change request details, tasks, and timelines**

1. In the navigation pane, choose **Change Manager**.

1. Choose the **Requests** tab.

1. In the **Change requests** section, search for the change request you want to review. 

   You can use the **Create date range** options to limit results to a specific time period.

   You can filter requests by the following properties:
   + `Status`
   + `Request ID`
   + `Approver`
   + `Requester`

   For example, to view details about all change requests that have completed successfully in the past 24 hours, do the following:

   1. For **Create date range**, choose **1d**.

   1. In the search box, select **Status, CompletedWithSuccess**. 

   1. In the results, choose the name of the successfully completed change request to review results for.

1. View information about the change request on the following tabs:
   + **Request details** – View basic details about the change request, including the requester, the change template, and the Automation runbooks selected for the change. You can also follow a link to the Automation operation details and view information about any runbook parameters specified in the request, Amazon CloudWatch alarms assigned to the change request, and approvals and comments provided for the request.
   + **Task** – View information about the task in the change, including task status for completed change requests, the targeted resources, the steps in the associated Automation runbooks, and concurrency and error threshold details.
   + **Timeline** – View a summary of all events associated with the change request, listed by date and time. The summary indicates when the change request was created, actions by assigned approvers, a note of when approved change requests are scheduled to run, runbook workflow details, and status changes for the overall change process and each step in the runbook.
   + **Associated events** – View auditable details about change requests that are recorded in [AWS CloudTrail Lake](https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudtrail-lake.html). Details include which API actions were run, the request parameters included for those actions, the user account that ran the action, the resources updated during the process, and more.

     When you enable CloudTrail Lake event tracking, CloudTrail Lake creates an event data store for events related to your change requests. The event details are available for the account or organization where the change request ran. You can turn on CloudTrail Lake event tracking from any change request in your account or organization. For information about enabling CloudTrail Lake integration and creating an event data store, see [Monitoring your change request events](monitoring-change-request-events.md).
**Note**  
There is a charge to use **CloudTrail Lake**. For details, see [AWS CloudTrail pricing](https://aws.amazon.com/cloudtrail/pricing/).

# Viewing aggregated counts of change requests (command line)
<a name="change-requests-review-aggregate-command-line"></a>

**Change Manager availability change**  
AWS Systems Manager Change Manager will no longer be open to new customers starting November 7, 2025. If you would like to use Change Manager, sign up prior to that date. Existing customers can continue to use the service as normal. For more information, see [AWS Systems Manager Change Manager availability change](https://docs.aws.amazon.com/systems-manager/latest/userguide/change-manager-availability-change.html). 

You can view aggregated counts of change requests in Change Manager, a tool in AWS Systems Manager, by using the [GetOpsSummary](https://docs.aws.amazon.com/systems-manager/latest/APIReference/API_GetOpsSummary.html) API operation. This API operation can return counts for a single AWS account in a single AWS Region or for multiple accounts and multiple Regions.

**Note**  
If you want to view aggregated counts of change requests for multiple AWS accounts and multiple AWS Regions, you must set up and configure a resource data sync. For more information, see [Creating a resource data sync for Inventory](inventory-create-resource-data-sync.md).

The following procedure describes how to use the AWS Command Line Interface (AWS CLI) (on Linux, macOS, or Windows Server) to view aggregated counts of change requests. 

**To view aggregated counts of change requests**

1. Install and configure the AWS Command Line Interface (AWS CLI), if you haven't already.

   For information, see [Installing or updating the latest version of the AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html).

1. Run one of the following commands. 

   **Single account and Region**

   This command returns a count of all change requests for the AWS account and AWS Region for which your AWS CLI session is configured.

------
#### [ Linux & macOS ]

   ```
   aws ssm get-ops-summary \
   --filters Key=AWS:OpsItem.OpsItemType,Values="/aws/changerequests",Type=Equal \
   --aggregators AggregatorType=count,AttributeName=Status,TypeName=AWS:OpsItem
   ```

------
#### [ Windows ]

   ```
   aws ssm get-ops-summary ^
   --filters Key=AWS:OpsItem.OpsItemType,Values="/aws/changerequests",Type=Equal ^
   --aggregators AggregatorType=count,AttributeName=Status,TypeName=AWS:OpsItem
   ```

------

   The call returns information like the following.

   ```
   {
       "Entities": [
           {
               "Data": {
                   "AWS:OpsItem": {
                       "Content": [
                           {
                               "Count": "38",
                               "Status": "Open"
                           }
                       ]
                   }
               }
           }
       ]
   }
   ```

   **Multiple accounts and/or Regions**

   This command returns a count of all change requests for the AWS accounts and AWS Regions specified in the resource data sync.

------
#### [ Linux & macOS ]

   ```
   aws ssm get-ops-summary \
       --sync-name resource_data_sync_name \
       --filters Key=AWS:OpsItem.OpsItemType,Values="/aws/changerequests",Type=Equal \
       --aggregators AggregatorType=count,AttributeName=Status,TypeName=AWS:OpsItem
   ```

------
#### [ Windows ]

   ```
   aws ssm get-ops-summary ^
       --sync-name resource_data_sync_name ^
       --filters Key=AWS:OpsItem.OpsItemType,Values="/aws/changerequests",Type=Equal ^
       --aggregators AggregatorType=count,AttributeName=Status,TypeName=AWS:OpsItem
   ```

------

   The call returns information like the following.

   ```
   {
       "Entities": [
           {
               "Data": {
                   "AWS:OpsItem": {
                       "Content": [
                           {
                               "Count": "43",
                               "Status": "Open"
                           },
                           {
                               "Count": "2",
                               "Status": "Resolved"
                           }
                       ]
                   }
               }
           }
       ]
   }
   ```

   **Multiple accounts and a specific Region**

   This command returns a count of all change requests for the AWS accounts specified in the resource data sync. However, it only returns data from the Region specified in the command.

------
#### [ Linux & macOS ]

   ```
   aws ssm get-ops-summary \
       --sync-name resource_data_sync_name \
       --filters Key=AWS:OpsItem.SourceRegion,Values='Region',Type=Equal Key=AWS:OpsItem.OpsItemType,Values="/aws/changerequests",Type=Equal \
       --aggregators AggregatorType=count,AttributeName=Status,TypeName=AWS:OpsItem
   ```

------
#### [ Windows ]

   ```
   aws ssm get-ops-summary ^
       --sync-name resource_data_sync_name ^
       --filters Key=AWS:OpsItem.SourceRegion,Values='Region',Type=Equal Key=AWS:OpsItem.OpsItemType,Values="/aws/changerequests",Type=Equal ^
       --aggregators AggregatorType=count,AttributeName=Status,TypeName=AWS:OpsItem
   ```

------

   **Multiple accounts and Regions with output grouped by Region**

   This command returns a count of all change requests for the AWS accounts and AWS Regions specified in the resource data sync. The output displays count information per Region.

------
#### [ Linux & macOS ]

   ```
   aws ssm get-ops-summary \
       --sync-name resource_data_sync_name \
       --filters Key=AWS:OpsItem.OpsItemType,Values="/aws/changerequests",Type=Equal \
       --aggregators '[{"AggregatorType":"count","TypeName":"AWS:OpsItem","AttributeName":"Status","Aggregators":[{"AggregatorType":"count","TypeName":"AWS:OpsItem","AttributeName":"SourceRegion"}]}]'
   ```

------
#### [ Windows ]

   ```
   aws ssm get-ops-summary ^
       --sync-name resource_data_sync_name ^
       --filters Key=AWS:OpsItem.OpsItemType,Values="/aws/changerequests",Type=Equal ^
       --aggregators '[{"AggregatorType":"count","TypeName":"AWS:OpsItem","AttributeName":"Status","Aggregators":[{"AggregatorType":"count","TypeName":"AWS:OpsItem","AttributeName":"SourceRegion"}]}]'
   ```

------

   The call returns information like the following.

   ```
   {
           "Entities": [
               {
                   "Data": {
                       "AWS:OpsItem": {
                           "Content": [
                               {
                                   "Count": "38",
                                   "SourceRegion": "us-east-1",
                                   "Status": "Open"
                               },
                               {
                                   "Count": "4",
                                   "SourceRegion": "us-east-2",
                                   "Status": "Open"
                               },
                               {
                                   "Count": "1",
                                   "SourceRegion": "us-west-1",
                                   "Status": "Open"
                               },
                               {
                                   "Count": "2",
                                   "SourceRegion": "us-east-2",
                                   "Status": "Resolved"
                               }
                           ]
                       }
                   }
               }
           ]
       }
   ```

   **Multiple accounts and Regions with output grouped by accounts and Regions**

   This command returns a count of all change requests for the AWS accounts and AWS Regions specified in the resource data sync. The output groups the count information by accounts and Regions.

------
#### [ Linux & macOS ]

   ```
   aws ssm get-ops-summary \
       --sync-name resource_data_sync_name \
       --filters Key=AWS:OpsItem.OpsItemType,Values="/aws/changerequests",Type=Equal \
       --aggregators '[{"AggregatorType":"count","TypeName":"AWS:OpsItem","AttributeName":"Status","Aggregators":[{"AggregatorType":"count","TypeName":"AWS:OpsItem","AttributeName":"SourceAccountId","Aggregators":[{"AggregatorType":"count","TypeName":"AWS:OpsItem","AttributeName":"SourceRegion"}]}]}]'
   ```

------
#### [ Windows ]

   ```
   aws ssm get-ops-summary ^
       --sync-name resource_data_sync_name ^
       --filters Key=AWS:OpsItem.OpsItemType,Values="/aws/changerequests",Type=Equal ^
       --aggregators '[{"AggregatorType":"count","TypeName":"AWS:OpsItem","AttributeName":"Status","Aggregators":[{"AggregatorType":"count","TypeName":"AWS:OpsItem","AttributeName":"SourceAccountId","Aggregators":[{"AggregatorType":"count","TypeName":"AWS:OpsItem","AttributeName":"SourceRegion"}]}]}]'
   ```

------

   The call returns information like the following.

   ```
   {
       "Entities": [
           {
               "Data": {
                   "AWS:OpsItem": {
                       "Content": [
                           {
                               "Count": "38",
                               "SourceAccountId": "123456789012",
                               "SourceRegion": "us-east-1",
                               "Status": "Open"
                           },
                           {
                               "Count": "4",
                               "SourceAccountId": "111122223333",
                               "SourceRegion": "us-east-2",
                               "Status": "Open"
                           },
                           {
                               "Count": "1",
                               "SourceAccountId": "111122223333",
                               "SourceRegion": "us-west-1",
                               "Status": "Open"
                           },
                           {
                               "Count": "2",
                               "SourceAccountId": "444455556666",
                               "SourceRegion": "us-east-2",
                               "Status": "Resolved"
                           },
                           {
                               "Count": "1",
                               "SourceAccountId": "222222222222",
                               "SourceRegion": "us-east-1",
                               "Status": "Open"
                           }
                       ]
                   }
               }
           }
       ]
   }
   ```

# Auditing and logging Change Manager activity
<a name="change-manager-auditing"></a>

**Change Manager availability change**  
AWS Systems Manager Change Manager will no longer be open to new customers starting November 7, 2025. If you would like to use Change Manager, sign up prior to that date. Existing customers can continue to use the service as normal. For more information, see [AWS Systems Manager Change Manager availability change](https://docs.aws.amazon.com/systems-manager/latest/userguide/change-manager-availability-change.html). 

You can audit activity in Change Manager, a tool in AWS Systems Manager, by using Amazon CloudWatch and AWS CloudTrail alarms.

For more information about auditing and logging options for Systems Manager, see [Logging and monitoring in AWS Systems Manager](monitoring.md).

## Audit Change Manager activity using CloudWatch alarms
<a name="change-manager-logging-auditing-alarms"></a>

You can configure and assign a CloudWatch alarm to a change template. If any conditions defined in the alarm are met, the actions specified for the alarm are taken. In the alarm configuration, you can specify an Amazon Simple Notification Service (Amazon SNS) topic to notify when an alarm condition is met. 

For information about creating a Change Manager template, see [Working with change templates](change-templates.md).

For information about creating CloudWatch alarms, see [Using CloudWatch Alarms](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/AlarmThatSendsEmail.html) in the *Amazon CloudWatch User Guide*.

## Audit Change Manager activity using CloudTrail
<a name="change-manager-logging-auditing-cloudtrail"></a>

CloudTrail captures API calls made in the Systems Manager console, the AWS Command Line Interface (AWS CLI), and the Systems Manager SDK. You can view the information in the CloudTrail console or in an Amazon Simple Storage Service (Amazon S3) bucket, where it's stored. One bucket is used for all CloudTrail logs for your account.

Logs of Change Manager actions show change template document creation, change template and change request approvals and rejections, activity generated by Automation runbooks, and more. For more information about viewing and using CloudTrail logs of Systems Manager activity, see [Logging AWS Systems Manager API calls with AWS CloudTrail](monitoring-cloudtrail-logs.md).

# Troubleshooting Change Manager
<a name="change-manager-troubleshooting"></a>

**Change Manager availability change**  
AWS Systems Manager Change Manager will no longer be open to new customers starting November 7, 2025. If you would like to use Change Manager, sign up prior to that date. Existing customers can continue to use the service as normal. For more information, see [AWS Systems Manager Change Manager availability change](https://docs.aws.amazon.com/systems-manager/latest/userguide/change-manager-availability-change.html). 

Use the following information to help you troubleshoot problems with Change Manager, a tool in AWS Systems Manager.

**Topics**
+ [“Group *\$1GUID\$1* not found” error during change request approvals when using Active Directory (groups](#change-manager-troubleshooting-sso)

## “Group *\$1GUID\$1* not found” error during change request approvals when using Active Directory (groups
<a name="change-manager-troubleshooting-sso"></a>

**Problem**: When AWS IAM Identity Center (IAM Identity Center) is used for user identity management, a member of an Active Directory group who is granted approval permissions in Change Manager receives a “not authorized” or “group not found” error.
+ **Solution**: When you select Active Directory groups in IAM Identity Center for access to the AWS Management Console, the system schedules a periodic synchronization that copies information from those Active Directory groups into IAM Identity Center. This process must complete before users authorized through Active Directory group membership can successfully approve a request. For more information, see [Connect to your Microsoft AD directory](https://docs.aws.amazon.com/singlesignon/latest/userguide/manage-your-identity-source-ad.html) in the *AWS IAM Identity Center User Guide*.

# AWS Systems Manager Documents
<a name="documents"></a>

An AWS Systems Manager document (SSM document) defines the actions that Systems Manager performs on your managed instances. Systems Manager includes more than 100 pre-configured documents that you can use by specifying parameters at runtime. You can find pre-configured documents in the Systems Manager Documents console by choosing the **Owned by Amazon** tab, or by specifying Amazon for the `Owner` filter when calling the `ListDocuments` API operation. Documents use JavaScript Object Notation (JSON) or YAML, and they include steps and parameters that you specify. 

For enhanced security, as of July 14th, 2025, SSM documents support environment variable interpolation when processing parameters. This feature, available in schema version 2.2 and with SSM Agent version 3.3.2746.0 or higher, helps prevent command injection attacks.

To get started with SSM documents, open the [Systems Manager console](https://console.aws.amazon.com/systems-manager/documents). In the navigation pane, choose **Documents**.

**Important**  
In Systems Manager, an *Amazon-owned* SSM document is a document created and managed by Amazon Web Services itself. *Amazon-owned* documents include a prefix like `AWS-*` in the document name. The owner of the document is considered to be Amazon, not a specific user account within AWS. These documents are publicly available for all to use.

## How can the Documents tool benefit my organization?
<a name="ssm-docs-benefits"></a>

Documents, a tool in AWS Systems Manager, offers these benefits:
+ **Document categories**

  To help you find the documents you need, choose a category depending on the type of document you're searching for. To broaden your search, you can choose multiple categories of the same document type. Choosing categories of different document types is not supported. Categories are only supported for documents owned by Amazon.
+  **Document versions** 

  You can create and save different versions of documents. You can then specify a default version for each document. The default version of a document can be updated to a newer version or reverted to an older version of the document. When you change the content of a document, Systems Manager automatically increments the version of the document. You can retrieve or use any version of a document by specifying the document version in the console, AWS Command Line Interface (AWS CLI) commands, or API calls.
+  **Customize documents for your needs** 

  If you want to customize the steps and actions in a document, you can create your own. The system stores the document with your AWS account in the AWS Region you create it in. For more information about how to create an SSM document, see [Creating SSM document content](documents-creating-content.md).
+  **Tag documents** 

  You can tag your documents to help you quickly identify one or more documents based on the tags you've assigned to them. For example, you can tag documents for specific environments, departments, users, groups, or periods. You can also restrict access to documents by creating an AWS Identity and Access Management (IAM) policy that specifies the tags that a user or group can access.
+  **Share documents** 

  You can make your documents public or share them with specific AWS accounts in the same AWS Region. Sharing documents between accounts can be useful if, for example, you want all of the Amazon Elastic Compute Cloud (Amazon EC2) instances that you supply to customers or employees to have the same configuration. In addition to keeping applications or patches on the instances up to date, you might want to restrict customer instances from certain activities. Or you might want to ensure that the instances used by employee accounts throughout your organization are granted access to specific internal resources. For more information, see [Sharing SSM documents](documents-ssm-sharing.md).

## Who should use Documents?
<a name="documents-who"></a>
+ Any AWS customer who wants to use Systems Manager tools to improve their operational efficiency at scale, reduce errors associated with manual intervention, and reduce time to resolution of common issues.
+ Infrastructure experts who want to automate deployment and configuration tasks.
+ Administrators who want to reliably resolve common issues, improve troubleshooting efficiency, and reduce repetitive operations.
+ Users who want to automate a task they normally perform manually.

## What are the types of SSM documents?
<a name="what-are-document-types"></a>

The following table describes the different types of SSM documents and their uses.


****  

| Type | Use with | Details | 
| --- | --- | --- | 
|  ApplicationConfiguration ApplicationConfigurationSchema  |   [AWS AppConfig](https://docs.aws.amazon.com/appconfig/latest/userguide/what-is-appconfig.html)   |  AWS AppConfig, a tool in AWS Systems Manager, enables you to create, manage, and quickly deploy application configurations. You can store configuration data in an SSM document by creating a document that uses the `ApplicationConfiguration` document type. For more information, see [Freeform configurations](https://docs.aws.amazon.com/appconfig/latest/userguide/appconfig-creating-configuration-and-profile.html#free-form-configurations) in the *AWS AppConfig User Guide*. If you create a configuration in an SSM document, then you must specify a corresponding JSON Schema. The schema uses the `ApplicationConfigurationSchema` document type and, like a set of rules, defines the allowable properties for each application configuration setting. For more information, see [About validators](https://docs.aws.amazon.com/appconfig/latest/userguide/appconfig-creating-configuration-and-profile-validators.html) in the *AWS AppConfig User Guide*.  | 
|  Automation runbook  |   [Automation](systems-manager-automation.md)   [State Manager](systems-manager-state.md)   [Maintenance Windows](maintenance-windows.md)   |  Use Automation runbooks when performing common maintenance and deployment tasks such as creating or updating an Amazon Machine Image (AMI). State Manager uses Automation runbooks to apply a configuration. These actions can be run on one or more targets at any point during the lifecycle of an instance. Maintenance Windows uses Automation runbooks to perform common maintenance and deployment tasks based on the specified schedule. All Automation runbooks that are supported for Linux-based operating systems are also supported on EC2 instances for macOS.  | 
|  Change Calendar document  |   [Change Calendar](systems-manager-change-calendar.md)   |  Change Calendar, a tool in AWS Systems Manager, uses the `ChangeCalendar` document type. A Change Calendar document stores a calendar entry and associated events that can allow or prevent Automation actions from changing your environment. In Change Calendar, a document stores [iCalendar 2.0](https://icalendar.org/) data in plaintext format. Change Calendar isn't supported on EC2 instances for macOS.  | 
|  AWS CloudFormation template  |   [AWS CloudFormation](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/Welcome.html)   |  AWS CloudFormation templates describe the resources that you want to provision in your CloudFormation stacks. By storing CloudFormation templates as Systems Manager documents, you can benefit from Systems Manager document features. These include creating and comparing multiple versions of your template, and sharing your template with other accounts in the same AWS Region. You can create and edit CloudFormation templates and stacks by using Application Manager, a tool in Systems Manager. For more information, see [Working with CloudFormation templates and stacks in Application Manager](application-manager-working-stacks.md).  | 
|  Command document  |   [Run Command](run-command.md)   [State Manager](systems-manager-state.md)   [Maintenance Windows](maintenance-windows.md)   |  Run Command, a tool in AWS Systems Manager, uses Command documents to run commands. State Manager, a tool in AWS Systems Manager, uses command documents to apply a configuration. These actions can be run on one or more targets at any point during the lifecycle of an instance. Maintenance Windows, a tool in AWS Systems Manager, uses Command documents to apply a configuration based on the specified schedule. Most Command documents are supported on all Linux and Windows Server operating systems supported by Systems Manager. The following Command documents are supported on EC2 instances for macOS: [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/systems-manager/latest/userguide/documents.html)  | 
|  AWS Config conformance pack template  |   [AWS Config](https://docs.aws.amazon.com/config/latest/developerguide/WhatIsConfig.html)   |  AWS Config conformance pack templates are YAML formatted documents used to create conformance packs that contains the list of AWS Config managed or custom rules and remediation actions. For more information, see [Conformance Packs](https://docs.aws.amazon.com/config/latest/developerguide/conformance-packs.html).  | 
|  Package document  |   [Distributor](distributor.md)   |  In Distributor, a tool in AWS Systems Manager, a package is represented by an SSM document. A package document includes attached ZIP archive files that contain software or assets to install on managed instances. Creating a package in Distributor creates the package document. Distributor isn't supported on Oracle Linux and macOS managed instances.  | 
|  Policy document  |   [State Manager](systems-manager-state.md)   |  Inventory, a tool in AWS Systems Manager, uses the `AWS-GatherSoftwareInventory` Policy document with a State Manager association to collect inventory data from managed instances. When creating your own SSM documents, Automation runbooks and Command documents are the preferred method for enforcing a policy on a managed instance. Systems Manager Inventory and the `AWS-GatherSoftwareInventory` Policy document are supported on all operating systems supported by Systems Manager.  | 
|  Post-incident analysis template  |   [Incident Manager post-incident analysis](https://docs.aws.amazon.com/incident-manager/latest/userguide/analysis.html)   |  Incident Manager uses the post-incident analysis template to create an analysis based on AWS operations management best practices. Use the template to create an analysis that your team can use to identify improvements to your incident response.   | 
|  Session document  |   [Session Manager](session-manager.md)   |  Session Manager, a tool in AWS Systems Manager, uses Session documents to determine which type of session to start, such as a port forwarding session, a session to run an interactive command, or a session to create an SSH tunnel. Session documents are supported on all Linux and Windows Server operating systems supported by Systems Manager. The following Command documents are supported on EC2 instances for macOS: [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/systems-manager/latest/userguide/documents.html)  | 

**SSM document quotas**  
For information about SSM document quotas, see [Systems Manager service quotas](https://docs.aws.amazon.com/general/latest/gr/ssm.html#limits_ssm) in the *Amazon Web Services General Reference*.

**Topics**
+ [How can the Documents tool benefit my organization?](#ssm-docs-benefits)
+ [Who should use Documents?](#documents-who)
+ [What are the types of SSM documents?](#what-are-document-types)
+ [Document components](documents-components.md)
+ [Creating SSM document content](documents-creating-content.md)
+ [Working with documents](documents-using.md)
+ [Troubleshooting parameter handling issues](parameter-troubleshooting.md)

# Document components
<a name="documents-components"></a>

This section includes information about the components that make up SSM documents.

**Topics**
+ [Schemas, features, and examples](documents-schemas-features.md)
+ [Data elements and parameters](documents-syntax-data-elements-parameters.md)
+ [Command document plugin reference](documents-command-ssm-plugin-reference.md)

# Schemas, features, and examples
<a name="documents-schemas-features"></a>

AWS Systems Manager (SSM) documents use the following schema versions.
+ Documents of type `Command` can use schema version 1.2, 2.0, and 2.2. If you use schema 1.2 documents, we recommend that you create documents that use schema version 2.2.
+ Documents of type `Policy` must use schema version 2.0 or later.
+ Documents of type `Automation` must use schema version 0.3.
+ Documents of type `Session` must use schema version 1.0.
+ You can create documents in JSON or YAML.

For more information about `Session` document schema, see [Session document schema](session-manager-schema.md).

By using the latest schema version for `Command` and `Policy` documents, you can take advantage of the following features.


**Schema version 2.2 document features**  

| Feature | Details | 
| --- | --- | 
|  Document editing  |  Documents can now be updated. With version 1.2, any update to a document required that you save it with a different name.  | 
|  Automatic versioning  |  Any update to a document creates a new version. This isn't a schema version, but a version of the document.  | 
|  Default version  |  If you have multiple versions of a document, you can specify which version is the default document.  | 
|  Sequencing  |  Plugins or *steps* in a document run in the order that you specified.  | 
|  Cross-platform support  |  Cross-platform support allows you to specify different operating systems for different plugins within the same SSM document. Cross-platform support uses the `precondition` parameter within a step.   | 
| Parameter interpolation | Interpolation means to insert or substitute a variable value into a string. Think of it as filling in a blank space with actual values before the string is used. In the context of SSM documents, parameter interpolation allows string parameters to be interpolated into environment variables before command execution, providing better security against command injections. When set to `ENV_VAR`, the agent creates an environment variable named `SSM_parameter-name` that contains the parameter's value. | 

**Note**  
You must keep AWS Systems Manager SSM Agent on your instances updated with the latest version to use new Systems Manager features and SSM document features. For more information, see [Updating the SSM Agent using Run Command](run-command-tutorial-update-software.md#rc-console-agentexample).

The following table lists the differences between major schema versions.


****  

| Version 1.2 | Version 2.2 (latest version) | Details | 
| --- | --- | --- | 
|  runtimeConfig  |  mainSteps  |  In version 2.2, the `mainSteps` section replaces `runtimeConfig`. The `mainSteps` section allows Systems Manager to run steps in sequence.  | 
|  properties  |  inputs  |  In version 2.2, the `inputs` section replaces the `properties` section. The `inputs` section accepts parameters for steps.  | 
|  commands  |  runCommand  |  In version 2.2, the `inputs` section takes the `runCommand` parameter instead of the `commands` parameter.  | 
|  id  |  action  |  In version 2.2, `Action` replaces `ID`. This is just a name change.  | 
|  not applicable  |  name  |  In version 2.2, `name` is any user-defined name for a step.  | 

**Using the precondition parameter**  
With schema version 2.2 or later, you can use the `precondition` parameter to specify the target operating system for each plugin or to validate input parameters you've defined in your SSM document. The `precondition` parameter supports referencing your SSM document's input parameters, and `platformType` using values of `Linux`, `MacOS`, and `Windows`. Only the `StringEquals` operator is supported.

For documents that use schema version 2.2 or later, if `precondition` isn't specified, each plugin is either run or skipped based on the plugin’s compatibility with the operating system. Plugin compatibility with the operating system is evaluated before the `precondition`. For documents that use schema 2.0 or earlier, incompatible plugins throw an error.

For example, in a schema version 2.2 document, if `precondition` isn't specified and the `aws:runShellScript` plugin is listed, then the step runs on Linux instances, but the system skips it on Windows Server instances because the `aws:runShellScript` isn't compatible with Windows Server instances. However, for a schema version 2.0 document, if you specify the `aws:runShellScript` plugin, and then run the document on a Windows Server instances, the execution fails. You can see an example of the precondition parameter in an SSM document later in this section.

## Schema version 2.2
<a name="documents-schema-twox"></a>

**Top-level elements**  
The following example shows the top-level elements of an SSM document using schema version 2.2.

------
#### [ YAML ]

```
---
schemaVersion: "2.2"
description: A description of the document.
parameters:
  parameter 1:
    property 1: "value"
    property 2: "value"
  parameter 2:
    property 1: "value"
    property 2: "value"
mainSteps:
  - action: Plugin name
    name: A name for the step.
    inputs:
      input 1: "value"
      input 2: "value"
      input 3: "{{ parameter 1 }}"
```

------
#### [ JSON ]

```
{
   "schemaVersion": "2.2",
   "description": "A description of the document.",
   "parameters": {
       "parameter 1": {
           "property 1": "value",
           "property 2": "value"
        },
        "parameter 2":{
           "property 1": "value",
           "property 2": "value"
        } 
    },
   "mainSteps": [
      {
         "action": "Plugin name",
         "name": "A name for the step.",
         "inputs": {
            "input 1": "value",
            "input 2": "value",
            "input 3": "{{ parameter 1 }}"
         }
      }
   ]
}
```

------

**Schema version 2.2 example**  
The following example uses the `aws:runPowerShellScript` plugin to run a PowerShell command on the target instances.

------
#### [ YAML ]

```
---
schemaVersion: "2.2"
description: "Example document"
parameters:
  Message:
    type: "String"
    description: "Example parameter"
    default: "Hello World"
    allowedValues: 
    - "Hello World"
mainSteps:
  - action: "aws:runPowerShellScript"
    name: "example"
    inputs:
      timeoutSeconds: '60'
      runCommand:
      - "Write-Output {{Message}}"
```

------
#### [ JSON ]

```
{
   "schemaVersion": "2.2",
   "description": "Example document",
   "parameters": {
      "Message": {
         "type": "String",
         "description": "Example parameter",
         "default": "Hello World",
         "allowedValues": ["Hello World"]
      }
   },
   "mainSteps": [
      {
         "action": "aws:runPowerShellScript",
         "name": "example",
         "inputs": {
            "timeoutSeconds": "60",
            "runCommand": [
               "Write-Output {{Message}}"
            ]
         }
      }
   ]
}
```

------

**Schema version 2.2 precondition parameter examples**  
Schema version 2.2 provides cross-platform support. This means that within a single SSM document you can specify different operating systems for different plugins. Cross-platform support uses the `precondition` parameter within a step, as shown in the following example. You can also use the `precondition` parameter to validate input parameters you've defined in your SSM document. You can see this in the second of the following examples.

------
#### [ YAML ]

```
---
schemaVersion: '2.2'
description: cross-platform sample
mainSteps:
- action: aws:runPowerShellScript
  name: PatchWindows
  precondition:
    StringEquals:
    - platformType
    - Windows
  inputs:
    runCommand:
    - cmds
- action: aws:runShellScript
  name: PatchLinux
  precondition:
    StringEquals:
    - platformType
    - Linux
  inputs:
    runCommand:
    - cmds
```

------
#### [ JSON ]

```
{
   "schemaVersion": "2.2",
   "description": "cross-platform sample",
   "mainSteps": [
      {
         "action": "aws:runPowerShellScript",
         "name": "PatchWindows",
         "precondition": {
            "StringEquals": [
               "platformType",
               "Windows"
            ]
         },
         "inputs": {
            "runCommand": [
               "cmds"
            ]
         }
      },
      {
         "action": "aws:runShellScript",
         "name": "PatchLinux",
         "precondition": {
            "StringEquals": [
               "platformType",
               "Linux"
            ]
         },
         "inputs": {
            "runCommand": [
               "cmds"
            ]
         }
      }
   ]
}
```

------

------
#### [ YAML ]

```
---
schemaVersion: '2.2'
parameters:
  action:
    type: String
    allowedValues:
    - Install
    - Uninstall
  confirmed:
    type: String
    allowedValues:
    - True
    - False
mainSteps:
- action: aws:runShellScript
  name: InstallAwsCLI
  precondition:
    StringEquals:
    - "{{ action }}"
    - "Install"
  inputs:
    runCommand:
    - sudo apt install aws-cli
- action: aws:runShellScript
  name: UninstallAwsCLI
  precondition:
    StringEquals:
    - "{{ action }} {{ confirmed }}"
    - "Uninstall True"
  inputs:
    runCommand:
    - sudo apt remove aws-cli
```

------
#### [ JSON ]

```
{
   "schemaVersion": "2.2",
   "parameters": {
      "action": {
         "type": "String",
         "allowedValues": [
            "Install",
            "Uninstall"
         ]
      },
      "confirmed": {
         "type": "String",
         "allowedValues": [
            true,
            false
         ]
      }
   },
   "mainSteps": [
      {
         "action": "aws:runShellScript",
         "name": "InstallAwsCLI",
         "precondition": {
            "StringEquals": [
               "{{ action }}",
               "Install"
            ]
         },
         "inputs": {
            "runCommand": [
               "sudo apt install aws-cli"
            ]
         }
      },
      {
         "action": "aws:runShellScript",
         "name": "UninstallAwsCLI",
         "precondition": {
            "StringEquals": [
               "{{ action }} {{ confirmed }}",
               "Uninstall True"
            ]
         },
         "inputs": {
            "runCommand": [
               "sudo apt remove aws-cli"
            ]
         }
      }
   ]
}
```

------

**Schema version 2.2 interpolation example with SSM Agent versions before 3.3.2746.0**  
On SSM Agent versions prior to 3.3.2746.0, the agent ignores the `interpolationType` parameter and instead performs a raw string substitution. If you are referencing `SSM_parameter-name` explicitly, you must set this explicitly. In the following example for Linux, the `SSM_Message` environment variable is referenced explicitly.

```
{
    "schemaVersion": "2.2",
    "description": "An example document",
    "parameters": {
        "Message": {
            "type": "String",
            "description": "Message to be printed",
            "default": "Hello",
            "interpolationType" : "ENV_VAR",
	     "allowedPattern: "^[^"]*$"

        }
    },
    "mainSteps": [{
        "action": "aws:runShellScript",
        "name": "printMessage",
        "inputs": {
            "runCommand": [
              "if [ -z "${SSM_Message+x}" ]; then",
              "    export SSM_Message=\"{{Message}}\"",
              "fi",
              "",
              "echo $SSM_Message"
            ]
        }
    }
}
```

**Note**  
`allowedPattern` isn’t technically required if an SSM document doesn’t use double braces: `{{ }}`

**Schema version 2.2 State Manager example**  
You can use the following SSM document with State Manager, a tool in Systems Manager, to download and install the ClamAV antivirus software. State Manager enforces a specific configuration, which means that each time the State Manager association is run, the system checks to see if the ClamAV software is installed. If not, State Manager reruns this document.

------
#### [ YAML ]

```
---
schemaVersion: '2.2'
description: State Manager Bootstrap Example
parameters: {}
mainSteps:
- action: aws:runShellScript
  name: configureServer
  inputs:
    runCommand:
    - sudo yum install -y httpd24
    - sudo yum --enablerepo=epel install -y clamav
```

------
#### [ JSON ]

```
{
   "schemaVersion": "2.2",
   "description": "State Manager Bootstrap Example",
   "parameters": {},
   "mainSteps": [
      {
         "action": "aws:runShellScript",
         "name": "configureServer",
         "inputs": {
            "runCommand": [
               "sudo yum install -y httpd24",
               "sudo yum --enablerepo=epel install -y clamav"
            ]
         }
      }
   ]
}
```

------

**Schema version 2.2 Inventory example**  
You can use the following SSM document with State Manager to collect inventory metadata about your instances.

------
#### [ YAML ]

```
---
schemaVersion: '2.2'
description: Software Inventory Policy Document.
parameters:
  applications:
    type: String
    default: Enabled
    description: "(Optional) Collect data for installed applications."
    allowedValues:
    - Enabled
    - Disabled
  awsComponents:
    type: String
    default: Enabled
    description: "(Optional) Collect data for AWS Components like amazon-ssm-agent."
    allowedValues:
    - Enabled
    - Disabled
  networkConfig:
    type: String
    default: Enabled
    description: "(Optional) Collect data for Network configurations."
    allowedValues:
    - Enabled
    - Disabled
  windowsUpdates:
    type: String
    default: Enabled
    description: "(Optional) Collect data for all Windows Updates."
    allowedValues:
    - Enabled
    - Disabled
  instanceDetailedInformation:
    type: String
    default: Enabled
    description: "(Optional) Collect additional information about the instance, including
      the CPU model, speed, and the number of cores, to name a few."
    allowedValues:
    - Enabled
    - Disabled
  customInventory:
    type: String
    default: Enabled
    description: "(Optional) Collect data for custom inventory."
    allowedValues:
    - Enabled
    - Disabled
mainSteps:
- action: aws:softwareInventory
  name: collectSoftwareInventoryItems
  inputs:
    applications: "{{ applications }}"
    awsComponents: "{{ awsComponents }}"
    networkConfig: "{{ networkConfig }}"
    windowsUpdates: "{{ windowsUpdates }}"
    instanceDetailedInformation: "{{ instanceDetailedInformation }}"
    customInventory: "{{ customInventory }}"
```

------
#### [ JSON ]

```
{
   "schemaVersion": "2.2",
   "description": "Software Inventory Policy Document.",
   "parameters": {
      "applications": {
         "type": "String",
         "default": "Enabled",
         "description": "(Optional) Collect data for installed applications.",
         "allowedValues": [
            "Enabled",
            "Disabled"
         ]
      },
      "awsComponents": {
         "type": "String",
         "default": "Enabled",
         "description": "(Optional) Collect data for AWS Components like amazon-ssm-agent.",
         "allowedValues": [
            "Enabled",
            "Disabled"
         ]
      },
      "networkConfig": {
         "type": "String",
         "default": "Enabled",
         "description": "(Optional) Collect data for Network configurations.",
         "allowedValues": [
            "Enabled",
            "Disabled"
         ]
      },
      "windowsUpdates": {
         "type": "String",
         "default": "Enabled",
         "description": "(Optional) Collect data for all Windows Updates.",
         "allowedValues": [
            "Enabled",
            "Disabled"
         ]
      },
      "instanceDetailedInformation": {
         "type": "String",
         "default": "Enabled",
         "description": "(Optional) Collect additional information about the instance, including\nthe CPU model, speed, and the number of cores, to name a few.",
         "allowedValues": [
            "Enabled",
            "Disabled"
         ]
      },
      "customInventory": {
         "type": "String",
         "default": "Enabled",
         "description": "(Optional) Collect data for custom inventory.",
         "allowedValues": [
            "Enabled",
            "Disabled"
         ]
      }
   },
   "mainSteps": [
      {
         "action": "aws:softwareInventory",
         "name": "collectSoftwareInventoryItems",
         "inputs": {
            "applications": "{{ applications }}",
            "awsComponents": "{{ awsComponents }}",
            "networkConfig": "{{ networkConfig }}",
            "windowsUpdates": "{{ windowsUpdates }}",
            "instanceDetailedInformation": "{{ instanceDetailedInformation }}",
            "customInventory": "{{ customInventory }}"
         }
      }
   ]
}
```

------

**Schema version 2.2 `AWS-ConfigureAWSPackage` example**  
The following example shows the `AWS-ConfigureAWSPackage` document. The `mainSteps` section includes the `aws:configurePackage` plugin in the `action` step.

**Note**  
On Linux operating systems, only the `AmazonCloudWatchAgent` and `AWSSupport-EC2Rescue` packages are supported.

------
#### [ YAML ]

```
---
schemaVersion: '2.2'
description: 'Install or uninstall the latest version or specified version of an AWS
  package. Available packages include the following: AWSPVDriver, AwsEnaNetworkDriver,
  AwsVssComponents, and AmazonCloudWatchAgent, and AWSSupport-EC2Rescue.'
parameters:
  action:
    description: "(Required) Specify whether or not to install or uninstall the package."
    type: String
    allowedValues:
    - Install
    - Uninstall
  name:
    description: "(Required) The package to install/uninstall."
    type: String
    allowedPattern: "^arn:[a-z0-9][-.a-z0-9]{0,62}:[a-z0-9][-.a-z0-9]{0,62}:([a-z0-9][-.a-z0-9]{0,62})?:([a-z0-9][-.a-z0-9]{0,62})?:package\\/[a-zA-Z][a-zA-Z0-9\\-_]{0,39}$|^[a-zA-Z][a-zA-Z0-9\\-_]{0,39}$"
  version:
    type: String
    description: "(Optional) A specific version of the package to install or uninstall."
mainSteps:
- action: aws:configurePackage
  name: configurePackage
  inputs:
    name: "{{ name }}"
    action: "{{ action }}"
    version: "{{ version }}"
```

------
#### [ JSON ]

```
{
   "schemaVersion": "2.2",
   "description": "Install or uninstall the latest version or specified version of an AWS package. Available packages include the following: AWSPVDriver, AwsEnaNetworkDriver, AwsVssComponents, and AmazonCloudWatchAgent, and AWSSupport-EC2Rescue.",
   "parameters": {
      "action": {
         "description":"(Required) Specify whether or not to install or uninstall the package.",
         "type":"String",
         "allowedValues":[
            "Install",
            "Uninstall"
         ]
      },
      "name": {
         "description": "(Required) The package to install/uninstall.",
         "type": "String",
         "allowedPattern": "^arn:[a-z0-9][-.a-z0-9]{0,62}:[a-z0-9][-.a-z0-9]{0,62}:([a-z0-9][-.a-z0-9]{0,62})?:([a-z0-9][-.a-z0-9]{0,62})?:package\\/[a-zA-Z][a-zA-Z0-9\\-_]{0,39}$|^[a-zA-Z][a-zA-Z0-9\\-_]{0,39}$"
      },
      "version": {
         "type": "String",
         "description": "(Optional) A specific version of the package to install or uninstall."
      }
   },
   "mainSteps":[
      {
         "action": "aws:configurePackage",
         "name": "configurePackage",
         "inputs": {
            "name": "{{ name }}",
            "action": "{{ action }}",
            "version": "{{ version }}"
         }
      }
   ]
}
```

------

## Schema version 1.2
<a name="documents-schema-onex"></a>

The following example shows the top-level elements of a schema version 1.2 document.

```
{
   "schemaVersion":"1.2",
   "description":"A description of the SSM document.",
   "parameters":{
      "parameter 1":{
         "one or more parameter properties"
      },
      "parameter 2":{
         "one or more parameter properties"
      },
      "parameter 3":{
         "one or more parameter properties"
      }
   },
   "runtimeConfig":{
      "plugin 1":{
         "properties":[
            {
               "one or more plugin properties"
            }
         ]
      }
   }
}
```

**Schema version 1.2 `aws:runShellScript` example**  
The following example shows the `AWS-RunShellScript` SSM document. The **runtimeConfig** section includes the `aws:runShellScript` plugin.

```
{
    "schemaVersion":"1.2",
    "description":"Run a shell script or specify the commands to run.",
    "parameters":{
        "commands":{
            "type":"StringList",
            "description":"(Required) Specify a shell script or a command to run.",
            "minItems":1,
            "displayType":"textarea"
        },
        "workingDirectory":{
            "type":"String",
            "default":"",
            "description":"(Optional) The path to the working directory on your instance.",
            "maxChars":4096
        },
        "executionTimeout":{
            "type":"String",
            "default":"3600",
            "description":"(Optional) The time in seconds for a command to complete before it is considered to have failed. Default is 3600 (1 hour). Maximum is 172800 (48 hours).",
            "allowedPattern":"([1-9][0-9]{0,3})|(1[0-9]{1,4})|(2[0-7][0-9]{1,3})|(28[0-7][0-9]{1,2})|(28800)"
        }
    },
    "runtimeConfig":{
        "aws:runShellScript":{
            "properties":[
                {
                    "id":"0.aws:runShellScript",
                    "runCommand":"{{ commands }}",
                    "workingDirectory":"{{ workingDirectory }}",
                    "timeoutSeconds":"{{ executionTimeout }}"
                }
            ]
        }
    }
}
```

## Schema version 0.3
<a name="automation-doc-syntax-examples"></a>

**Top-level elements**  
The following example shows the top-level elements of a schema version 0.3 Automation runbook in JSON format.

```
{
    "description": "document-description",
    "schemaVersion": "0.3",
    "assumeRole": "{{assumeRole}}",
    "parameters": {
        "parameter1": {
            "type": "String",
            "description": "parameter-1-description",
            "default": ""
        },
        "parameter2": {
            "type": "String",
            "description": "parameter-2-description",
            "default": ""
        }
    },
    "variables": {
        "variable1": {
            "type": "StringMap",
            "description": "variable-1-description",
            "default": {}
        },
        "variable2": {
            "type": "String",
            "description": "variable-2-description",
            "default": "default-value"
        }
    },
    "mainSteps": [
        {
            "name": "myStepName",
            "action": "action-name",
            "maxAttempts": 1,
            "inputs": {
                "Handler": "python-only-handler-name",
                "Runtime": "runtime-name",
                "Attachment": "script-or-zip-name"
            },
            "outputs": {
                "Name": "output-name",
                "Selector": "selector.value",
                "Type": "data-type"
            }
        }
    ],
    "files": {
        "script-or-zip-name": {
            "checksums": {
                "sha256": "checksum"
            },
            "size": 1234
        }
    }
}
```

**YAML Automation runbook example**  
The following sample shows the contents of an Automation runbook, in YAML format. This working example of version 0.3 of the document schema also demonstrates the use of Markdown to format document descriptions.

```
description: >-
  ##Title: LaunchInstanceAndCheckState

  -----

  **Purpose**: This Automation runbook first launches an EC2 instance
  using the AMI ID provided in the parameter ```imageId```. The second step of
  this document continuously checks the instance status check value for the
  launched instance until the status ```ok``` is returned.


  ##Parameters:

  -----

  Name | Type | Description | Default Value

  ------------- | ------------- | ------------- | -------------

  assumeRole | String | (Optional) The ARN of the role that allows Automation to
  perform the actions on your behalf. | -

  imageId  | String | (Optional) The AMI ID to use for launching the instance.
  The default value uses the latest Amazon Linux AMI ID available. | {{
  ssm:/aws/service/ami-amazon-linux-latest/al2023-ami-kernel-6.1-x86_64 }}
schemaVersion: '0.3'
assumeRole: 'arn:aws:iam::111122223333::role/AutomationServiceRole'
parameters:
  imageId:
    type: String
    default: '{{ ssm:/aws/service/ami-amazon-linux-latest/al2023-ami-kernel-6.1-x86_64 }}'
    description: >-
      (Optional) The AMI ID to use for launching the instance. The default value
      uses the latest released Amazon Linux AMI ID.
  tagValue:
    type: String
    default: ' LaunchedBySsmAutomation'
    description: >-
      (Optional) The tag value to add to the instance. The default value is
      LaunchedBySsmAutomation.
  instanceType:
    type: String
    default: t2.micro
    description: >-
      (Optional) The instance type to use for the instance. The default value is
      t2.micro.
mainSteps:
  - name: LaunchEc2Instance
    action: 'aws:executeScript'
    outputs:
      - Name: payload
        Selector: $.Payload
        Type: StringMap
    inputs:
      Runtime: python3.11
      Handler: launch_instance
      Script: ''
      InputPayload:
        image_id: '{{ imageId }}'
        tag_value: '{{ tagValue }}'
        instance_type: '{{ instanceType }}'
      Attachment: launch.py
    description: >-
      **About This Step**


      This step first launches an EC2 instance using the ```aws:executeScript```
      action and the provided python script.
  - name: WaitForInstanceStatusOk
    action: 'aws:executeScript'
    inputs:
      Runtime: python3.11
      Handler: poll_instance
      Script: |-
        def poll_instance(events, context):
          import boto3
          import time

          ec2 = boto3.client('ec2')

          instance_id = events['InstanceId']

          print('[INFO] Waiting for instance status check to report ok', instance_id)

          instance_status = "null"

          while True:
            res = ec2.describe_instance_status(InstanceIds=[instance_id])

            if len(res['InstanceStatuses']) == 0:
              print("Instance status information is not available yet")
              time.sleep(5)
              continue

            instance_status = res['InstanceStatuses'][0]['InstanceStatus']['Status']

            print('[INFO] Polling to get status of the instance', instance_status)

            if instance_status == 'ok':
              break

            time.sleep(10)

          return {'Status': instance_status, 'InstanceId': instance_id}
      InputPayload: '{{ LaunchEc2Instance.payload }}'
    description: >-
      **About This Step**


      The python script continuously polls the instance status check value for
      the instance launched in Step 1 until the ```ok``` status is returned.
files:
  launch.py:
    checksums:
      sha256: 18871b1311b295c43d0f...[truncated]...772da97b67e99d84d342ef4aEXAMPLE
```

## Secure parameter handling examples
<a name="secure-parameter-examples"></a>

The following examples demonstrate secure parameter handling using environment variable `interpolationType`.

### Basic secure command execution
<a name="basic-secure-command"></a>

This example shows how to securely handle a command parameter:

**Note**  
`allowedPattern` isn’t technically required in SSM documents that don’t use double braces: `{{ }}` 

------
#### [ YAML ]

```
---

schemaVersion: '2.2'
description: An example document.
parameters:
  Message:
    type: String
    description: "Message to be printed"
    default: Hello
    interpolationType: ENV_VAR
    allowedPattern: "^[^"]*$"
mainSteps:
  - action: aws:runShellScript
    name: printMessage
    precondition:
      StringEquals:
        - platformType
        - Linux
    inputs:
      runCommand:
        - echo {{Message}}
```

------
#### [ JSON ]

```
{
    "schemaVersion": "2.2",
    "description": "An example document.",
    "parameters": {
        "Message": {
            "type": "String",
            "description": "Message to be printed",
            "default": "Hello",
            "interpolationType": "ENV_VAR",
            "allowedPattern": "^[^"]*$"
        }
    },
    "mainSteps": [{
        "action": "aws:runShellScript",
        "name": "printMessage",
        "precondition": {
           "StringEquals": ["platformType", "Linux"]
        },
        "inputs": {
            "runCommand": [
              "echo {{Message}}"
            ]
        }
    }]
}
```

------

### Using parameters in interpreted languages
<a name="interpreted-language-example"></a>

This example demonstrates secure parameter handling in Python:

------
#### [ YAML ]

```
---
schemaVersion: '2.2'
description: 'Secure Python script execution'
parameters:
  inputData:
    type: String
    description: 'Input data for processing'
    interpolationType: 'ENV_VAR'
mainSteps:
  - action: aws:runPowerShellScript
    name: runPython
    inputs:
      runCommand:
        - |
          python3 -c '
          import os
          import json
          
          # Safely access parameter through environment variable
          input_data = os.environ.get("SSM_inputData", "")
          
          # Process the data
          try:
              processed_data = json.loads(input_data)
              print(f"Successfully processed: {processed_data}")
          except json.JSONDecodeError:
              print("Invalid JSON input")
          '
```

------

### Backwards compatibility example
<a name="backwards-compatibility-example"></a>

This example shows how to handle parameters securely while maintaining backwards compatibility:

------
#### [ YAML ]

```
---
schemaVersion: '2.2'
description: 'Backwards compatible secure parameter handling'
parameters:
  userInput:
    type: String
    description: 'User input to process'
    interpolationType: 'ENV_VAR'
    allowedPattern: '^[^"]*$'

mainSteps:
  - action: aws:runShellScript
    name: processInput
    inputs:
      runCommand:
        - |
          # Handle both modern and legacy agent versions
          if [ -z "${SSM_userInput+x}" ]; then
              # Legacy agent - fall back to direct parameter reference
              export SSM_userInput="{{userInput}}"
          fi
          
          # Process the input securely
          echo "Processing input: $SSM_userInput"
```

------

**Note**  
`allowedPattern` isn’t technically required in SSM documents that don’t use double braces: `{{ }}` 

## Parameter security best practices
<a name="parameter-security-best-practices"></a>

Follow these best practices when handling parameters in SSM documents:
+ **Use environment variable interpolation** - Always use `interpolationType: "ENV_VAR"` for string parameters that will be used in command execution.
+ **Implement input validation** - Use `allowedPattern` to restrict parameter values to safe patterns.
+ **Handle legacy systems** - Include fallback logic for older SSM Agent versions that don't support environment variable interpolation.
+ **Escape special characters** - When using parameter values in commands, properly escape special characters to prevent interpretation by the shell.
+ **Limit parameter scope** - Use the most restrictive parameter patterns possible for your use case.

# Data elements and parameters
<a name="documents-syntax-data-elements-parameters"></a>

This topic describes the data elements used in SSM documents. The schema version used to create a document defines the syntax and data elements that the document accepts. We recommend that you use schema version 2.2 or later for Command documents. Automation runbooks use schema version 0.3. Additionally, Automation runbooks support the use of Markdown, a markup language, which allows you to add wiki-style descriptions to documents and individual steps within the document. For more information about using Markdown, see [Using Markdown in the Console](https://docs.aws.amazon.com/general/latest/gr/aws-markdown.html) in the *AWS Management Console Getting Started Guide*.

The following section describes the data elements that you can include in a SSM document.

## Top-level data elements
<a name="top-level"></a>

**schemaVersion**  
The schema version to use.  
Type: Version  
Required: Yes

**description**  
Information you provide to describe the purpose of the document. You can also use this field to specify whether a parameter requires a value for a document to run, or if providing a value for the parameter is optional. Required and optional parameters can be seen in the examples throughout this topic.  
Type: String  
Required: No

**parameters**  
A structure that defines the parameters the document accepts.   
For enhanced security when handling string parameters, you can use environment variable interpolation by specifying the `interpolationType` property. When set to `ENV_VAR`, the system creates an environment variable named `SSM_parameter-name` containing the parameter value.  
The following includes an example of a parameter using environment variable `interpolationType`:  

```
{
    "schemaVersion": "2.2",
    "description": "An example document.",
    "parameters": {
        "Message": {
            "type": "String",
            "description": "Message to be printed",
            "default": "Hello",
            "interpolationType" : "ENV_VAR",
            "allowedPattern": "^[^"]*$"

        }
    },
    "mainSteps": [{
        "action": "aws:runShellScript",
        "name": "printMessage",
        "precondition" : {
           "StringEquals" : ["platformType", "Linux"]
        },
        "inputs": {
            "runCommand": [
              "echo {{Message}}"
            ]
        }
    }
}
```
`allowedPattern` isn’t technically required in SSM documents that don’t use double braces: `{{ }}` 
For parameters that you use often, we recommend that you store those parameters in Parameter Store, a tool in AWS Systems Manager. Then, you can define parameters in your document that reference Parameter Store parameters as their default value. To reference a Parameter Store parameter, use the following syntax.   

```
{{ssm:parameter-name}}
```
You can use a parameter that references a Parameter Store parameter the same way as any other document parameters. In the following example, the default value for the `commands` parameter is the Parameter Store parameter `myShellCommands`. By specifying the `commands` parameter as a `runCommand` string, the document runs the commands stored in the `myShellCommands` parameter.  

```
---
schemaVersion: '2.2'
description: runShellScript with command strings stored as Parameter Store parameter
parameters:
  commands:
    type: StringList
    description: "(Required) The commands to run on the instance."
    default: ["{{ ssm:myShellCommands }}"],
            interpolationType : 'ENV_VAR'
            allowedPattern: '^[^"]*$'

mainSteps:
- action: aws:runShellScript
  name: runShellScriptDefaultParams
  inputs:
    runCommand:"{{ commands }}"
```

```
{
    "schemaVersion": "2.2",
    "description": "runShellScript with command strings stored as Parameter Store parameter",
    "parameters": {
      "commands": {
        "type": "StringList",
        "description": "(Required) The commands to run on the instance.",
        "default": ["{{ ssm:myShellCommands }}"],
        "interpolationType" : "ENV_VAR"
      }
    },
    "mainSteps": [
      {
        "action": "aws:runShellScript",
        "name": "runShellScriptDefaultParams",
        "inputs": {
            "runCommand": [
              "{{ commands }}"
          ]
        }
      }
    ]
  }
```
You can reference `String` and `StringList` Parameter Store parameters in the `parameters` section of your document. You can't reference `SecureString` Parameter Store parameters.
For more information about Parameter Store, see [AWS Systems Manager Parameter Store](systems-manager-parameter-store.md).  
Type: Structure  
The `parameters` structure accepts the following fields and values:  
+ `type`: (Required) Allowed values include the following: `String`, `StringList`, `Integer` `Boolean`, `MapList`, and `StringMap`. To view examples of each type, see [SSM document parameter `type` examples](#top-level-properties-type) in the next section.
**Note**  
Command type documents only support the `String` and `StringList` parameter types.
+ `description`: (Optional) A description of the parameter.
+ `default`: (Optional) The default value of the parameter or a reference to a parameter in Parameter Store.
+ `allowedValues`: (Optional) An array of values allowed for the parameter. Defining allowed values for the parameter validates the user input. If a user inputs a value that isn't allowed, the execution fails to start.

------
#### [ YAML ]

  ```
  DirectoryType:
    type: String
    description: "(Required) The directory type to launch."
    default: AwsMad
    allowedValues:
    - AdConnector
    - AwsMad
    - SimpleAd
  ```

------
#### [ JSON ]

  ```
  "DirectoryType": {
    "type": "String",
    "description": "(Required) The directory type to launch.",
    "default": "AwsMad",
    "allowedValues": [
      "AdConnector",
      "AwsMad",
      "SimpleAd"
    ]
  }
  ```

------
+ `allowedPattern`: (Optional) A regular expression that validates whether the user input matches the defined pattern for the parameter. If the user input doesn't match the allowed pattern, the execution fails to start.
**Note**  
Systems Manager performs two validations for `allowedPattern`. The first validation is performed using the [Java regex library](https://docs.oracle.com/javase/8/docs/api/java/util/regex/package-summary.html) at the API level when you use a document. The second validation is performed on SSM Agent by using the [GO regexp library](https://pkg.go.dev/regexp) before processing the document. 

------
#### [ YAML ]

  ```
  InstanceId:
    type: String
    description: "(Required) The instance ID to target."
    allowedPattern: "^i-(?:[a-f0-9]{8}|[a-f0-9]{17})$"
    default: ''
  ```

------
#### [ JSON ]

  ```
  "InstanceId": {
    "type": "String",
    "description": "(Required) The instance ID to target.",
    "allowedPattern": "^i-(?:[a-f0-9]{8}|[a-f0-9]{17})$",
    "default": ""
  }
  ```

------
+ `displayType`: (Optional) Used to display either a `textfield` or a `textarea` in the AWS Management Console. `textfield` is a single-line text box. `textarea` is a multi-line text area.
+ `minItems`: (Optional) The minimum number of items allowed.
+ `maxItems`: (Optional) The maximum number of items allowed.
+ `minChars`: (Optional) The minimum number of parameter characters allowed.
+ `maxChars`: (Optional) The maximum number of parameter characters allowed.
+ `interpolationType`: (Optional) Defines how parameter values are processed before command execution. When set to `ENV_VAR`, the parameter value is made available as an environment variable named `SSM_parameter-name`. This feature helps prevent command injection by treating parameter values as literal strings.

  Type: String

  Valid values: `ENV_VAR`
Required: No

**variables**  
(Schema version 0.3 only) Values you can reference or update throughout the steps in an Automation runbook. Variables are similar to parameters, but differ in a very important way. Parameter values are static in the context of a runbook, but the values of variables can be changed in the context of the runbook. When updating the value of a variable, the data type must match the defined data type. For information about updating variables values in an automation, see [`aws:updateVariable` – Updates a value for a runbook variable](automation-action-update-variable.md)  
Type: Boolean \$1 Integer \$1 MapList \$1 String \$1 StringList \$1 StringMap  
Required: No  

```
variables:
    payload:
        type: StringMap
        default: "{}"
```

```
{
    "variables": [
        "payload": {
            "type": "StringMap",
            "default": "{}"
        }
    ]
}
```

**runtimeConfig**  
(Schema version 1.2 only) The configuration for the instance as applied by one or more Systems Manager plugins. Plugins aren't guaranteed to run in sequence.   
Type: Dictionary<string,PluginConfiguration>  
Required: No

**mainSteps**  
(Schema version 0.3, 2.0, and 2.2 only) An object that can include multiple steps (plugins). Plugins are defined within steps. Steps run in sequential order as listed in the document.   
Type: Dictionary<string,PluginConfiguration>  
Required: Yes

**outputs**  
(Schema version 0.3 only) Data generated by the execution of this document that can be used in other processes. For example, if your document creates a new AMI, you might specify "CreateImage.ImageId" as the output value, and then use this output to create new instances in a subsequent automation execution. For more information about outputs, see [Using action outputs as inputs](automation-action-outputs-inputs.md).  
Type: Dictionary<string,OutputConfiguration>  
Required: No

**files**  
(Schema version 0.3 only) The script files (and their checksums) attached to the document and run during an automation execution. Applies only to documents that include the `aws:executeScript` action and for which attachments have been specified in one or more steps.   
To learn about the runtimes supported by Automation runbooks, see [`aws:executeScript` – Run a script](automation-action-executeScript.md). For more information about including scripts in Automation runbooks, see [Using scripts in runbooks](automation-document-script-considerations.md) and [Visual design experience for Automation runbooks](automation-visual-designer.md).  
When creating an Automation runbook with attachments, you must also specify attachment files using the `--attachments` option (for AWS CLI) or `Attachments` (for API and SDK). You can specify the file location for SSM documents and files stored in Amazon Simple Storage Service (Amazon S3) buckets. For more information, see [Attachments](https://docs.aws.amazon.com/systems-manager/latest/APIReference/API_CreateDocument.html#systemsmanager-CreateDocument-request-Attachments) in the AWS Systems Manager API Reference.  

```
---
files:
  launch.py:
    checksums:
      sha256: 18871b1311b295c43d0f...[truncated]...772da97b67e99d84d342ef4aEXAMPLE
```

```
"files": {
    "launch.py": {
        "checksums": {
            "sha256": "18871b1311b295c43d0f...[truncated]...772da97b67e99d84d342ef4aEXAMPLE"
        }
    }
}
```
Type: Dictionary<string,FilesConfiguration>  
Required: No

## SSM document parameter `type` examples
<a name="top-level-properties-type"></a>

Parameter types in SSM documents are static. This means the parameter type can't be changed after it's defined. When using parameters with SSM document plugins, the type of a parameter can't be dynamically changed within a plugin's input. For example, you can't reference an `Integer` parameter within the `runCommand` input of the `aws:runShellScript` plugin because this input accepts a string or list of strings. To use a parameter for a plugin input, the parameter type must match the accepted type. For example, you must specify a `Boolean` type parameter for the `allowDowngrade` input of the `aws:updateSsmAgent` plugin. If your parameter type doesn't match the input type for a plugin, the SSM document fails to validate and the system doesn't create the document. This is also true when using parameters downstream within inputs for other plugins or AWS Systems Manager Automation actions. For example, you can't reference a `StringList` parameter within the `documentParameters` input of the `aws:runDocument` plugin. The `documentParameters` input accepts a map of strings even if the downstream SSM document parameter type is a `StringList` parameter and matches the parameter you're referencing.

When using parameters with Automation actions, parameter types aren't validated when you create the SSM document in most cases. Only when you use the `aws:runCommand` action are parameter types validated when you create the SSM document. In all other cases, the parameter validation occurs during the automation execution when an action's input is verified before running the action. For example, if your input parameter is a `String` and you reference it as the value for the `MaxInstanceCount` input of the `aws:runInstances` action, the SSM document is created. However, when running the document, the automation fails while validating the `aws:runInstances` action because the `MaxInstanceCount` input requires an `Integer`.

The following are examples of each parameter `type`.

String  
A sequence of zero or more Unicode characters wrapped in quotation marks. For example, "i-1234567890abcdef0". Use backslashes to escape.  
String parameters can include an optional `interpolationType` field with the value `ENV_VAR` to enable environment variable interpolation for improved security.  

```
---
InstanceId:
  type: String
  description: "(Optional) The target EC2 instance ID."
  interpolationType: ENV_VAR
```

```
"InstanceId":{
  "type":"String",
  "description":"(Optional) The target EC2 instance ID.",
  "interpolationType": "ENV_VAR"
}
```

StringList  
A list of String items separated by commas. For example, ["cd \$1", "pwd"].  

```
---
commands:
  type: StringList
  description: "(Required) Specify a shell script or a command to run."
  default: ""
  minItems: 1
  displayType: textarea
```

```
"commands":{
  "type":"StringList",
  "description":"(Required) Specify a shell script or a command to run.",
  "minItems":1,
  "displayType":"textarea"
}
```

Boolean  
Accepts only `true` or `false`. Doesn't accept "true" or 0.  

```
---
canRun:
  type: Boolean
  description: ''
  default: true
```

```
"canRun": {
  "type": "Boolean",
  "description": "",
  "default": true
}
```

Integer  
Integral numbers. Doesn't accept decimal numbers, for example 3.14159, or numbers wrapped in quotation marks, for example "3".  

```
---
timeout:
  type: Integer
  description: The type of action to perform.
  default: 100
```

```
"timeout": {
  "type": "Integer",
  "description": "The type of action to perform.",
  "default": 100    
}
```

StringMap  
A mapping of keys to values. Keys and values must be strings. For example, \$1"Env": "Prod"\$1.  

```
---
notificationConfig:
  type: StringMap
  description: The configuration for events to be notified about
  default:
    NotificationType: 'Command'
    NotificationEvents:
    - 'Failed'
    NotificationArn: "$dependency.topicArn"
  maxChars: 150
```

```
"notificationConfig" : {
  "type" : "StringMap",
  "description" : "The configuration for events to be notified about",
  "default" : {
    "NotificationType" : "Command",
    "NotificationEvents" : ["Failed"],
    "NotificationArn" : "$dependency.topicArn"
  },
  "maxChars" : 150
}
```

MapList  
A list of StringMap objects.  

```
blockDeviceMappings:
  type: MapList
  description: The mappings for the create image inputs
  default:
  - DeviceName: "/dev/sda1"
    Ebs:
      VolumeSize: "50"
  - DeviceName: "/dev/sdm"
    Ebs:
      VolumeSize: "100"
  maxItems: 2
```

```
"blockDeviceMappings":{
  "type":"MapList",
  "description":"The mappings for the create image inputs",
  "default":[
    {
      "DeviceName":"/dev/sda1",
      "Ebs":{
        "VolumeSize":"50"
      }
    },
    {
      "DeviceName":"/dev/sdm",
      "Ebs":{
        "VolumeSize":"100"
      }
    }
  ],
  "maxItems":2
}
```

## Viewing SSM Command document content
<a name="viewing-ssm-document-content"></a>

To preview the required and optional parameters for an AWS Systems Manager (SSM) Command document, in addition to the actions the document runs, you can view the content of the document in the Systems Manager console.

**To view SSM Command document content**

1. Open the AWS Systems Manager console at [https://console.aws.amazon.com/systems-manager/](https://console.aws.amazon.com/systems-manager/).

1. In the navigation pane, choose **Documents**.

1. In the search box, select **Document type**, and then select **Command**.

1. Choose the name of a document, and then choose the **Content** tab. 

1. In the content field, review the available parameters and action steps for the document.

   For example, the following image shows that (1) `version` and (2) `allowDowngrade` are optional parameters for the `AWS-UpdateSSMAgent` document, and that the first action run by the document is (3) `aws:updateSsmAgent`.  
![\[View SSM document content in the Systems Manager console\]](http://docs.aws.amazon.com/systems-manager/latest/userguide/images/view-document-content.png)

# Command document plugin reference
<a name="documents-command-ssm-plugin-reference"></a>

This reference describes the plugins that you can specify in an AWS Systems Manager (SSM) Command type document. These plugins can't be used in SSM Automation runbooks, which use Automation actions. For information about AWS Systems Manager Automation actions, see [Systems Manager Automation actions reference](automation-actions.md).

Systems Manager determines the actions to perform on a managed instance by reading the contents of an SSM document. Each document includes a code-execution section. Depending on the schema version of your document, this code-execution section can include one or more plugins or steps. For the purpose of this Help topic, plugins and steps are called *plugins*. This section includes information about each of the Systems Manager plugins. For more information about documents, including information about creating documents and the differences between schema versions, see [AWS Systems Manager Documents](documents.md).

For plugins that accept String parameters, such as `aws:runShellScript` and `aws:runPowerShellScript`, the `interpolationType` parameter can be used to enhance security by treating parameter inputs as string literals rather than potentially executable commands. For example:

```
{
    "schemaVersion": "2.2",
    "description": "runShellScript with command strings stored as Parameter Store parameter",
    "parameters": {
      "commands": {
        "type": "StringList",
        "description": "(Required) The commands to run on the instance.",
        "default": ["{{ ssm:myShellCommands }}"],
        "interpolationType" : "ENV_VAR"
      }
    },
    //truncated
 }
```

**Note**  
Some of the plugins described here run only on either Windows Server instances or Linux instances. Platform dependencies are noted for each plugin.   
The following document plugins are supported on Amazon Elastic Compute Cloud (Amazon EC2) instances for macOS:  
`aws:refreshAssociation`
`aws:runShellScript`
`aws:runPowerShellScript`
`aws:softwareInventory`
`aws:updateSsmAgent`

**Topics**
+ [Shared inputs](#shared-inputs)
+ [`aws:applications`](#aws-applications)
+ [`aws:cloudWatch`](#aws-cloudWatch)
+ [`aws:configureDocker`](#aws-configuredocker)
+ [`aws:configurePackage`](#aws-configurepackage)
+ [`aws:domainJoin`](#aws-domainJoin)
+ [`aws:downloadContent`](#aws-downloadContent)
+ [`aws:psModule`](#aws-psModule)
+ [`aws:refreshAssociation`](#aws-refreshassociation)
+ [`aws:runDockerAction`](#aws-rundockeraction)
+ [`aws:runDocument`](#aws-rundocument)
+ [`aws:runPowerShellScript`](#aws-runPowerShellScript)
+ [`aws:runShellScript`](#aws-runShellScript)
+ [`aws:softwareInventory`](#aws-softwareinventory)
+ [`aws:updateAgent`](#aws-updateagent)
+ [`aws:updateSsmAgent`](#aws-updatessmagent)

## Shared inputs
<a name="shared-inputs"></a>

With SSM Agent version 3.0.502 and later only, all plugins can use the following inputs:

**finallyStep**  
The last step you want the document to run. If this input is defined for a step, it takes precedence over an `exit` value specified in the `onFailure` or `onSuccess` inputs. In order for a step with this input to run as expected, the step must be the last one defined in the `mainSteps` of your document.  
Type: Boolean  
Valid values: `true` \$1 `false`  
Required: No

**onFailure**  
If you specify this input for a plugin with the `exit` value and the step fails, the step status reflects the failure and the document doesn't run any remaining steps unless a `finallyStep` has been defined. If you specify this input for a plugin with the `successAndExit` value and the step fails, the step status shows successful and the document doesn't run any remaining steps unless a `finallyStep` has been defined.  
Type: String  
Valid values: `exit` \$1 `successAndExit`  
Required: No

**onSuccess**  
If you specify this input for a plugin and the step runs successfully, the document doesn't run any remaining steps unless a `finallyStep` has been defined.  
Type: String  
Valid values: `exit`  
Required: No

------
#### [ YAML ]

```
---
schemaVersion: '2.2'
description: Shared inputs example
parameters:
  customDocumentParameter:
    type: String
    description: Example parameter for a custom Command-type document.
mainSteps:
- action: aws:runDocument
  name: runCustomConfiguration
  inputs:
    documentType: SSMDocument
    documentPath: "yourCustomDocument"
    documentParameters: '"documentParameter":{{customDocumentParameter}}'
    onSuccess: exit
- action: aws:runDocument
  name: ifConfigurationFailure
  inputs:
    documentType: SSMDocument
    documentPath: "yourCustomRepairDocument"
    onFailure: exit
- action: aws:runDocument
  name: finalConfiguration
  inputs:
    documentType: SSMDocument
    documentPath: "yourCustomFinalDocument"
    finallyStep: true
```

------
#### [ JSON ]

```
{
   "schemaVersion": "2.2",
   "description": "Shared inputs example",
   "parameters": {
      "customDocumentParameter": {
         "type": "String",
         "description": "Example parameter for a custom Command-type document."
      }
   },
   "mainSteps":[
      {
         "action": "aws:runDocument",
         "name": "runCustomConfiguration",
         "inputs": {
            "documentType": "SSMDocument",
            "documentPath": "yourCustomDocument",
            "documentParameters": "\"documentParameter\":{{customDocumentParameter}}",
            "onSuccess": "exit"
         }
      },
      {
         "action": "aws:runDocument",
         "name": "ifConfigurationFailure",
         "inputs": {
            "documentType": "SSMDocument",
            "documentPath": "yourCustomRepairDocument",
            "onFailure": "exit"
         }
      },
      {
         "action": "aws:runDocument",
         "name":"finalConfiguration",
         "inputs": {
            "documentType": "SSMDocument",
            "documentPath": "yourCustomFinalDocument",
            "finallyStep": true
         }
      }
   ]
}
```

------

## `aws:applications`
<a name="aws-applications"></a>

Install, repair, or uninstall applications on an EC2 instance. This plugin only runs on Windows Server operating systems.

### Syntax
<a name="applications-syntax"></a>

#### Schema 2.2
<a name="applications-syntax-2.2"></a>

------
#### [ YAML ]

```
---
schemaVersion: '2.2'
description: aws:applications plugin
parameters:
  source:
    description: "(Required) Source of msi."
    type: String
mainSteps:
- action: aws:applications
  name: example
  inputs:
    action: Install
    source: "{{ source }}"
```

------
#### [ JSON ]

```
{
  "schemaVersion":"2.2",
  "description":"aws:applications",
  "parameters":{
    "source":{
    "description":"(Required) Source of msi.",
    "type":"String"
    }
  },
  "mainSteps":[
    {
      "action":"aws:applications",
      "name":"example",
      "inputs":{
        "action":"Install",
        "source":"{{ source }}"
      }
    }
  ]
}
```

------

#### Schema 1.2
<a name="applications-syntax-1.2"></a>

------
#### [ YAML ]

```
---
runtimeConfig:
  aws:applications:
    properties:
    - id: 0.aws:applications
      action: "{{ action }}"
      parameters: "{{ parameters }}"
      source: "{{ source }}"
      sourceHash: "{{ sourceHash }}"
```

------
#### [ JSON ]

```
{
   "runtimeConfig":{
      "aws:applications":{
         "properties":[
            {
               "id":"0.aws:applications",
               "action":"{{ action }}",
               "parameters":"{{ parameters }}",
               "source":"{{ source }}",
               "sourceHash":"{{ sourceHash }}"
            }
         ]
      }
   }
}
```

------

### Properties
<a name="applications-properties"></a>

**action**  
The action to take.  
Type: Enum  
Valid values: `Install` \$1 `Repair` \$1 `Uninstall`  
Required: Yes

**parameters**  
The parameters for the installer.  
Type: String  
Required: No

**source**  
The URL of the `.msi` file for the application.  
Type: String  
Required: Yes

**sourceHash**  
The SHA256 hash of the `.msi` file.  
Type: String  
Required: No

## `aws:cloudWatch`
<a name="aws-cloudWatch"></a>

Export data from Windows Server to Amazon CloudWatch or Amazon CloudWatch Logs and monitor the data using CloudWatch metrics. This plugin only runs on Windows Server operating systems. For more information about configuring CloudWatch integration with Amazon Elastic Compute Cloud (Amazon EC2), see [Collecting metrics, logs, and traces with the CloudWatch agent](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/Install-CloudWatch-Agent.html) in the *Amazon CloudWatch User Guide*.

**Important**  
The unified CloudWatch agent has replaced SSM Agent as the tool for sending log data to Amazon CloudWatch Logs. The SSM Agent aws:cloudWatch plugin is not supported. We recommend using only the unified CloudWatch agent for your log collection processes. For more information, see the following topics:  
[Sending node logs to unified CloudWatch Logs (CloudWatch agent)](monitoring-cloudwatch-agent.md)
[Migrate Windows Server node log collection to the CloudWatch agent](monitoring-cloudwatch-agent.md#monitoring-cloudwatch-agent-migrate)
[Collecting metrics, logs, and traces with the CloudWatch agent](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/Install-CloudWatch-Agent.html) in the *Amazon CloudWatch User Guide*.

You can export and monitor the following data types:

**ApplicationEventLog**  
Sends application event log data to CloudWatch Logs.

**CustomLogs**  
Sends any text-based log file to Amazon CloudWatch Logs. The CloudWatch plugin creates a fingerprint for log files. The system then associates a data offset with each fingerprint. The plugin uploads files when there are changes, records the offset, and associates the offset with a fingerprint. This method is used to avoid a situation where a user turns on the plugin, associates the service with a directory that contains a large number of files, and the system uploads all of the files.  
Be aware that if your application truncates or attempts to clean logs during polling, any logs specified for `LogDirectoryPath` can lose entries. If, for example, you want to limit log file size, create a new log file when that limit is reached, and then continue writing data to the new file.

**ETW**  
Sends Event Tracing for Windows (ETW) data to CloudWatch Logs.

**IIS**  
Sends IIS log data to CloudWatch Logs.

**PerformanceCounter**  
Sends Windows performance counters to CloudWatch. You can select different categories to upload to CloudWatch as metrics. For each performance counter that you want to upload, create a **PerformanceCounter** section with a unique ID (for example, "PerformanceCounter2", "PerformanceCounter3", and so on) and configure its properties.  
If the AWS Systems Manager SSM Agent or the CloudWatch plugin is stopped, performance counter data isn't logged in CloudWatch. This behavior is different than custom logs or Windows Event logs. Custom logs and Windows Event logs preserve performance counter data and upload it to CloudWatch after SSM Agent or the CloudWatch plugin is available.

**SecurityEventLog**  
Sends security event log data to CloudWatch Logs.

**SystemEventLog**  
Sends system event log data to CloudWatch Logs.

You can define the following destinations for the data:

**CloudWatch**  
The destination where your performance counter metric data is sent. You can add more sections with unique IDs (for example, "CloudWatch2", CloudWatch3", and so on), and specify a different Region for each new ID to send the same data to different locations.

**CloudWatchLogs**  
The destination where your log data is sent. You can add more sections with unique IDs (for example, "CloudWatchLogs2", CloudWatchLogs3", and so on), and specify a different Region for each new ID to send the same data to different locations.

### Syntax
<a name="cloudWatch-syntax"></a>

```
"runtimeConfig":{
        "aws:cloudWatch":{
            "settings":{
                "startType":"{{ status }}"
            },
            "properties":"{{ properties }}"
        }
    }
```

### Settings and properties
<a name="cloudWatch-properties"></a>

**AccessKey**  
Your access key ID. This property is required unless you launched your instance using an IAM role. This property can't be used with SSM.  
Type: String  
Required: No

**CategoryName**  
The performance counter category from Performance Monitor.  
Type: String  
Required: Yes

**CounterName**  
The name of the performance counter from Performance Monitor.  
Type: String  
Required: Yes

**CultureName**  
The locale where the timestamp is logged. If **CultureName** is blank, it defaults to the same locale used by your Windows Server instance.  
Type: String  
Valid values: For a list of supported values, see [National Language Support (NLS)](https://msdn.microsoft.com/en-us/library/cc233982.aspx) on the Microsoft website. The **div**, **div-MV**, **hu**, and **hu-HU** values aren't supported.  
Required: No

**DimensionName**  
A dimension for your Amazon CloudWatch metric. If you specify `DimensionName`, you must specify `DimensionValue`. These parameters provide another view when listing metrics. You can use the same dimension for multiple metrics so that you can view all metrics belonging to a specific dimension.  
Type: String  
Required: No

**DimensionValue**  
A dimension value for your Amazon CloudWatch metric.  
Type: String  
Required: No

**Encoding**  
The file encoding to use (for example, UTF-8). Use the encoding name, not the display name.  
Type: String  
Valid values: For a list of supported values, see [Encoding Class](https://learn.microsoft.com/en-us/dotnet/api/system.text.encoding?view=net-7.0) in the Microsoft Learn Library.  
Required: Yes

**Filter**  
The prefix of log names. Leave this parameter blank to monitor all files.  
Type: String  
Valid values: For a list of supported values, see the [FileSystemWatcherFilter Property](http://msdn.microsoft.com/en-us/library/system.io.filesystemwatcher.filter.aspx) in the MSDN Library.  
Required: No

**Flows**  
Each data type to upload, along with the destination for the data (CloudWatch or CloudWatch Logs). For example, to send a performance counter defined under `"Id": "PerformanceCounter"` to the CloudWatch destination defined under `"Id": "CloudWatch"`, enter **"PerformanceCounter,CloudWatch"**. Similarly, to send the custom log, ETW log, and system log to the CloudWatch Logs destination defined under `"Id": "ETW"`, enter **"(ETW),CloudWatchLogs"**. In addition, you can send the same performance counter or log file to more than one destination. For example, to send the application log to two different destinations that you defined under `"Id": "CloudWatchLogs"` and `"Id": "CloudWatchLogs2"`, enter **"ApplicationEventLog,(CloudWatchLogs, CloudWatchLogs2)"**.  
Type: String  
Valid values (source): `ApplicationEventLog` \$1 `CustomLogs` \$1 `ETW` \$1 `PerformanceCounter` \$1 `SystemEventLog` \$1 `SecurityEventLog`   
Valid values (destination): `CloudWatch` \$1 `CloudWatchLogs` \$1 `CloudWatch`*n* \$1 `CloudWatchLogs`*n*   
Required: Yes

**FullName**  
The full name of the component.  
Type: String  
Required: Yes

**Id**  
Identifies the data source or destination. This identifier must be unique within the configuration file.  
Type: String  
Required: Yes

**InstanceName**  
The name of the performance counter instance. Don't use an asterisk (\$1) to indicate all instances because each performance counter component only supports one metric. You can, however use **\$1Total**.  
Type: String  
Required: Yes

**Levels**  
The types of messages to send to Amazon CloudWatch.  
Type: String  
Valid values:   
+ **1** - Only error messages uploaded.
+ **2** - Only warning messages uploaded.
+ **4** - Only information messages uploaded.
You can add values together to include more than one type of message. For example, **3** means that error messages (**1**) and warning messages (**2**) are included. A value of **7** means that error messages (**1**), warning messages (**2**), and informational messages (**4**) are included.  
Required: Yes  
Windows Security Logs should set Levels to 7.

**LineCount**  
The number of lines in the header to identify the log file. For example, IIS log files have virtually identical headers. You could enter **3**, which would read the first three lines of the log file's header to identify it. In IIS log files, the third line is the date and time stamp, which is different between log files.  
Type: Integer  
Required: No

**LogDirectoryPath**  
For CustomLogs, the path where logs are stored on your EC2 instance. For IIS logs, the folder where IIS logs are stored for an individual site (for example, **C:\$1\$1inetpub\$1\$1logs\$1\$1LogFiles\$1\$1W3SVC*n***). For IIS logs, only W3C log format is supported. IIS, NCSA, and Custom formats aren't supported.   
Type: String  
Required: Yes

**LogGroup**  
The name for your log group. This name is displayed on the **Log Groups** screen in the CloudWatch console.  
Type: String  
Required: Yes

**LogName**  
The name of the log file.  

1. To find the name of the log, in Event Viewer, in the navigation pane, select **Applications and Services Logs**.

1. In the list of logs, right-click the log you want to upload (for example, `Microsoft` > `Windows` > `Backup` > `Operational`), and then select **Create Custom View**.

1. In the **Create Custom View** dialog box, select the **XML** tab. The **LogName** is in the <Select Path=> tag (for example, `Microsoft-Windows-Backup`). Copy this text into the **LogName** parameter.
Type: String  
Valid values: `Application` \$1 `Security` \$1 `System` \$1 `Microsoft-Windows-WinINet/Analytic`  
Required: Yes

**LogStream**  
The destination log stream. If you use **\$1instance\$1id\$1**, the default, the instance ID of this instance is used as the log stream name.  
Type: String  
Valid values: `{instance_id}` \$1 `{hostname}` \$1 `{ip_address}` *<log\$1stream\$1name>*  
If you enter a log stream name that doesn't already exist, CloudWatch Logs automatically creates it for you. You can use a literal string or predefined variables (**\$1instance\$1id\$1**, **\$1hostname\$1**, **\$1ip\$1address\$1**, or a combination of all three to define a log stream name.  
The log stream name specified in this parameter is displayed on the **Log Groups > Streams for *<YourLogStream>*** screen in the CloudWatch console.  
Required: Yes

**MetricName**  
The CloudWatch metric that you want performance data to be included under.  
Don't use special characters in the name. If you do, the metric and associated alarms might not work.
Type: String  
Required: Yes

**NameSpace**  
The metric namespace where you want performance counter data to be written.  
Type: String  
Required: Yes

**PollInterval**  
How many seconds must elapse before new performance counter and log data is uploaded.  
Type: Integer  
Valid values: Set this to 5 or more seconds. Fifteen seconds (00:00:15) is recommended.  
Required: Yes

**Region**  
The AWS Region where you want to send log data. Although you can send performance counters to a different Region from where you send your log data, we recommend that you set this parameter to the same Region where your instance is running.  
Type: String  
Valid values: Regions IDs of the AWS Regions supported by both Systems Manager and CloudWatch Logs, such as `us-east-2`, `eu-west-1`, and `ap-southeast-1`. For lists of AWS Regions supported by each service, see [Amazon CloudWatch Logs Service Endpoints](https://docs.aws.amazon.com/general/latest/gr/cwl_region.html#cwl_region) and [Systems Manager service endpoints](https://docs.aws.amazon.com/general/latest/gr/ssm.html#ssm_region) in the *Amazon Web Services General Reference*.   
Required: Yes

**SecretKey**  
Your secret access key. This property is required unless you launched your instance using an IAM role.  
Type: String  
Required: No

**startType**  
Turn on or turn off CloudWatch on the instance.  
Type: String  
Valid values: `Enabled` \$1 `Disabled`  
Required: Yes

**TimestampFormat**  
The timestamp format you want to use. For a list of supported values, see [Custom Date and Time Format Strings](http://msdn.microsoft.com/en-us/library/8kb3ddd4.aspx) in the MSDN Library.  
Type: String  
Required: Yes

**TimeZoneKind**  
Provides time zone information when no time zone information is included in your log’s timestamp. If this parameter is left blank and if your timestamp doesn’t include time zone information, CloudWatch Logs defaults to the local time zone. This parameter is ignored if your timestamp already contains time zone information.  
Type: String  
Valid values: `Local` \$1 `UTC`  
Required: No

**Unit**  
The appropriate unit of measure for the metric.  
Type: String  
Valid values: Seconds \$1 Microseconds \$1 Milliseconds \$1 Bytes \$1 Kilobytes \$1 Megabytes \$1 Gigabytes \$1 Terabytes \$1 Bits \$1 Kilobits \$1 Megabits \$1 Gigabits \$1 Terabits \$1 Percent \$1 Count \$1 Bytes/Second \$1 Kilobytes/Second \$1 Megabytes/Second \$1 Gigabytes/Second \$1 Terabytes/Second \$1 Bits/Second \$1 Kilobits/Second \$1 Megabits/Second \$1 Gigabits/Second \$1 Terabits/Second \$1 Count/Second \$1 None  
Required: Yes

## `aws:configureDocker`
<a name="aws-configuredocker"></a>

(Schema version 2.0 or later) Configure an instance to work with containers and Docker. This plugin is supported on most Linux variants and Windows Server operating systems.

### Syntax
<a name="configuredocker-syntax"></a>

#### Schema 2.2
<a name="configuredocker-syntax-2.2"></a>

------
#### [ YAML ]

```
---
schemaVersion: '2.2'
description: aws:configureDocker
parameters:
  action:
    description: "(Required) The type of action to perform."
    type: String
    default: Install
    allowedValues:
    - Install
    - Uninstall
mainSteps:
- action: aws:configureDocker
  name: configureDocker
  inputs:
    action: "{{ action }}"
```

------
#### [ JSON ]

```
{
  "schemaVersion": "2.2",
  "description": "aws:configureDocker plugin",
  "parameters": {
    "action": {
      "description": "(Required) The type of action to perform.",
      "type": "String",
      "default": "Install",
      "allowedValues": [
        "Install",
        "Uninstall"
      ]
    }
  },
  "mainSteps": [
    {
      "action": "aws:configureDocker",
      "name": "configureDocker",
      "inputs": {
        "action": "{{ action }}"
      }
    }
  ]
}
```

------

### Inputs
<a name="configuredocker-properties"></a>

**action**  
The type of action to perform.  
Type: Enum  
Valid values: `Install` \$1 `Uninstall`  
Required: Yes

## `aws:configurePackage`
<a name="aws-configurepackage"></a>

(Schema version 2.0 or later) Install or uninstall an AWS Systems Manager Distributor package. You can install the latest version, default version, or a version of the package you specify. Packages provided by AWS are also supported. This plugin runs on Windows Server and Linux operating systems, but not all the available packages are supported on Linux operating systems.

Available AWS packages for Windows Server include the following: `AWSPVDriver`, `AWSNVMe`, `AwsEnaNetworkDriver`, `AwsVssComponents`, `AmazonCloudWatchAgent`, `CodeDeployAgent`, and `AWSSupport-EC2Rescue.`

Available AWS packages for Linux operating systems include the following: `AmazonCloudWatchAgent`, `CodeDeployAgent`, and `AWSSupport-EC2Rescue`.

### Syntax
<a name="configurepackage-syntax"></a>

#### Schema 2.2
<a name="configurepackage-syntax-2.2"></a>

------
#### [ YAML ]

```
---
schemaVersion: '2.2'
description: aws:configurePackage
parameters:
  name:
    description: "(Required) The name of the AWS package to install or uninstall."
    type: String
  action:
    description: "(Required) The type of action to perform."
    type: String
    default: Install
    allowedValues:
    - Install
    - Uninstall
  ssmParameter:
    description: "(Required) Argument stored in Parameter Store."
    type: String
    default: "{{ ssm:parameter_store_arg }}"
mainSteps:
- action: aws:configurePackage
  name: configurePackage
  inputs:
    name: "{{ name }}"
    action: "{{ action }}"
    additionalArguments: 
      "{\"SSM_parameter_store_arg\": \"{{ ssmParameter }}\", \"SSM_custom_arg\": \"myValue\"}"
```

------
#### [ JSON ]

```
{
   "schemaVersion": "2.2",
   "description": "aws:configurePackage",
   "parameters": {
      "name": {
         "description": "(Required) The name of the AWS package to install or uninstall.",
         "type": "String"
      },
      "action": {
         "description": "(Required) The type of action to perform.",
         "type": "String",
         "default": "Install",
         "allowedValues": [
            "Install",
            "Uninstall"
         ]
      },
      "ssmParameter": {
         "description": "(Required) Argument stored in Parameter Store.",
         "type": "String",
         "default": "{{ ssm:parameter_store_arg }}"
      }
   },
   "mainSteps": [
      {
         "action": "aws:configurePackage",
         "name": "configurePackage",
         "inputs": {
            "name": "{{ name }}",
            "action": "{{ action }}",
            "additionalArguments": "{\"SSM_parameter_store_arg\": \"{{ ssmParameter }}\", \"SSM_custom_arg\": \"myValue\"}"
         }
      }
   ]
}
```

------

### Inputs
<a name="configurepackage-properties"></a>

**name**  
The name of the AWS package to install or uninstall. Available packages include the following: `AWSPVDriver`, `AwsEnaNetworkDriver`, `AwsVssComponents`, and `AmazonCloudWatchAgent`.  
Type: String  
Required: Yes

**action**  
Install or uninstall a package.  
Type: Enum  
Valid values: `Install` \$1 `Uninstall`  
Required: Yes

**installationType**  
The type of installation to perform. If you specify `Uninstall and reinstall`, the package is completely uninstalled, and then reinstalled. The application is unavailable until the reinstallation is complete. If you specify `In-place update`, only new or changed files are added to the existing installation according you instructions you provide in an update script. The application remains available throughout the update process. The `In-place update` option isn't supported for AWS-published packages. `Uninstall and reinstall` is the default value.  
Type: Enum  
Valid values: `Uninstall and reinstall` \$1 `In-place update`  
Required: No

**additionalArguments**  
A JSON string of the additional parameters to provide to your install, uninstall, or update scripts. Each parameter must be prefixed with `SSM_`. You can reference a Parameter Store parameter in your additional arguments by using the convention `{{ssm:parameter-name}}`. To use the additional parameter in your install, uninstall, or update script, you must reference the parameter as an environment variable using the syntax appropriate for the operating system. For example, in PowerShell, you reference the `SSM_arg` argument as `$Env:SSM_arg`. There is no limit to the number of arguments you define, but the additional argument input has a 4096 character limit. This limit includes all of the keys and values you define.  
Type: StringMap  
Required: No

**version**  
A specific version of the package to install or uninstall. If installing, the system installs the latest published version, by default. If uninstalling, the system uninstalls the currently installed version, by default. If no installed version is found, the latest published version is downloaded, and the uninstall action is run.  
Type: String  
Required: No

## `aws:domainJoin`
<a name="aws-domainJoin"></a>

Join an EC2 instance to a domain. This plugin runs on Linux and Windows Server operating systems. This plugin changes the hostname for Linux instances to the format EC2AMAZ-*XXXXXXX*. For more information about joining EC2 instances, see [Join an EC2 Instance to Your AWS Managed Microsoft AD Directory](https://docs.aws.amazon.com/directoryservice/latest/admin-guide/ms_ad_join_instance.html) in the *AWS Directory Service Administration Guide*.

### Syntax
<a name="domainJoin-syntax"></a>

#### Schema 2.2
<a name="domainJoin-syntax-2.2"></a>

------
#### [ YAML ]

```
---
schemaVersion: '2.2'
description: aws:domainJoin
parameters:
  directoryId:
    description: "(Required) The ID of the directory."
    type: String
  directoryName:
    description: "(Required) The name of the domain."
    type: String
  directoryOU:
    description: "(Optional) The organizational unit to assign the computer object to."
    type: String
  dnsIpAddresses:
    description: "(Required) The IP addresses of the DNS servers for your directory."
    type: StringList
  hostname:
    description: "(Optional) The hostname you want to assign to the node."
    type: String
mainSteps:
- action: aws:domainJoin
  name: domainJoin
  inputs:
    directoryId: "{{ directoryId }}"
    directoryName: "{{ directoryName }}"
    directoryOU: "{{ directoryOU }}"
    dnsIpAddresses: "{{ dnsIpAddresses }}"
    hostname: "{{ hostname }}"
```

------
#### [ JSON ]

```
{
  "schemaVersion": "2.2",
  "description": "aws:domainJoin",
  "parameters": {
    "directoryId": {
      "description": "(Required) The ID of the directory.",
      "type": "String"
    },
    "directoryName": {
      "description": "(Required) The name of the domain.",
      "type": "String"
    },
    "directoryOU": {
        "description": "(Optional) The organizational unit to assign the computer object to.",
        "type": "String"
      },
    "dnsIpAddresses": {
      "description": "(Required) The IP addresses of the DNS servers for your directory.",
      "type": "StringList"
    },
    "hostname": {
        "description": "(Optional) The hostname you want to assign to the node.",
        "type": "String"
      }
  },
  "mainSteps": [
    {
      "action": "aws:domainJoin",
      "name": "domainJoin",
      "inputs": {
        "directoryId": "{{ directoryId }}",
        "directoryName": "{{ directoryName }}",
        "directoryOU":"{{ directoryOU }}",
        "dnsIpAddresses":"{{ dnsIpAddresses }}",
        "hostname":"{{ hostname }}"
      }
    }
  ]
}
```

------

#### Schema 1.2
<a name="domainJoin-syntax-1.2"></a>

------
#### [ YAML ]

```
---
runtimeConfig:
  aws:domainJoin:
    properties:
      directoryId: "{{ directoryId }}"
      directoryName: "{{ directoryName }}"
      directoryOU: "{{ directoryOU }}"
      dnsIpAddresses: "{{ dnsIpAddresses }}"
```

------
#### [ JSON ]

```
{
   "runtimeConfig":{
      "aws:domainJoin":{
         "properties":{
            "directoryId":"{{ directoryId }}",
            "directoryName":"{{ directoryName }}",
            "directoryOU":"{{ directoryOU }}",
            "dnsIpAddresses":"{{ dnsIpAddresses }}"
         }
      }
   }
}
```

------

### Properties
<a name="domainJoin-properties"></a>

**directoryId**  
The ID of the directory.  
Type: String  
Required: Yes  
Example: "directoryId": "d-1234567890"

**directoryName**  
The name of the domain.  
Type: String  
Required: Yes  
Example: "directoryName": "example.com"

**directoryOU**  
The organizational unit (OU).  
Type: String  
Required: No  
Example: "directoryOU": "OU=test,DC=example,DC=com"

**dnsIpAddresses**  
The IP addresses of the DNS servers.  
Type: StringList  
Required: Yes  
Example: "dnsIpAddresses": ["198.51.100.1","198.51.100.2"]

**hostname**  
The hostname you want to assign to the node. If not provided, there is no name change for Windows Server instances, while Linux instances will use the default naming pattern. If provided, Windows Server instances will use the exact provided value, while for Linux instances it serves as a prefix (unless `keepHostName` is set to "true").  
Type: String  
Required: No

**keepHostName**  
Determines whether the hostname is changed for Linux instances when joined to the domain. This is a Linux-only parameter. By default (without inputs to `hostname`, `hostnameNumAppendDigits`, and with `keepHostName` as "false"), Linux hosts will be renamed to the pattern EC2AMAZ-XXXXXX. When set to "true", it keeps the original hostname and ignores inputs to `hostname` and `hostnameNumAppendDigits`.  
Type: Boolean  
Required: No

**hostnameNumAppendDigits**  
Defines the number of random numeric digits to append after the hostname value. This is a Linux-only parameter and is used together with the `hostname` parameter. It is ignored if `hostname` is not provided.  
Type: String  
Allowed values: 1 to 5  
Required: No

### Examples
<a name="domainJoin-examples"></a>

For examples, see [Join an Amazon EC2 Instance to your AWS Managed Microsoft AD](https://docs.aws.amazon.com/directoryservice/latest/admin-guide/ec2-join-aws-domain.html) in the *AWS Directory Service Administration Guide*.

## `aws:downloadContent`
<a name="aws-downloadContent"></a>

(Schema version 2.0 or later) Download SSM documents and scripts from remote locations. GitHub Enterprise repositories are not supported. This plugin is supported on Linux and Windows Server operating systems.

### Syntax
<a name="downloadContent-syntax"></a>

#### Schema 2.2
<a name="downloadContent-syntax-2.2"></a>

------
#### [ YAML ]

```
---
schemaVersion: '2.2'
description: aws:downloadContent
parameters:
  sourceType:
    description: "(Required) The download source."
    type: String
  sourceInfo:
    description: "(Required) The information required to retrieve the content from
      the required source."
    type: StringMap
mainSteps:
- action: aws:downloadContent
  name: downloadContent
  inputs:
    sourceType: "{{ sourceType }}"
    sourceInfo: "{{ sourceInfo }}"
```

------
#### [ JSON ]

```
{
  "schemaVersion": "2.2",
  "description": "aws:downloadContent",
  "parameters": {
    "sourceType": {
    "description": "(Required) The download source.",
    "type": "String"
  },
  "sourceInfo": {
    "description": "(Required) The information required to retrieve the content from the required source.",
    "type": "StringMap"
    }
  },
  "mainSteps": [
    {
      "action": "aws:downloadContent",
      "name": "downloadContent",
      "inputs": {
        "sourceType":"{{ sourceType }}",
        "sourceInfo":"{{ sourceInfo }}"
      }
    }
  ]
}
```

------

### Inputs
<a name="downloadContent-inputs"></a>

**sourceType**  
The download source. Systems Manager supports the following source types for downloading scripts and SSM documents: `GitHub`, `Git`, `HTTP`, `S3`, and `SSMDocument`.  
Type: String  
Required: Yes

**sourceInfo**  
The information required to retrieve the content from the required source.  
Type: StringMap  
Required: Yes  
 **For sourceType `GitHub,` specify the following:**   
+ owner: The repository owner.
+ repository: The name of the repository.
+ path: The path to the file or directory you want to download.
+ getOptions: Extra options to retrieve content from a branch other than master or from a specific commit in the repository. getOptions can be omitted if you're using the latest commit in the master branch. If your repository was created after October 1, 2020 the default branch might be named main instead of master. In this case, you will need to specify values for the getOptions parameter.

  This parameter uses the following format:
  + branch:refs/heads/*branch\$1name*

    The default is `master`.

    To specify a non-default branch use the following format:

    branch:refs/heads/*branch\$1name*
  + commitID:*commitID*

    The default is `head`.

    To use the version of your SSM document in a commit other than the latest, specify the full commit ID. For example:

    ```
    "getOptions": "commitID:bbc1ddb94...b76d3bEXAMPLE",
    ```
+ tokenInfo: The Systems Manager parameter (a SecureString parameter) where you store your GitHub access token information, in the format `{{ssm-secure:secure-string-token-name}}`.
**Note**  
This `tokenInfo` field is the only SSM document plugin field that supports a SecureString parameter. SecureString parameters aren't supported for any other fields, nor for any other SSM document plugins.

```
{
    "owner":"TestUser",
    "repository":"GitHubTest",
    "path":"scripts/python/test-script",
    "getOptions":"branch:master",
    "tokenInfo":"{{ssm-secure:secure-string-token}}"
}
```
 **For sourceType `Git`, you must specify the following:**   
+ repository

  The Git repository URL to the file or directory you want to download.

  Type: String
Additionally, you can specify the following optional parameters:  
+ getOptions

  Extra options to retrieve content from a branch other than master or from a specific commit in the repository. getOptions can be omitted if you're using the latest commit in the master branch.

  Type: String

  This parameter uses the following format:
  + branch:refs/heads/*branch\$1name*

    The default is `master`.

    `"branch"` is required only if your SSM document is stored in a branch other than `master`. For example:

    ```
    "getOptions": "branch:refs/heads/main"
    ```
  + commitID:*commitID*

    The default is `head`.

    To use the version of your SSM document in a commit other than the latest, specify the full commit ID. For example:

    ```
    "getOptions": "commitID:bbc1ddb94...b76d3bEXAMPLE",
    ```
+ privateSSHKey

  The SSH key to use when connecting to the `repository` you specify. You can use the following format to reference a `SecureString` parameter for the value of your SSH key: `{{ssm-secure:your-secure-string-parameter}}`.

  Type: String
+ skipHostKeyChecking

  Determines the value of the StrictHostKeyChecking option when connecting to the `repository` you specify. The default value is `false`.

  Type: Boolean
+ username

  The username to use when connecting to the `repository` you specify using HTTP. You can use the following format to reference a `SecureString` parameter for the value of your username: `{{ssm-secure:your-secure-string-parameter}}`.

  Type: String
+ password

  The password to use when connecting to the `repository` you specify using HTTP. You can use the following format to reference a `SecureString` parameter for the value of your password: `{{ssm-secure:your-secure-string-parameter}}`.

  Type: String
 **For sourceType `HTTP`, you must specify the following:**   
+ url

  The URL to the file or directory you want to download.

  Type: String
Additionally, you can specify the following optional parameters:  
+ allowInsecureDownload

  Determines whether a download can be performed over a connection that isn't encrypted with Secure Socket Layer (SSL) or Transport Layer Security (TLS). The default value is `false`. We don't recommend performing downloads without encryption. If you choose to do so, you assume all associated risks. Security is a shared responsibility between AWS and you. This is described as the shared responsibility model. To learn more, see the [shared responsibility model](https://aws.amazon.com/compliance/shared-responsibility-model/).

  Type: Boolean
+ authMethod

  Determines whether a username and password are used for authentication when connecting to the `url` you specify. If you specify `Basic` or `Digest`, you must provide values for the `username` and `password` parameters. To use the `Digest` method, SSM Agent version 3.0.1181.0 or later must be installed on your instance. The `Digest` method supports MD5 and SHA256 encryption.

  Type: String

  Valid values: `None` \$1 `Basic` \$1 `Digest`
+ username

  The username to use when connecting to the `url` you specify using `Basic` authentication. You can use the following format to reference a `SecureString` parameter for the value of your username: `{{ssm-secure:your-secure-string-parameter}}`.

  Type: String
+ password

  The password to use when connecting to the `url` you specify using `Basic` authentication. You can use the following format to reference a `SecureString` parameter for the value of your password: `{{ssm-secure:your-secure-string-parameter}}`.

  Type: String
 **For sourceType `S3`, specify the following:**   
+ path: The URL to the file or directory you want to download from Amazon S3.
When downloading a file from an S3 bucket, the .etag files are generated in the download directory.

```
{
    "path": "https://s3.amazonaws.com/amzn-s3-demo-bucket/powershell/helloPowershell.ps1" 
}
```
 **For sourceType `SSMDocument`, specify *one* of the following:**   
+ name: The name and version of the document in the following format: `name:version`. Version is optional. 

  ```
  {
      "name": "Example-RunPowerShellScript:3" 
  }
  ```
+ name: The ARN for the document in the following format: `arn:aws:ssm:region:account_id:document/document_name`

  ```
  {
     "name":"arn:aws:ssm:us-east-2:3344556677:document/MySharedDoc"
  }
  ```

**destinationPath**  
An optional local path on the instance where you want to download the file. If you don't specify a path, the content is downloaded to a path relative to your command ID.  
Type: String  
Required: No

## `aws:psModule`
<a name="aws-psModule"></a>

Install PowerShell modules on an Amazon EC2 instance. This plugin only runs on Windows Server operating systems.

### Syntax
<a name="psModule-syntax"></a>

#### Schema 2.2
<a name="psModule-syntax-2.2"></a>

------
#### [ YAML ]

```
---
schemaVersion: '2.2'
description: aws:psModule
parameters:
  source:
    description: "(Required) The URL or local path on the instance to the application
      .zip file."
    type: String
mainSteps:
- action: aws:psModule
  name: psModule
  inputs:
    source: "{{ source }}"
```

------
#### [ JSON ]

```
{
  "schemaVersion": "2.2",
  "description": "aws:psModule",
  "parameters": {
    "source": {
      "description": "(Required) The URL or local path on the instance to the application .zip file.",
      "type": "String"
    }
  },
  "mainSteps": [
    {
      "action": "aws:psModule",
      "name": "psModule",
      "inputs": {
        "source": "{{ source }}"
      }
    }
  ]
}
```

------

#### Schema 1.2
<a name="domainJoin-syntax-1.2"></a>

------
#### [ YAML ]

```
---
runtimeConfig:
  aws:psModule:
    properties:
    - runCommand: "{{ commands }}"
      source: "{{ source }}"
      sourceHash: "{{ sourceHash }}"
      workingDirectory: "{{ workingDirectory }}"
      timeoutSeconds: "{{ executionTimeout }}"
```

------
#### [ JSON ]

```
{
   "runtimeConfig":{
      "aws:psModule":{
         "properties":[
            {
               "runCommand":"{{ commands }}",
               "source":"{{ source }}",
               "sourceHash":"{{ sourceHash }}",
               "workingDirectory":"{{ workingDirectory }}",
               "timeoutSeconds":"{{ executionTimeout }}"
            }
         ]
      }
   }
}
```

------

### Properties
<a name="psModule-properties"></a>

**runCommand**  
The PowerShell command to run after the module is installed.  
Type: StringList  
Required: No

**source**  
The URL or local path on the instance to the application `.zip` file.  
Type: String  
Required: Yes

**sourceHash**  
The SHA256 hash of the `.zip` file.  
Type: String  
Required: No

**timeoutSeconds**  
The time in seconds for a command to be completed before it's considered to have failed.  
Type: String  
Required: No

**workingDirectory**  
The path to the working directory on your instance.  
Type: String  
Required: No

## `aws:refreshAssociation`
<a name="aws-refreshassociation"></a>

(Schema version 2.0 or later) Refresh (force apply) an association on demand. This action will change the system state based on what is defined in the selected association or all associations bound to the targets. This plugin runs on Linux and Microsoft Windows Server operating systems.

### Syntax
<a name="refreshassociation-syntax"></a>

#### Schema 2.2
<a name="refreshassociation-syntax-2.2"></a>

------
#### [ YAML ]

```
---
schemaVersion: '2.2'
description: aws:refreshAssociation
parameters:
  associationIds:
    description: "(Optional) List of association IDs. If empty, all associations bound
      to the specified target are applied."
    type: StringList
mainSteps:
- action: aws:refreshAssociation
  name: refreshAssociation
  inputs:
    associationIds:
    - "{{ associationIds }}"
```

------
#### [ JSON ]

```
{
  "schemaVersion": "2.2",
  "description": "aws:refreshAssociation",
  "parameters": {
    "associationIds": {
      "description": "(Optional) List of association IDs. If empty, all associations bound to the specified target are applied.",
      "type": "StringList"
    }
  },
  "mainSteps": [
    {
      "action": "aws:refreshAssociation",
      "name": "refreshAssociation",
      "inputs": {
        "associationIds": [
          "{{ associationIds }}"
        ]
      }
    }
  ]
}
```

------

### Inputs
<a name="refreshassociation-properties"></a>

**associationIds**  
List of association IDs. If empty, all associations bound to the specified target are applied.  
Type: StringList  
Required: No

## `aws:runDockerAction`
<a name="aws-rundockeraction"></a>

(Schema version 2.0 or later) Run Docker actions on containers. This plugin runs on Linux and Microsoft Windows Server operating systems.

### Syntax
<a name="rundockeraction-syntax"></a>

#### Schema 2.2
<a name="rundockeraction-syntax-2.2"></a>

------
#### [ YAML ]

```
---
mainSteps:
- action: aws:runDockerAction
  name: RunDockerAction
  inputs:
    action: "{{ action }}"
    container: "{{ container }}"
    image: "{{ image }}"
    memory: "{{ memory }}"
    cpuShares: "{{ cpuShares }}"
    volume: "{{ volume }}"
    cmd: "{{ cmd }}"
    env: "{{ env }}"
    user: "{{ user }}"
    publish: "{{ publish }}"
    workingDirectory: "{{ workingDirectory }}"
    timeoutSeconds: "{{ timeoutSeconds }}"
```

------
#### [ JSON ]

```
{
   "mainSteps":[
      {
         "action":"aws:runDockerAction",
         "name":"RunDockerAction",
         "inputs":{
            "action":"{{ action }}",
            "container":"{{ container }}",
            "image":"{{ image }}",
            "memory":"{{ memory }}",
            "cpuShares":"{{ cpuShares }}",
            "volume":"{{ volume }}",
            "cmd":"{{ cmd }}",
            "env":"{{ env }}",
            "user":"{{ user }}",
            "publish":"{{ publish }}",
            "workingDirectory": "{{ workingDirectory }}",
            "timeoutSeconds": "{{ timeoutSeconds }}"
         }
      }
   ]
}
```

------

### Inputs
<a name="rundockeraction-properties"></a>

**action**  
The type of action to perform.  
Type: String  
Required: Yes

**container**  
The Docker container ID.  
Type: String  
Required: No

**image**  
The Docker image name.  
Type: String  
Required: No

**cmd**  
The container command.  
Type: String  
Required: No

**memory**  
The container memory limit.  
Type: String  
Required: No

**cpuShares**  
The container CPU shares (relative weight).  
Type: String  
Required: No

**volume**  
The container volume mounts.  
Type: StringList  
Required: No

**env**  
The container environment variables.  
Type: String  
Required: No

**user**  
The container user name.  
Type: String  
Required: No

**publish**  
The container published ports.  
Type: String  
Required: No

**workingDirectory**  
The path to the working directory on your managed node.  
Type: String  
Required: No

**timeoutSeconds**  
The time in seconds for a command to be completed before it's considered to have failed.  
Type: String  
Required: No

## `aws:runDocument`
<a name="aws-rundocument"></a>

(Schema version 2.0 or later) Runs SSM documents stored in Systems Manager or on a local share. You can use this plugin with the [`aws:downloadContent`](#aws-downloadContent) plugin to download an SSM document from a remote location to a local share, and then run it. This plugin is supported on Linux and Windows Server operating systems. This plugin doesn't support running the `AWS-UpdateSSMAgent` document or any document that uses the `aws:updateSsmAgent` plugin.

### Syntax
<a name="rundocument-syntax"></a>

#### Schema 2.2
<a name="aws-rundocument-syntax-2.2"></a>

------
#### [ YAML ]

```
---
schemaVersion: '2.2'
description: aws:runDocument
parameters:
  documentType:
    description: "(Required) The document type to run."
    type: String
    allowedValues:
    - LocalPath
    - SSMDocument
mainSteps:
- action: aws:runDocument
  name: runDocument
  inputs:
    documentType: "{{ documentType }}"
```

------
#### [ JSON ]

```
{
  "schemaVersion": "2.2",
  "description": "aws:runDocument",
  "parameters": {
    "documentType": {
      "description": "(Required) The document type to run.",
      "type": "String",
      "allowedValues": [
        "LocalPath",
        "SSMDocument"
      ]
    }
  },
  "mainSteps": [
    {
      "action": "aws:runDocument",
      "name": "runDocument",
      "inputs": {
        "documentType": "{{ documentType }}"
      }
    }
  ]
}
```

------

### Inputs
<a name="rundocument-properties"></a>

**documentType**  
The document type to run. You can run local documents (`LocalPath`) or documents stored in Systems Manager (`SSMDocument`).  
Type: String  
Required: Yes

**documentPath**  
The path to the document. If `documentType` is `LocalPath`, then specify the path to the document on the local share. If `documentType` is `SSMDocument`, then specify the name of the document.  
Type: String  
Required: No

**documentParameters**  
Parameters for the document.  
Type: StringMap  
Required: No

## `aws:runPowerShellScript`
<a name="aws-runPowerShellScript"></a>

Run PowerShell scripts or specify the path to a script to run. This plugin runs on Microsoft Windows Server and Linux operating systems.

### Syntax
<a name="runPowerShellScript-syntax"></a>

#### Schema 2.2
<a name="runPowerShellScript-syntax-2.2"></a>

------
#### [ YAML ]

```
---
schemaVersion: '2.2'
description: aws:runPowerShellScript
parameters:
  commands:
    type: String
    description: "(Required) The commands to run or the path to an existing script
      on the instance."
    default: Write-Host "Hello World"
mainSteps:
- action: aws:runPowerShellScript
  name: runPowerShellScript
  inputs:
    timeoutSeconds: '60'
    runCommand:
    - "{{ commands }}"
```

------
#### [ JSON ]

```
{
  "schemaVersion": "2.2",
  "description": "aws:runPowerShellScript",
  "parameters": {
    "commands": {
      "type": "String",
      "description": "(Required) The commands to run or the path to an existing script on the instance.",
      "default": "Write-Host \"Hello World\""
    }
  },
  "mainSteps": [
    {
      "action": "aws:runPowerShellScript",
      "name": "runPowerShellScript",
      "inputs": {
        "timeoutSeconds": "60",
        "runCommand": [
          "{{ commands }}"
        ]
      }
    }
  ]
}
```

------

#### Schema 1.2
<a name="runPowerShellScript-syntax-1.2"></a>

------
#### [ YAML ]

```
---
runtimeConfig:
  aws:runPowerShellScript:
    properties:
    - id: 0.aws:runPowerShellScript
      runCommand: "{{ commands }}"
      workingDirectory: "{{ workingDirectory }}"
      timeoutSeconds: "{{ executionTimeout }}"
```

------
#### [ JSON ]

```
{
   "runtimeConfig":{
      "aws:runPowerShellScript":{
         "properties":[
            {
               "id":"0.aws:runPowerShellScript",
               "runCommand":"{{ commands }}",
               "workingDirectory":"{{ workingDirectory }}",
               "timeoutSeconds":"{{ executionTimeout }}"
            }
         ]
      }
   }
}
```

------

### Properties
<a name="runPowerShellScript-properties"></a>

**runCommand**  
Specify the commands to run or the path to an existing script on the instance.  
Type: StringList  
Required: Yes

**timeoutSeconds**  
The time in seconds for a command to be completed before it's considered to have failed. When the timeout is reached, Systems Manager stops the command execution.  
Type: String  
Required: No

**workingDirectory**  
The path to the working directory on your instance.  
Type: String  
Required: No

## `aws:runShellScript`
<a name="aws-runShellScript"></a>

Run Linux shell scripts or specify the path to a script to run. This plugin only runs on Linux operating systems.

### Syntax
<a name="runShellScript-syntax"></a>

#### Schema 2.2
<a name="runShellScript-syntax-2.2"></a>

------
#### [ YAML ]

```
---
schemaVersion: '2.2'
description: aws:runShellScript
parameters:
  commands:
    type: String
    description: "(Required) The commands to run or the path to an existing script
      on the instance."
    default: echo Hello World
mainSteps:
- action: aws:runShellScript
  name: runShellScript
  inputs:
    timeoutSeconds: '60'
    runCommand:
    - "{{ commands }}"
```

------
#### [ JSON ]

```
{
  "schemaVersion": "2.2",
  "description": "aws:runShellScript",
  "parameters": {
    "commands": {
      "type": "String",
      "description": "(Required) The commands to run or the path to an existing script on the instance.",
      "default": "echo Hello World"
    }
  },
  "mainSteps": [
    {
      "action": "aws:runShellScript",
      "name": "runShellScript",
      "inputs": {
        "timeoutSeconds": "60",
        "runCommand": [
          "{{ commands }}"
        ]
      }
    }
  ]
}
```

------

#### Schema 1.2
<a name="runShellScript-syntax-1.2"></a>

------
#### [ YAML ]

```
---
runtimeConfig:
  aws:runShellScript:
    properties:
    - runCommand: "{{ commands }}"
      workingDirectory: "{{ workingDirectory }}"
      timeoutSeconds: "{{ executionTimeout }}"
```

------
#### [ JSON ]

```
{
   "runtimeConfig":{
      "aws:runShellScript":{
         "properties":[
            {
               "runCommand":"{{ commands }}",
               "workingDirectory":"{{ workingDirectory }}",
               "timeoutSeconds":"{{ executionTimeout }}"
            }
         ]
      }
   }
}
```

------

### Properties
<a name="runShellScript-properties"></a>

**runCommand**  
Specify the commands to run or the path to an existing script on the instance.  
Type: StringList  
Required: Yes

**timeoutSeconds**  
The time in seconds for a command to be completed before it's considered to have failed. When the timeout is reached, Systems Manager stops the command execution.  
Type: String  
Required: No

**workingDirectory**  
The path to the working directory on your instance.  
Type: String  
Required: No

## `aws:softwareInventory`
<a name="aws-softwareinventory"></a>

(Schema version 2.0 or later) Gather metadata about applications, files, and configurations on your managed instances. This plugin runs on Linux and Microsoft Windows Server operating systems. When you configure inventory collection, you start by creating an AWS Systems Manager State Manager association. Systems Manager collects the inventory data when the association is run. If you don't create the association first, and attempt to invoke the `aws:softwareInventory` plugin the system returns the following error:

```
The aws:softwareInventory plugin can only be invoked via ssm-associate.
```

An instance can have only one inventory association configured at a time. If you configure an instance with two or more associations, the inventory association doesn't run and no inventory data is collected. For more information about collecting inventory, see [AWS Systems Manager Inventory](systems-manager-inventory.md).

### Syntax
<a name="softwareinventory-syntax"></a>

#### Schema 2.2
<a name="softwareinventory-syntax-2.2"></a>

------
#### [ YAML ]

```
---
mainSteps:
- action: aws:softwareInventory
  name: collectSoftwareInventoryItems
  inputs:
    applications: "{{ applications }}"
    awsComponents: "{{ awsComponents }}"
    networkConfig: "{{ networkConfig }}"
    files: "{{ files }}"
    services: "{{ services }}"
    windowsRoles: "{{ windowsRoles }}"
    windowsRegistry: "{{ windowsRegistry}}"
    windowsUpdates: "{{ windowsUpdates }}"
    instanceDetailedInformation: "{{ instanceDetailedInformation }}"
    customInventory: "{{ customInventory }}"
```

------
#### [ JSON ]

```
{
   "mainSteps":[
      {
         "action":"aws:softwareInventory",
         "name":"collectSoftwareInventoryItems",
         "inputs":{
            "applications":"{{ applications }}",
            "awsComponents":"{{ awsComponents }}",
            "networkConfig":"{{ networkConfig }}",
            "files":"{{ files }}",
            "services":"{{ services }}",
            "windowsRoles":"{{ windowsRoles }}",
            "windowsRegistry":"{{ windowsRegistry}}",
            "windowsUpdates":"{{ windowsUpdates }}",
            "instanceDetailedInformation":"{{ instanceDetailedInformation }}",
            "customInventory":"{{ customInventory }}"
         }
      }
   ]
}
```

------

### Inputs
<a name="softwareinventory-properties"></a>

**applications**  
(Optional) Collect metadata for installed applications.  
Type: String  
Required: No

**awsComponents**  
(Optional) Collect metadata for AWS components like amazon-ssm-agent.  
Type: String  
Required: No

**files**  
(Optional, requires SSM Agent version 2.2.64.0 or later) Collect metadata for files, including file names, the time files were created, the time files were last modified and accessed, and file sizes, to name a few. For more information about collecting file inventory, see [Working with file and Windows registry inventory](inventory-file-and-registry.md).  
Type: String  
Required: No

**networkConfig**  
(Optional) Collect metadata for network configurations.  
Type: String  
Required: No

**billingInfo**  
(Optional) Collect metadata for platform details associated with the billing code of the AMI.  
Type: String  
Required: No

**windowsUpdates**  
(Optional) Collect metadata for all Windows updates.  
Type: String  
Required: No

**instanceDetailedInformation**  
(Optional) Collect more instance information than is provided by the default inventory plugin (`aws:instanceInformation`), including CPU model, speed, and the number of cores, to name a few.  
Type: String  
Required: No

**services**  
(Optional, Windows OS only, requires SSM Agent version 2.2.64.0 or later) Collect metadata for service configurations.  
Type: String  
Required: No

**windowsRegistry**  
(Optional, Windows OS only, requires SSM Agent version 2.2.64.0 or later) Collect Windows Registry keys and values. You can choose a key path and collect all keys and values recursively. You can also collect a specific registry key and its value for a specific path. Inventory collects the key path, name, type, and the value. For more information about collecting Windows Registry inventory, see [Working with file and Windows registry inventory](inventory-file-and-registry.md).  
Type: String  
Required: No

**windowsRoles**  
(Optional, Windows OS only, requires SSM Agent version 2.2.64.0 or later) Collect metadata for Microsoft Windows role configurations.  
Type: String  
Required: No

**customInventory**  
(Optional) Collect custom inventory data. For more information about custom inventory, see [Working with custom inventory](inventory-custom.md)  
Type: String  
Required: No

**customInventoryDirectory**  
(Optional) Collect custom inventory data from the specified directory. For more information about custom inventory, see [Working with custom inventory](inventory-custom.md)  
Type: String  
Required: No

## `aws:updateAgent`
<a name="aws-updateagent"></a>

Update the EC2Config service to the latest version or specify an older version. This plugin only runs on Microsoft Windows Server operating systems. For more information about the EC2Config service, see [Configuring a Windows Instance using the EC2Config service (legacy)](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2config-service.html) in the *Amazon EC2 User Guide*.

### Syntax
<a name="updateagent-syntax"></a>

#### Schema 2.2
<a name="updateagent-syntax-2.2"></a>

------
#### [ YAML ]

```
---
schemaVersion: '2.2'
description: aws:updateAgent
mainSteps:
- action: aws:updateAgent
  name: updateAgent
  inputs:
    agentName: Ec2Config
    source: https://s3.{Region}.amazonaws.com/aws-ssm-{Region}/manifest.json
```

------
#### [ JSON ]

```
{
  "schemaVersion": "2.2",
  "description": "aws:updateAgent",
  "mainSteps": [
    {
      "action": "aws:updateAgent",
      "name": "updateAgent",
      "inputs": {
        "agentName": "Ec2Config",
        "source": "https://s3.{Region}.amazonaws.com/aws-ssm-{Region}/manifest.json"
      }
    }
  ]
}
```

------

#### Schema 1.2
<a name="updateagent-syntax-1.2"></a>

------
#### [ YAML ]

```
---
runtimeConfig:
  aws:updateAgent:
    properties:
      agentName: Ec2Config
      source: https://s3.{Region}.amazonaws.com/aws-ssm-{Region}/manifest.json
      allowDowngrade: "{{ allowDowngrade }}"
      targetVersion: "{{ version }}"
```

------
#### [ JSON ]

```
{
   "runtimeConfig":{
      "aws:updateAgent":{
         "properties":{
            "agentName":"Ec2Config",
            "source":"https://s3.{Region}.amazonaws.com/aws-ssm-{Region}/manifest.json",
            "allowDowngrade":"{{ allowDowngrade }}",
            "targetVersion":"{{ version }}"
         }
      }
   }
}
```

------

### Properties
<a name="updateagent-properties"></a>

**agentName**  
EC2Config. This is the name of the agent that runs the EC2Config service.  
Type: String  
Required: Yes

**allowDowngrade**  
Allow the EC2Config service to be downgraded to an earlier version. If set to false, the service can be upgraded to newer versions only (default). If set to true, specify the earlier version.   
Type: Boolean  
Required: No

**source**  
The location where Systems Manager copies the version of EC2Config to install. You can't change this location.  
Type: String  
Required: Yes

**targetVersion**  
A specific version of the EC2Config service to install. If not specified, the service will be updated to the latest version.  
Type: String  
Required: No

## `aws:updateSsmAgent`
<a name="aws-updatessmagent"></a>

Update the SSM Agent to the latest version or specify an older version. This plugin runs on Linux and Windows Server operating systems. For more information, see [Working with SSM Agent](ssm-agent.md). 

### Syntax
<a name="updateSSMagent-syntax"></a>

#### Schema 2.2
<a name="updateaSSMgent-syntax-2.2"></a>

------
#### [ YAML ]

```
---
schemaVersion: '2.2'
description: aws:updateSsmAgent
parameters:
  allowDowngrade:
    default: 'false'
    description: "(Optional) Allow the Amazon SSM Agent service to be downgraded to
      an earlier version. If set to false, the service can be upgraded to newer versions
      only (default). If set to true, specify the earlier version."
    type: String
    allowedValues:
    - 'true'
    - 'false'
mainSteps:
- action: aws:updateSsmAgent
  name: updateSSMAgent
  inputs:
    agentName: amazon-ssm-agent
    source: https://s3.{Region}.amazonaws.com/amazon-ssm-{Region}/ssm-agent-manifest.json
    allowDowngrade: "{{ allowDowngrade }}"
```

------
#### [ JSON ]

```
{
  "schemaVersion": "2.2",
  "description": "aws:updateSsmAgent",
  "parameters": {
    "allowDowngrade": {
      "default": "false",
      "description": "(Required) Allow the Amazon SSM Agent service to be downgraded to an earlier version. If set to false, the service can be upgraded to newer versions only (default). If set to true, specify the earlier version.",
      "type": "String",
      "allowedValues": [
        "true",
        "false"
      ]
    }
  },
  "mainSteps": [
    {
      "action": "aws:updateSsmAgent",
      "name": "awsupdateSsmAgent",
      "inputs": {
        "agentName": "amazon-ssm-agent",
        "source": "https://s3.{Region}.amazonaws.com/amazon-ssm-{Region}/ssm-agent-manifest.json",
        "allowDowngrade": "{{ allowDowngrade }}"
      }
    }
  ]
}
```

------

#### Schema 1.2
<a name="updateaSSMgent-syntax-1.2"></a>

------
#### [ YAML ]

```
---
runtimeConfig:
  aws:updateSsmAgent:
    properties:
    - agentName: amazon-ssm-agent
      source: https://s3.{Region}.amazonaws.com/aws-ssm-{Region}/manifest.json
      allowDowngrade: "{{ allowDowngrade }}"
```

------
#### [ JSON ]

```
{
   "runtimeConfig":{
      "aws:updateSsmAgent":{
         "properties":[
            {
               "agentName":"amazon-ssm-agent",
               "source":"https://s3.{Region}.amazonaws.com/aws-ssm-{Region}/manifest.json",
               "allowDowngrade":"{{ allowDowngrade }}"
            }
         ]
      }
   }
}
```

------

### Properties
<a name="updateSSMagent-properties"></a>

**agentName**  
amazon-ssm-agent. This is the name of the Systems Manager agent that processes requests and runs commands on the instance.  
Type: String  
Required: Yes

**allowDowngrade**  
Allow the SSM Agent to be downgraded to an earlier version. If set to false, the agent can be upgraded to newer versions only (default). If set to true, specify the earlier version.   
Type: Boolean  
Required: Yes

**source**  
The location where Systems Manager copies the SSM Agent version to install. You can't change this location.  
Type: String  
Required: Yes

**targetVersion**  
A specific version of SSM Agent to install. If not specified, the agent will be updated to the latest version.  
Type: String  
Required: No

# Creating SSM document content
<a name="documents-creating-content"></a>

If the AWS Systems Manager public documents don't perform all the actions you want to perform on your AWS resources, you can create your own SSM documents. You can also clone SSM documents using the console. Cloning documents copies content from an existing document to a new document that you can modify. When creating or cloning a document, the content of the document must not exceed 64KB. This quota also includes the content specified for input parameters at runtime. When you create a new `Command` or `Policy` document, we recommend that you use schema version 2.2 or later so you can take advantage of the latest features, such as document editing, automatic versioning, sequencing, and more.

## Writing SSM document content
<a name="writing-ssm-doc-content"></a>

To create your own SSM document content, it's important to understand the different schemas, features, plugins, and syntax available for SSM documents. We recommend becoming familiar with the following resources.
+  [Writing your own AWS Systems Manager documents](https://aws.amazon.com/blogs//mt/writing-your-own-aws-systems-manager-documents/) 
+  [Data elements and parameters](documents-syntax-data-elements-parameters.md) 
+  [Schemas, features, and examples](documents-schemas-features.md) 
+  [Command document plugin reference](documents-command-ssm-plugin-reference.md) 
+  [Systems Manager Automation actions reference](automation-actions.md) 
+  [Automation system variables](automation-variables.md) 
+  [Additional runbook examples](automation-document-examples.md) 
+  [Working with Systems Manager Automation runbooks](https://docs.aws.amazon.com/toolkit-for-vscode/latest/userguide/systems-manager-automation-docs.html) using the AWS Toolkit for Visual Studio Code 
+  [Visual design experience for Automation runbooks](automation-visual-designer.md) 
+  [Using scripts in runbooks](automation-document-script-considerations.md) 

AWS pre-defined SSM documents might perform some of the actions you require. You can call these documents by using the `aws:runDocument`, `aws:runCommand`, or `aws:executeAutomation` plugins within your custom SSM document, depending on the document type. You can also copy portions of those documents into a custom SSM document, and edit the content to meet your requirements.

**Tip**  
When creating SSM document content, you might change the content and update your SSM document several times while testing. The following commands update the SSM document with your latest content, and update the document's default version to the latest version of the document.  
The Linux and Windows commands use the `jq` command line tool to filter the JSON response data.

```
latestDocVersion=$(aws ssm update-document \
    --content file://path/to/file/documentContent.json \
    --name "ExampleDocument" \
    --document-format JSON \
    --document-version '$LATEST' \
    | jq -r '.DocumentDescription.LatestVersion')

aws ssm update-document-default-version \
    --name "ExampleDocument" \
    --document-version $latestDocVersion
```

```
latestDocVersion=$(aws ssm update-document ^
    --content file://C:\path\to\file\documentContent.json ^
    --name "ExampleDocument" ^
    --document-format JSON ^
    --document-version "$LATEST" ^
    | jq -r '.DocumentDescription.LatestVersion')

aws ssm update-document-default-version ^
    --name "ExampleDocument" ^
    --document-version $latestDocVersion
```

```
$content = Get-Content -Path "C:\path\to\file\documentContent.json" | Out-String
$latestDocVersion = Update-SSMDocument `
    -Content $content `
    -Name "ExampleDocument" `
    -DocumentFormat "JSON" `
    -DocumentVersion '$LATEST' `
    | Select-Object -ExpandProperty LatestVersion

Update-SSMDocumentDefaultVersion `
    -Name "ExampleDocument" `
    -DocumentVersion $latestDocVersion
```

### Security best practices for SSM documents
<a name="ssm-document-security-practices"></a>

When creating SSM documents, follow these security best practices to help prevent command injection and ensure secure parameter handling:
+ Use environment variable interpolation for string parameters that will be used in commands or scripts. Add the `interpolationType` property with value `ENV_VAR` to your string parameters:

  ```
  {
      "command": {
          "type": "String",
          "description": "Command to execute",
          "interpolationType": "ENV_VAR"
      }
  }
  ```

  You can further improve the security of your SSM documents by specifying that double-quote marks aren’t accepted in values delivered by interpolation:

  ```
  {
      "command": {
          "type": "String",
          "description": "Command to execute",
          "interpolationType": "ENV_VAR",
              "allowedPattern": "^[^"]*$"
      }
  }
  ```
+ When using interpreted languages like Python, Ruby, or Node.js, reference parameters using the appropriate environment variable syntax:

  ```
  # Python example
  import os
  command = os.environ['SSM_Message']
  ```
+ For backwards compatibility with older SSM Agent versions (prior to version 3.3.2746.0), include fallback logic for environment variables:

  ```
  if [ -z "${SSM_command+x}" ]; then
      export SSM_command="{{command}}"
  fi
  ```
+ Combine environment variable interpolation with `allowedPattern` for additional input validation. In the following example, the `allowedPattern` value `^[^"]*$` specifically prevent double-quotes in the string value:

  ```
  {
      "command": {
          "type": "String",
          "interpolationType": "ENV_VAR",
          "allowedPattern": "^[a-zA-Z0-9_-]+$"
      }
  }
  ```
+ Before implementing your SSM document, verify the following security considerations:
  + All string parameters that accept user input use environment variable interpolation when appropriate.
  + Input validation is implemented using `allowedPattern` where possible.
  + The document includes appropriate error handling for parameter processing.
  + Backwards compatibility is maintained for environments using older SSM Agent versions.

For information about AWS service-owned resources that Systems Manager accesses and how to configure data perimeter policies, see [Data perimeters in AWS Systems Manager](data-perimeters.md).

## Cloning an SSM document
<a name="cloning-ssm-document"></a>

You can clone AWS Systems Manager documents using the Systems Manager Documents console to create SSM documents. Cloning SSM documents copies content from an existing document to a new document that you can modify. You can't clone a document larger than 64KB.

**To clone an SSM document**

1. Open the AWS Systems Manager console at [https://console.aws.amazon.com/systems-manager/](https://console.aws.amazon.com/systems-manager/).

1. In the navigation pane, choose **Documents**.

1. In the search box, enter the name of the document you want to clone.

1. Choose the name of the document you want to clone, and then choose **Clone document** in the **Actions** dropdown. 

1. Modify the document as you prefer, and then choose **Create document** to save the document. 

After writing your SSM document content, you can use your content to create an SSM document using one of the following methods.

**Topics**
+ [Writing SSM document content](#writing-ssm-doc-content)
+ [Cloning an SSM document](#cloning-ssm-document)
+ [Creating composite documents](#documents-creating-composite)

## Creating composite documents
<a name="documents-creating-composite"></a>

A *composite* AWS Systems Manager (SSM) document is a custom document that performs a series of actions by running one or more secondary SSM documents. Composite documents promote *infrastructure as code* by allowing you to create a standard set of SSM documents for common tasks such as boot-strapping software or domain-joining instances. You can then share these documents across AWS accounts in the same AWS Region to reduce SSM document maintenance and ensure consistency.

For example, you can create a composite document that performs the following actions:

1. Installs all patches in the allow list.

1. Installs antivirus software.

1. Downloads scripts from GitHub and runs them.

In this example, your custom SSM document includes the following plugins to perform these actions:

1. The `aws:runDocument` plugin to run the `AWS-RunPatchBaseline` document, which installs all allow listed patches.

1. The `aws:runDocument` plugin to run the `AWS-InstallApplication` document, which installs the antivirus software.

1. The `aws:downloadContent` plugin to download scripts from GitHub and run them.

Composite and secondary documents can be stored in Systems Manager, GitHub (public and private repositories), or Amazon S3. Composite documents and secondary documents can be created in JSON or YAML. 

**Note**  
Composite documents can only run to a maximum depth of three documents. This means that a composite document can call a child document; and that child document can call one last document.

To create a composite document, add the [`aws:runDocument`](documents-command-ssm-plugin-reference.md#aws-rundocument) plugin in a custom SSM document and specify the required inputs. The following is an example of a composite document that performs the following actions:

1. Runs the [`aws:downloadContent`](documents-command-ssm-plugin-reference.md#aws-downloadContent) plugin to download an SSM document from a GitHub public repository to a local directory called bootstrap. The SSM document is called StateManagerBootstrap.yml (a YAML document).

1. Runs the `aws:runDocument` plugin to run the StateManagerBootstrap.yml document. No parameters are specified.

1. Runs the `aws:runDocument` plugin to run the `AWS-ConfigureDocker pre-defined` SSM document. The specified parameters install Docker on the instance.

```
{
  "schemaVersion": "2.2",
  "description": "My composite document for bootstrapping software and installing Docker.",
  "parameters": {
  },
  "mainSteps": [
    {
      "action": "aws:downloadContent",
      "name": "downloadContent",
      "inputs": {
        "sourceType": "GitHub",
        "sourceInfo": "{\"owner\":\"TestUser1\",\"repository\":\"TestPublic\", \"path\":\"documents/bootstrap/StateManagerBootstrap.yml\"}",
        "destinationPath": "bootstrap"
      }
    },
    {
      "action": "aws:runDocument",
      "name": "runDocument",
      "inputs": {
        "documentType": "LocalPath",
        "documentPath": "bootstrap",
        "documentParameters": "{}"
      }
    },
    {
      "action": "aws:runDocument",
      "name": "configureDocker",
      "inputs": {
        "documentType": "SSMDocument",
        "documentPath": "AWS-ConfigureDocker",
        "documentParameters": "{\"action\":\"Install\"}"
      }
    }
  ]
}
```

**More info**  
+ For information about rebooting servers and instances when using Run Command to call scripts, see [Handling reboots when running commands](send-commands-reboot.md).
+ For more information about the plugins you can add to a custom SSM document, see [Command document plugin reference](documents-command-ssm-plugin-reference.md).
+ If you simply want to run a document from a remote location (without creating a composite document), see [Running documents from remote locations](documents-running-remote-github-s3.md).

# Working with documents
<a name="documents-using"></a>

This section includes information about how to use and work with SSM documents.

**Topics**
+ [Compare SSM document versions](comparing-versions.md)
+ [Create an SSM document](create-ssm-console.md)
+ [Deleting custom SSM documents](deleting-documents.md)
+ [Running documents from remote locations](documents-running-remote-github-s3.md)
+ [Sharing SSM documents](documents-ssm-sharing.md)
+ [Searching for SSM documents](ssm-documents-searching.md)

# Compare SSM document versions
<a name="comparing-versions"></a>

You can compare the differences in content between versions of AWS Systems Manager (SSM) documents in the Systems Manager Documents console. When comparing versions of an SSM document, differences between the content of the versions are highlighted.

**To compare SSM document content (console)**

1. Open the AWS Systems Manager console at [https://console.aws.amazon.com/systems-manager/](https://console.aws.amazon.com/systems-manager/).

1. In the navigation pane, choose **Documents**.

1. In the documents list, choose the document whose content you want to compare.

1. On the **Content** tab, select **Compare versions**, and choose the version of the document you want to compare the content to.

# Create an SSM document
<a name="create-ssm-console"></a>

After you create the content for your custom SSM document, as described in [Writing SSM document content](documents-creating-content.md#writing-ssm-doc-content), you can use the Systems Manager console to create an SSM document using your content.

**To create an SSM document**

1. Open the AWS Systems Manager console at [https://console.aws.amazon.com/systems-manager/](https://console.aws.amazon.com/systems-manager/).

1. In the navigation pane, choose **Documents**.

1. Choose **Create command or session**.

1. Enter a descriptive name for the document.

1. (Optional) For **Target type**, specify the type of resources the document can run on.

1. In the **Document type** list, choose the type of document you want to create.

1. Delete the brackets in the **Content** field, and then paste the document content you created earlier.

1. (Optional) In the **Document tags** section, apply one or more tag key name/value pairs to the document.

   Tags are optional metadata that you assign to a resource. Tags allow you to categorize a resource in different ways, such as by purpose, owner, or environment. For example, you might want to tag a document to identify the type of tasks it runs, the type of operating systems it targets, and the environment it runs in. In this case, you could specify the following key name/value pairs:
   + `Key=TaskType,Value=MyConfigurationUpdate`
   + `Key=OS,Value=AMAZON_LINUX_2`
   + `Key=Environment,Value=Production`

1. Choose **Create document** to save the document.

# Deleting custom SSM documents
<a name="deleting-documents"></a>

If you no longer want to use a custom SSM document, you can delete it using the AWS Systems Manager console. 

**To delete an SSM document**

1. Open the AWS Systems Manager console at [https://console.aws.amazon.com/systems-manager/](https://console.aws.amazon.com/systems-manager/).

1. In the navigation pane, choose **Documents**.

1. Select the document you want to delete.

1. Select **Delete**. When prompted to delete the document, select **Delete**.

For examples using command line tools or SDKs to delete SSM documents, see [Use `DeleteDocument` with an AWS SDK or CLI](example_ssm_DeleteDocument_section.md).

# Running documents from remote locations
<a name="documents-running-remote-github-s3"></a>

You can run AWS Systems Manager (SSM) documents from remote locations by using the `AWS-RunDocument` pre-defined SSM document. This document supports running SSM documents stored in the following locations:
+ Public and private GitHub repositories (GitHub Enterprise is not supported)
+ Amazon S3 buckets
+ Systems Manager

While you can also run remote documents by using State Manager or Automation, tools in AWS Systems Manager, the following procedure describes only how to run remote SSM documents by using AWS Systems Manager Run Command in the Systems Manager console. 

**Note**  
`AWS-RunDocument` can be used to run only command-type SSM documents, not other types such as Automation runbooks. The `AWS-RunDocument` uses the `aws:downloadContent` plugin. For more information about the `aws:downloadContent` plugin, see [`aws:downloadContent`](documents-command-ssm-plugin-reference.md#aws-downloadContent).

**Warning**  
`AWS-RunDocument` can execute document content from various sources (SSM documents, GitHub, S3, URLs). When executing remote documents, the IAM permissions evaluated are for `ssm:GetDocument` on the remote document and `ssm:SendCommand` on `AWS-RunDocument`. If you have IAM policies that deny access to specific SSM documents, users with `AWS-RunDocument` permissions can still execute those denied documents by passing the document content as parameters, which may not be subject to the same document-specific IAM restrictions.  
To properly restrict document execution, use one of these approaches:  
**Allowlist approved sources**: If you need to use nested document execution, restrict access to only approved sources using appropriate controls for each source type: IAM policies to control `ssm:GetDocument` for SSM document sources, IAM and Amazon S3 bucket policies for Amazon S3 sources, and network settings (such as VPC endpoints or security groups) for public Internet sources.
**Restrict access to AWS-RunDocument**: Deny `ssm:SendCommand` on `AWS-RunDocument` and any other documents that use the `aws:runDocument` plugin in your IAM policies to prevent nested document execution.
**Use permission boundaries**: Implement IAM permission boundaries to set maximum permissions for users, preventing them from executing unauthorized documents regardless of the execution method.
For more information about IAM best practices and permission boundaries, see [Permissions boundaries for IAM entities](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_boundaries.html) in the *AWS Identity and Access Management User Guide*.

**Before you begin**  
Before you run a remote document, you must complete the following tasks.
+ Create an SSM Command document and save it in a remote location. For more information, see [Creating SSM document content](documents-creating-content.md)
+ If you plan to run a remote document that is stored in a private GitHub repository, then you must create a Systems Manager `SecureString` parameter for your GitHub security access token. You can't access a remote document in a private GitHub repository by manually passing your token over SSH. The access token must be passed as a Systems Manager `SecureString` parameter. For more information about creating a `SecureString` parameter, see [Creating Parameter Store parameters in Systems Manager](sysman-paramstore-su-create.md).

## Run a remote document (console)
<a name="documents-running-remote-github-s3-console"></a>

**To run a remote document**

1. Open the AWS Systems Manager console at [https://console.aws.amazon.com/systems-manager/](https://console.aws.amazon.com/systems-manager/).

1. In the navigation pane, choose **Run Command**.

1. Choose **Run command**.

1. In the **Document** list, choose **`AWS-RunDocument`**.

1. In **Command parameters**, for **Source Type**, choose an option. 
   + If you choose **GitHub**, specify **Source Info** information in the following format:

     ```
     {
         "owner": "owner_name",
         "repository": "repository_name",
         "path": "path_to_document",
         "getOptions":"branch:branch_name",
         "tokenInfo": "{{ssm-secure:secure-string-token}}"
     }
     ```

     For example:

     ```
     {
         "owner":"TestUser",
         "repository":"GitHubTestExamples",
         "path":"scripts/python/test-script",
         "getOptions":"branch:exampleBranch",
         "tokenInfo":"{{ssm-secure:my-secure-string-token}}"
     }
     ```
**Note**  
`getOptions` are extra options to retrieve content from a branch other than master, or from a specific commit in the repository. `getOptions` can be omitted if you are using the latest commit in the master branch. The `branch` parameter is required only if your SSM document is stored in a branch other than `master`.  
To use the version of your SSM document in a particular *commit* in your repository, use `commitID` with `getOptions` instead of `branch`. For example:  

     ```
     "getOptions": "commitID:bbc1ddb94...b76d3bEXAMPLE",
     ```
   + If you choose **S3**, specify **Source Info** information in the following format:

     ```
     {"path":"URL_to_document_in_S3"}
     ```

     For example:

     ```
     {"path":"https://s3.amazonaws.com/amzn-s3-demo-bucket/scripts/ruby/mySSMdoc.json"}
     ```
   + If you choose **SSMDocument**, specify **Source Info** information in the following format:

     ```
     {"name": "document_name"}
     ```

     For example:

     ```
     {"name": "mySSMdoc"}
     ```

1. In the **Document Parameters** field, enter parameters for the remote SSM document. For example, if you run the `AWS-RunPowerShell` document, you could specify:

   ```
   {"commands": ["date", "echo \"Hello World\""]}
   ```

   If you run the `AWS-ConfigureAWSPack` document, you could specify:

   ```
   {
      "action":"Install",
      "name":"AWSPVDriver"
   }
   ```

1. In the **Targets** section, choose the managed nodes on which you want to run this operation by specifying tags, selecting instances or edge devices manually, or specifying a resource group.
**Tip**  
If a managed node you expect to see isn't listed, see [Troubleshooting managed node availability](fleet-manager-troubleshooting-managed-nodes.md) for troubleshooting tips.

1. For **Other parameters**:
   + For **Comment**, enter information about this command.
   + For **Timeout (seconds)**, specify the number of seconds for the system to wait before failing the overall command execution. 

1. For **Rate control**:
   + For **Concurrency**, specify either a number or a percentage of managed nodes on which to run the command at the same time.
**Note**  
If you selected targets by specifying tags applied to managed nodes or by specifying AWS resource groups, and you aren't certain how many managed nodes are targeted, then restrict the number of targets that can run the document at the same time by specifying a percentage.
   + For **Error threshold**, specify when to stop running the command on other managed nodes after it fails on either a number or a percentage of nodes. For example, if you specify three errors, then Systems Manager stops sending the command when the fourth error is received. Managed nodes still processing the command might also send errors.

1. (Optional) For **Output options**, to save the command output to a file, select the **Write command output to an S3 bucket** box. Enter the bucket and prefix (folder) names in the boxes.
**Note**  
The S3 permissions that grant the ability to write the data to an S3 bucket are those of the instance profile (for EC2 instances) or IAM service role (hybrid-activated machines) assigned to the instance, not those of the IAM user performing this task. For more information, see [Configure instance permissions required for Systems Manager](setup-instance-permissions.md) or [Create an IAM service role for a hybrid environment](hybrid-multicloud-service-role.md). In addition, if the specified S3 bucket is in a different AWS account, make sure that the instance profile or IAM service role associated with the managed node has the necessary permissions to write to that bucket.

1. In the **SNS notifications** section, if you want notifications sent about the status of the command execution, select the **Enable SNS notifications** check box.

   For more information about configuring Amazon SNS notifications for Run Command, see [Monitoring Systems Manager status changes using Amazon SNS notifications](monitoring-sns-notifications.md).

1. Choose **Run**.

**Note**  
For information about rebooting servers and instances when using Run Command to call scripts, see [Handling reboots when running commands](send-commands-reboot.md).

# Sharing SSM documents
<a name="documents-ssm-sharing"></a>

You can share AWS Systems Manager (SSM) documents privately or publicly with accounts in the same AWS Region. To privately share a document, you modify the document permissions and allow specific individuals to access it according to their AWS account ID. To publicly share an SSM document, you modify the document permissions and specify `All`. Documents can't be simultaneously shared publicly and privately.

**Warning**  
Use shared SSM documents only from trusted sources. When using any shared document, carefully review the contents of the document before using it so that you understand how it will change the configuration of your instance. For more information about shared document best practices, see [Best practices for shared SSM documents](#best-practices-shared). 

**Limitations**  
As you begin working with SSM documents, be aware of the following limitations.
+ Only the owner can share a document.
+ You must stop sharing a document before you can delete it. For more information, see [Modify permissions for a shared SSM document](#modify-permissions-shared).
+ You can share a document with a maximum of 1000 AWS accounts. You can request an increase to this limit in the [Support Center](https://console.aws.amazon.com/support/home#/case/create?issueType=service-limit-increase). For **Limit type**, choose *EC2 Systems Manager* and describe your reason for the request.
+ You can publicly share a maximum of five SSM documents. You can request an increase to this limit in the [Support Center](https://console.aws.amazon.com/support/home#/case/create?issueType=service-limit-increase). For **Limit type**, choose *EC2 Systems Manager* and describe your reason for the request.
+ Documents can be shared with other accounts in the same AWS Region only. Cross-Region sharing isn't supported.

**Important**  
In Systems Manager, an *Amazon-owned* SSM document is a document created and managed by Amazon Web Services itself. *Amazon-owned* documents include a prefix like `AWS-*` in the document name. The owner of the document is considered to be Amazon, not a specific user account within AWS. These documents are publicly available for all to use.

For more information about Systems Manager service quotas, see [AWS Systems Manager Service Quotas](https://docs.aws.amazon.com/general/latest/gr/ssm.html#limits_ssm).

**Topics**
+ [Best practices for shared SSM documents](#best-practices-shared)
+ [Block public sharing for SSM documents](#block-public-access)
+ [Share an SSM document](#ssm-how-to-share)
+ [Modify permissions for a shared SSM document](#modify-permissions-shared)
+ [Using shared SSM documents](#using-shared-documents)

## Best practices for shared SSM documents
<a name="best-practices-shared"></a>

Review the following guidelines before you share or use a shared document. 

**Remove sensitive information**  
Review your AWS Systems Manager (SSM) document carefully and remove any sensitive information. For example, verify that the document doesn't include your AWS credentials. If you share a document with specific individuals, those users can view the information in the document. If you share a document publicly, anyone can view the information in the document.

**Block public sharing for documents**  
Review all publicly shared SSM documents in your account and confirm whether you want to continue sharing them. To stop sharing a document with the public, you must modify the document permission setting as described in the [Modify permissions for a shared SSM document](#modify-permissions-shared) section of this topic. Turning on the block public sharing setting doesn't affect any documents you're currently sharing with the public. Unless your use case requires you to share documents with the public, we recommend turning on the block public sharing setting for your SSM documents in the **Preferences** section of the Systems Manager Documents console. Turning on this setting prevents unwanted access to your SSM documents. The block public sharing setting is an account level setting that can differ for each AWS Region.

**Restrict Run Command actions using an IAM trust policy**  
Create a restrictive AWS Identity and Access Management (IAM) policy for users who will have access to the document. The IAM policy determines which SSM documents a user can see in either the Amazon Elastic Compute Cloud (Amazon EC2) console or by calling `ListDocuments` using the AWS Command Line Interface (AWS CLI) or AWS Tools for Windows PowerShell. The policy also restricts the actions the user can perform with SSM documents. You can create a restrictive policy so that a user can only use specific documents. For more information, see [Customer managed policy examples](security_iam_id-based-policy-examples.md#customer-managed-policies).

**Use caution when using shared SSM documents**  
Review the contents of every document that is shared with you, especially public documents, to understand the commands that will be run on your instances. A document could intentionally or unintentionally have negative repercussions after it's run. If the document references an external network, review the external source before you use the document. 

**Send commands using the document hash**  
When you share a document, the system creates a Sha-256 hash and assigns it to the document. The system also saves a snapshot of the document content. When you send a command using a shared document, you can specify the hash in your command to ensure that the following conditions are true:  
+ You're running a command from the correct Systems Manager document
+ The content of the document hasn't changed since it was shared with you.
If the hash doesn't match the specified document or if the content of the shared document has changed, the command returns an `InvalidDocument` exception. The hash can't verify document content from external locations.

**Use the interpolation parameter to improve security**  
For `String` type parameters in your SSM documents, use the parameter and value `interpolationType": "ENV_VAR` to improve security against command injection attacks by treating parameter inputs as string literals rather than potentially executable commands. In this case, the agent creates an environment variable named `SSM_parameter-name` with the parameter's value. We recommend updating all your existing SSM documents that include `String` type parameters to include `"interpolationType": "ENV_VAR"`. For more information, see [Writing SSM document content](documents-creating-content.md#writing-ssm-doc-content).

## Block public sharing for SSM documents
<a name="block-public-access"></a>

Before you begin, review all publicly shared SSM documents in your AWS account and confirm whether you want to continue sharing them. To stop sharing an SSM document with the public, you must modify the document permission setting as described in the [Modify permissions for a shared SSM document](#modify-permissions-shared) section of this topic. Turning on the block public sharing setting doesn't affect any SSM documents you're currently sharing with the public. With the block public sharing setting enabled, you won’t be able to share any additional SSM documents with the public.

Unless your use case requires you to share documents with the public, we recommend turning on the block public sharing setting for your SSM documents. Turning on this setting prevents unwanted access to your SSM documents. The block public sharing setting is an account level setting that can differ for each AWS Region. Complete the following tasks to block public sharing for any SSM documents you're not currently sharing.

### Block public sharing (console)
<a name="block-public-access-console"></a>

**To block public sharing of your SSM documents**

1. Open the AWS Systems Manager console at [https://console.aws.amazon.com/systems-manager/](https://console.aws.amazon.com/systems-manager/).

1. In the navigation pane, choose **Documents**.

1. Choose **Preferences**, and then choose **Edit** in the **Block public sharing** section.

1. Select the **Block public sharing** check box, and then choose **Save**. 

### Block public sharing (command line)
<a name="block-public-access-cli"></a>

Open the AWS Command Line Interface (AWS CLI) or AWS Tools for Windows PowerShell on your local computer and run the following command to block public sharing of your SSM documents.

------
#### [ Linux & macOS ]

```
aws ssm update-service-setting  \
    --setting-id /ssm/documents/console/public-sharing-permission \
    --setting-value Disable \
    --region 'The AWS Region you want to block public sharing in'
```

------
#### [ Windows ]

```
aws ssm update-service-setting ^
    --setting-id /ssm/documents/console/public-sharing-permission ^
    --setting-value Disable ^
    --region "The AWS Region you want to block public sharing in"
```

------
#### [ PowerShell ]

```
Update-SSMServiceSetting `
    -SettingId /ssm/documents/console/public-sharing-permission `
    -SettingValue Disable `
    –Region The AWS Region you want to block public sharing in
```

------

Confirm the setting value was updated using the following command.

------
#### [ Linux & macOS ]

```
aws ssm get-service-setting   \
    --setting-id /ssm/documents/console/public-sharing-permission \
    --region The AWS Region you blocked public sharing in
```

------
#### [ Windows ]

```
aws ssm get-service-setting  ^
    --setting-id /ssm/documents/console/public-sharing-permission ^
    --region "The AWS Region you blocked public sharing in"
```

------
#### [ PowerShell ]

```
Get-SSMServiceSetting `
    -SettingId /ssm/documents/console/public-sharing-permission `
    -Region The AWS Region you blocked public sharing in
```

------

### Restricting access to block public sharing with IAM
<a name="block-public-access-changes-iam"></a>

You can create AWS Identity and Access Management (IAM) policies that restrict users from modifying the block public sharing setting. This prevents users from allowing unwanted access to your SSM documents. 

The following is an example of an IAM policy that prevents users from updating the block public sharing setting. To use this example, you must replace the example Amazon Web Services account ID with your own account ID.

------
#### [ JSON ]

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Effect": "Deny",
            "Action": "ssm:UpdateServiceSetting",
            "Resource": "arn:aws:ssm:*:444455556666:servicesetting/ssm/documents/console/public-sharing-permission"
        }
    ]
}
```

------

## Share an SSM document
<a name="ssm-how-to-share"></a>

You can share AWS Systems Manager (SSM) documents by using the Systems Manager console. When sharing documents from the console, only the default version of the document can be shared. You can also share SSM documents programmatically by calling the `ModifyDocumentPermission` API operation using the AWS Command Line Interface (AWS CLI), AWS Tools for Windows PowerShell, or the AWS SDK. Before you share a document, get the AWS account IDs of the people with whom you want to share. You will specify these account IDs when you share the document.

### Share a document (console)
<a name="share-using-console"></a>

1. Open the AWS Systems Manager console at [https://console.aws.amazon.com/systems-manager/](https://console.aws.amazon.com/systems-manager/).

1. In the navigation pane, choose **Documents**.

1. In the documents list, choose the document you want to share, and then choose **View details**. On the **Permissions** tab, verify that you're the document owner. Only a document owner can share a document.

1. Choose **Edit**.

1. To share the command publicly, choose **Public** and then choose **Save**. To share the command privately, choose **Private**, enter the AWS account ID, choose **Add permission**, and then choose **Save**. 

### Share a document (command line)
<a name="share-using-cli"></a>

The following procedure requires that you specify an AWS Region for your command line session.

1. Open the AWS CLI or AWS Tools for Windows PowerShell on your local computer and run the following command to specify your credentials. 

   In the following command, replace *region* with your own information. For a list of supported *region* values, see the **Region** column in [Systems Manager service endpoints](https://docs.aws.amazon.com/general/latest/gr/ssm.html#ssm_region) in the *Amazon Web Services General Reference*.

------
#### [ Linux & macOS ]

   ```
   aws config
   
   AWS Access Key ID: [your key]
   AWS Secret Access Key: [your key]
   Default region name: region
   Default output format [None]:
   ```

------
#### [ Windows ]

   ```
   aws config
   
   AWS Access Key ID: [your key]
   AWS Secret Access Key: [your key]
   Default region name: region
   Default output format [None]:
   ```

------
#### [ PowerShell ]

   ```
   Set-AWSCredentials –AccessKey your key –SecretKey your key
   Set-DefaultAWSRegion -Region region
   ```

------

1. Use the following command to list all of the SSM documents that are available for you. The list includes documents that you created and documents that were shared with you.

------
#### [ Linux & macOS ]

   ```
   aws ssm list-documents
   ```

------
#### [ Windows ]

   ```
   aws ssm list-documents
   ```

------
#### [ PowerShell ]

   ```
   Get-SSMDocumentList
   ```

------

1. Use the following command to get a specific document.

------
#### [ Linux & macOS ]

   ```
   aws ssm get-document \
       --name document name
   ```

------
#### [ Windows ]

   ```
   aws ssm get-document ^
       --name document name
   ```

------
#### [ PowerShell ]

   ```
   Get-SSMDocument `
       –Name document name
   ```

------

1. Use the following command to get a description of the document.

------
#### [ Linux & macOS ]

   ```
   aws ssm describe-document \
       --name document name
   ```

------
#### [ Windows ]

   ```
   aws ssm describe-document ^
       --name document name
   ```

------
#### [ PowerShell ]

   ```
   Get-SSMDocumentDescription `
       –Name document name
   ```

------

1. Use the following command to view the permissions for the document.

------
#### [ Linux & macOS ]

   ```
   aws ssm describe-document-permission \
       --name document name \
       --permission-type Share
   ```

------
#### [ Windows ]

   ```
   aws ssm describe-document-permission ^
       --name document name ^
       --permission-type Share
   ```

------
#### [ PowerShell ]

   ```
   Get-SSMDocumentPermission `
       –Name document name `
       -PermissionType Share
   ```

------

1. Use the following command to modify the permissions for the document and share it. You must be the owner of the document to edit the permissions. Optionally, for documents shared with specific AWS account IDs, you can specify a version of the document you want to share using the `--shared-document-version` parameter. If you don't specify a version, the system shares the `Default` version of the document. If you share a document publicly (with `all`), all versions of the specified document are shared by default. The following example command privately shares the document with a specific individual, based on that person's AWS account ID.

------
#### [ Linux & macOS ]

   ```
   aws ssm modify-document-permission \
       --name document name \
       --permission-type Share \
       --account-ids-to-add AWS account ID
   ```

------
#### [ Windows ]

   ```
   aws ssm modify-document-permission ^
       --name document name ^
       --permission-type Share ^
       --account-ids-to-add AWS account ID
   ```

------
#### [ PowerShell ]

   ```
   Edit-SSMDocumentPermission `
       –Name document name `
       -PermissionType Share `
       -AccountIdsToAdd AWS account ID
   ```

------

1. Use the following command to share a document publicly.
**Note**  
If you share a document publicly (with `all`), all versions of the specified document are shared by default. 

------
#### [ Linux & macOS ]

   ```
   aws ssm modify-document-permission \
       --name document name \
       --permission-type Share \
       --account-ids-to-add 'all'
   ```

------
#### [ Windows ]

   ```
   aws ssm modify-document-permission ^
       --name document name ^
       --permission-type Share ^
       --account-ids-to-add "all"
   ```

------
#### [ PowerShell ]

   ```
   Edit-SSMDocumentPermission `
       -Name document name `
       -PermissionType Share `
       -AccountIdsToAdd ('all')
   ```

------

## Modify permissions for a shared SSM document
<a name="modify-permissions-shared"></a>

If you share a command, users can view and use that command until you either remove access to the AWS Systems Manager (SSM) document or delete the SSM document. However, you can't delete a document as long as it's shared. You must stop sharing it first and then delete it.

### Stop sharing a document (console)
<a name="unshare-using-console"></a>

**Stop sharing a document**

1. Open the AWS Systems Manager console at [https://console.aws.amazon.com/systems-manager/](https://console.aws.amazon.com/systems-manager/).

1. In the navigation pane, choose **Documents**.

1. In the documents list, choose the document you want to stop sharing, and then choose the **Details**. In the **Permissions** section, verify that you're the document owner. Only a document owner can stop sharing a document.

1. Choose **Edit**.

1. Choose **X** to delete the AWS account ID that should no longer have access to the command, and then choose **Save**. 

### Stop sharing a document (command line)
<a name="unshare-using-cli"></a>

Open the AWS CLI or AWS Tools for Windows PowerShell on your local computer and run the following command to stop sharing a command.

------
#### [ Linux & macOS ]

```
aws ssm modify-document-permission \
    --name document name \
    --permission-type Share \
    --account-ids-to-remove 'AWS account ID'
```

------
#### [ Windows ]

```
aws ssm modify-document-permission ^
    --name document name ^
    --permission-type Share ^
    --account-ids-to-remove "AWS account ID"
```

------
#### [ PowerShell ]

```
Edit-SSMDocumentPermission `
    -Name document name `
    -PermissionType Share `
    –AccountIdsToRemove AWS account ID
```

------

## Using shared SSM documents
<a name="using-shared-documents"></a>

When you share an AWS Systems Manager (SSM) document, the system generates an Amazon Resource Name (ARN) and assigns it to the command. If you select and run a shared document from the Systems Manager console, you don't see the ARN. However, if you want to run a shared SSM document using a method other than the Systems Manager console, you must specify the full ARN of the document for the `DocumentName` request parameter. You're shown the full ARN for an SSM document when you run the command to list documents. 

**Note**  
You aren't required to specify ARNs for AWS public documents (documents that begin with `AWS-*`) or documents that you own.

### Use a shared SSM document (command line)
<a name="using-shared-documents-cli"></a>

 **To list all public SSM documents** 

------
#### [ Linux & macOS ]

```
aws ssm list-documents \
    --filters Key=Owner,Values=Public
```

------
#### [ Windows ]

```
aws ssm list-documents ^
    --filters Key=Owner,Values=Public
```

------
#### [ PowerShell ]

```
$filter = New-Object Amazon.SimpleSystemsManagement.Model.DocumentKeyValuesFilter
$filter.Key = "Owner"
$filter.Values = "Public"

Get-SSMDocumentList `
    -Filters @($filter)
```

------

 **To list private SSM documents that have been shared with you** 

------
#### [ Linux & macOS ]

```
aws ssm list-documents \
    --filters Key=Owner,Values=Private
```

------
#### [ Windows ]

```
aws ssm list-documents ^
    --filters Key=Owner,Values=Private
```

------
#### [ PowerShell ]

```
$filter = New-Object Amazon.SimpleSystemsManagement.Model.DocumentKeyValuesFilter
$filter.Key = "Owner"
$filter.Values = "Private"

Get-SSMDocumentList `
    -Filters @($filter)
```

------

 **To list all SSM documents available to you** 

------
#### [ Linux & macOS ]

```
aws ssm list-documents
```

------
#### [ Windows ]

```
aws ssm list-documents
```

------
#### [ PowerShell ]

```
Get-SSMDocumentList
```

------

 **To get information about an SSM document that has been shared with you** 

------
#### [ Linux & macOS ]

```
aws ssm describe-document \
    --name arn:aws:ssm:us-east-2:12345678912:document/documentName
```

------
#### [ Windows ]

```
aws ssm describe-document ^
    --name arn:aws:ssm:us-east-2:12345678912:document/documentName
```

------
#### [ PowerShell ]

```
Get-SSMDocumentDescription `
    –Name arn:aws:ssm:us-east-2:12345678912:document/documentName
```

------

 **To run a shared SSM document** 

------
#### [ Linux & macOS ]

```
aws ssm send-command \
    --document-name arn:aws:ssm:us-east-2:12345678912:document/documentName \
    --instance-ids ID
```

------
#### [ Windows ]

```
aws ssm send-command ^
    --document-name arn:aws:ssm:us-east-2:12345678912:document/documentName ^
    --instance-ids ID
```

------
#### [ PowerShell ]

```
Send-SSMCommand `
    –DocumentName arn:aws:ssm:us-east-2:12345678912:document/documentName `
    –InstanceIds ID
```

------

# Searching for SSM documents
<a name="ssm-documents-searching"></a>

You can search the AWS Systems Manager (SSM) document store for SSM documents by using either free text search or a filter-based search. You can also favorite documents to help you find frequently used SSM documents. The following sections describes how to use these features.

## Using free text search
<a name="ssm-documents-searching-free-text"></a>

The search box on the Systems Manager **Documents** page supports free text search. Free text search compares the search term or terms that you enter against the document name in each SSM document. If you enter a single search term, for example **ansible**, then Systems Manager returns all SSM documents where this term was discovered. If you enter multiple search terms, then Systems Manager searches by using an `OR` statement. For example, if you specify **ansible** and **linux**, then search returns all documents with *either* keyword in their name.

If you enter a free text search term and choose a search option, such as **Platform type**, then search uses an `AND` statement and returns all documents with the keyword in their name and the specified platform type.

**Note**  
Note the following details about free text search.  
Free text search is *not* case sensitive.
Search terms require a minimum of three characters and have a maximum of 20 characters.
Free text search accepts up to five search terms.
If you enter a space between search terms, the system includes the space when searching.
You can combine free text search with other search options such as **Document type** or **Platform type**.
The **Document Name Prefix** filter and free text search can't be used together. they're mutually exclusive.

**To search for an SSM document**

1. Open the AWS Systems Manager console at [https://console.aws.amazon.com/systems-manager/](https://console.aws.amazon.com/systems-manager/).

1. In the navigation pane, choose **Documents**.

1. Enter your search terms in the search box, and press Enter.

### Performing free text document search by using the AWS CLI
<a name="ssm-documents-searching-free-text-cli"></a>

**To perform a free text document search by using the CLI**

1. Install and configure the AWS Command Line Interface (AWS CLI), if you haven't already.

   For information, see [Installing or updating the latest version of the AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html).

1. To perform free text document search with a single term, run the following command. In this command, replace *search\$1term* with your own information.

   ```
   aws ssm list-documents --filters Key="SearchKeyword",Values="search_term"
   ```

   Here's an example.

   ```
   aws ssm list-documents --filters Key="SearchKeyword",Values="aws-asg" --region us-east-2
   ```

   To search using multiple terms that create an `AND` statement, run the following command. In this command, replace *search\$1term\$11* and *search\$1term\$12* with your own information.

   ```
   aws ssm list-documents --filters Key="SearchKeyword",Values="search_term_1","search_term_2","search_term_3" --region us-east-2
   ```

   Here's an example.

   ```
   aws ssm list-documents --filters Key="SearchKeyword",Values="aws-asg","aws-ec2","restart" --region us-east-2
   ```

## Using filters
<a name="ssm-documents-searching-filters"></a>

The Systems Manager **Documents** page automatically displays the following filters when you choose the search box. 
+ Document name prefix
+ Platform types
+ Document type
+ Tag key

![\[Filter options on SSM Documents page.\]](http://docs.aws.amazon.com/systems-manager/latest/userguide/images/ssm-documents-filters-1.png)


You can search for SSM documents by using a single filter. If you want to return a more specific set of SSM documents, you can apply multiple filters. Here is an example of a search that uses the **Platform types** and the **Document name prefix** filters.

![\[Applying multiple filter options on the SSM Documents page.\]](http://docs.aws.amazon.com/systems-manager/latest/userguide/images/ssm-documents-filters-2.png)


If you apply multiple filters, Systems Manager creates different search statements based on the filters you choose: 
+ If you apply the *same* filter multiple times, for example **Document name prefix**, then Systems Manager searches by using an `OR` statement. For example, if you specify one filter of **Document name prefix**=**AWS** and a second filter of **Document name prefix**=**Lambda**, then search returns all documents with the prefix "`AWS`" and all documents with the prefix "`Lambda`".
+ If you apply *different* filters, for example **Document name prefix** and **Platform types**, then Systems Manager searches by using an `AND` statement. For example, if you specify a **Document name prefix**=**AWS** filter and a **Platform types**=**Linux** filter, then search returns all documents with the prefix "`AWS`" that are specific to the Linux platform.

**Note**  
Searches that use filters are case sensitive. 

## Adding documents to your favorites
<a name="favorite-documents"></a>

To help you find frequently used SSM documents, add documents to your favorites. You can favorite up to 20 documents per document type, per AWS account and AWS Region. You can choose, modify, and view your favorites from the documents AWS Management Console. The following procedures describe how to choose, modify, and view your favorites.

**To favorite an SSM document**

1. Open the AWS Systems Manager console at [https://console.aws.amazon.com/systems-manager/](https://console.aws.amazon.com/systems-manager/).

1. In the navigation pane, choose **Documents**.

1. Select the star icon next to the document name you want to favorite.

**To remove an SSM document from your favorites**

1. Open the AWS Systems Manager console at [https://console.aws.amazon.com/systems-manager/](https://console.aws.amazon.com/systems-manager/).

1. In the navigation pane, choose **Documents**.

1. Deselect the star icon next to the document name you want to remove from your favorites.

**To view your favorites from the documents AWS Management Console**

1. Open the AWS Systems Manager console at [https://console.aws.amazon.com/systems-manager/](https://console.aws.amazon.com/systems-manager/).

1. In the navigation pane, choose **Documents**.

1. Select the **Favorites** tab.

# Troubleshooting parameter handling issues
<a name="parameter-troubleshooting"></a>

## Common parameter handling issues
<a name="common-parameter-issues"></a>

**Environment variables not available during execution**  
**Problem:** Commands fail because environment variables (`SSM_parameter-name`) are not found.  
**Possible causes:**  
+ SSM Agent version doesn't support environment variable interpolation
+ `interpolationType` is not set to `ENV_VAR`
+ Parameter name doesn't match the expected environment variable name
**Solution:**  
+ Verify SSM Agent version is 3.3.2746.0 or later
+ Add fallback logic for older agent versions:

  ```
  if [ -z "${SSM_parameterName+x}" ]; then
      export SSM_parameterName="{{parameterName}}"
  fi
  ```

**Parameter values containing special characters**  
**Problem:** Commands fail when parameter values contain spaces, quotes, or other special characters.  
**Solution:**  
+ Use proper quoting when referencing environment variables:

  ```
  # Correct
  echo "$SSM_parameter-name"
  
  # Incorrect
  echo $SSM_parameter-name
  ```
+ Add input validation using `allowedPattern` to restrict special characters

**Inconsistent behavior across platforms**  
**Problem:** Parameter handling works differently on Linux and Windows Server systems.  
**Solution:**  
+ Use platform-specific environment variable syntax:

  ```
  # PowerShell
  $env:SSM_parameter-name
  
  # Bash
  $SSM_parameter-name
  ```
+ Use platform-specific precondition checks in your document

**Parameter values not properly escaped**  
**Problem:** Command injection vulnerabilities despite using environment variable interpolation.  
**Solution:**  
+ Always use proper escaping when including parameter values in commands:

  ```
  # Correct
  mysql_command="mysql -u \"$SSM_username\" -p\"$SSM_password\""
  
  # Incorrect
  mysql_command="mysql -u $SSM_username -p$SSM_password"
  ```

## Parameter validation tips
<a name="parameter-validation"></a>

Use these techniques to validate your parameter handling:

1. Test environment variable availability:

   ```
   #!/bin/bash
   # Print all SSM_ environment variables
   env | grep ^SSM_
   
   # Test specific parameter
   if [ -n "$SSM_parameter" ]; then
       echo "Parameter is available"
   else
       echo "Parameter is not available"
   fi
   ```

1. Verify parameter patterns:

   ```
   parameters:
     myParameter:
       type: String
       allowedPattern: "^[a-zA-Z0-9_-]+$"
       description: "Test this pattern with sample inputs"
   ```

1. Include error handling:

   ```
   if [[ ! "$SSM_parameter" =~ ^[a-zA-Z0-9_-]+$ ]]; then
       echo "Parameter validation failed"
       exit 1
   fi
   ```

# AWS Systems Manager Maintenance Windows
<a name="maintenance-windows"></a>

Maintenance Windows, a tool in AWS Systems Manager, helps you define a schedule for when to perform potentially disruptive actions on your nodes such as patching an operating system, updating drivers, or installing software or patches.

**Note**  
State Manager and Maintenance Windows can perform some similar types of updates on your managed nodes. Which one you choose depends on whether you need to automate system compliance or perform high-priority, time-sensitive tasks during periods you specify.  
For more information, see [Choosing between State Manager and Maintenance Windows](state-manager-vs-maintenance-windows.md).

With Maintenance Windows, you can schedule actions on numerous other AWS resource types, such as Amazon Simple Storage Service (Amazon S3) buckets, Amazon Simple Queue Service (Amazon SQS) queues, AWS Key Management Service (AWS KMS) keys, and many more. 

For a full list of supported resource types that you can include in a maintenance window target, see [Resources you can use with AWS Resource Groups and Tag Editor](https://docs.aws.amazon.com/ARG/latest/userguide/supported-resources.html#supported-resources-console) in the *AWS Resource Groups User Guide*. To get started with Maintenance Windows, open the [Systems Manager console](https://console.aws.amazon.com//systems-manager/maintenance-windows). In the navigation pane, choose **Maintenance Windows**.

Each maintenance window has a schedule, a maximum duration, a set of registered targets (the managed nodes or other AWS resources that are acted upon), and a set of registered tasks. You can add tags to your maintenance windows when you create or update them. (Tags are keys that help identify and sort your resources within your organization.) You can also specify dates that a maintenance window shouldn't run before or after, and you can specify the international time zone on which to base the maintenance window schedule. 

For an explanation of how the various schedule-related options for maintenance windows relate to one another, see [Maintenance window scheduling and active period options](maintenance-windows-schedule-options.md).

For more information about working with the `--schedule` option, see [Reference: Cron and rate expressions for Systems Manager](reference-cron-and-rate-expressions.md).

**Supported task types**  
With maintenance windows, you can run four types of tasks:
+ Commands in Run Command, a tool in Systems Manager

  For more information about Run Command, see [AWS Systems Manager Run Command](run-command.md).
+ Workflows in Automation, a tool in Systems Manager

  For more information about Automation workflows, see [AWS Systems Manager Automation](systems-manager-automation.md).
+ Functions in AWS Lambda

  For more information about Lambda functions, see [Getting started with Lambda](https://docs.aws.amazon.com/lambda/latest/dg/getting-started.html) in the *AWS Lambda Developer Guide*.
+ Tasks in AWS Step Functions
**Note**  
Maintenance window tasks support Step Functions Standard state machine workflows only. They don't support Express state machine workflows. For information about state machine workflow types, see [Standard vs. Express Workflows](https://docs.aws.amazon.com/step-functions/latest/dg/concepts-standard-vs-express.html) in the *AWS Step Functions Developer Guide*.

  For more information about Step Functions, see the *[AWS Step Functions Developer Guide](https://docs.aws.amazon.com/step-functions/latest/dg/)*.

This means you can use maintenance windows to perform tasks such as the following on your selected targets.
+ Install or update applications.
+ Apply patches.
+ Install or update SSM Agent.
+ Run PowerShell commands and Linux shell scripts by using a Systems Manager Run Command task.
+ Build Amazon Machine Images (AMIs), boot-strap software, and configure nodes by using a Systems Manager Automation task.
+ Run AWS Lambda functions that invokes additional actions, such as scanning your nodes for patch updates.
+ Run AWS Step Functions state machines to perform tasks such as removing a node from an Elastic Load Balancing environment, patching the node, and then adding the node back to the Elastic Load Balancing environment.
+ Target nodes that are offline by specifying an AWS resource group as the target.

**Note**  
One or more targets must be specified for maintenance window Run Command-type tasks. Depending on the task, targets are optional for other maintenance window task types (Automation, AWS Lambda, and AWS Step Functions). For more information about running tasks that don't specify targets, see [Registering maintenance window tasks without targets](maintenance-windows-targetless-tasks.md).

**EventBridge support**  
This Systems Manager tool is supported as an *event* type in Amazon EventBridge rules. For information, see [Monitoring Systems Manager events with Amazon EventBridge](monitoring-eventbridge-events.md) and [Reference: Amazon EventBridge event patterns and types for Systems Manager](reference-eventbridge-events.md).

**Topics**
+ [Setting up Maintenance Windows](setting-up-maintenance-windows.md)
+ [Create and manage maintenance windows using the console](sysman-maintenance-working.md)
+ [Tutorials](maintenance-windows-tutorials.md)
+ [Using pseudo parameters when registering maintenance window tasks](maintenance-window-tasks-pseudo-parameters.md)
+ [Maintenance window scheduling and active period options](maintenance-windows-schedule-options.md)
+ [Registering maintenance window tasks without targets](maintenance-windows-targetless-tasks.md)
+ [Troubleshooting maintenance windows](troubleshooting-maintenance-windows.md)

# Setting up Maintenance Windows
<a name="setting-up-maintenance-windows"></a>

Before users in your AWS account can create and schedule maintenance window tasks using Maintenance Windows, a tool in AWS Systems Manager, they must be granted the necessary permissions. In addition, you must create an IAM service role for maintenance windows and the IAM policy to attach to it.

**Before you begin**  
In addition to the permissions you configure in this section, the IAM Entities (users, roles, or groups that will work with maintenance windows should already have general maintenance window permissions. You can grant these permissions by assigning the IAM policy `AmazonSSMFullAccess` to the Entities, or assigning a custom IAM policy that provides a smaller set of access permissions for Systems Manager that covers maintenance window tasks.

**Topics**
+ [Control access to maintenance windows using the console](configuring-maintenance-window-permissions-console.md)
+ [Control access to maintenance windows using the AWS CLI](configuring-maintenance-window-permissions-cli.md)

# Control access to maintenance windows using the console
<a name="configuring-maintenance-window-permissions-console"></a>

The following procedures describe how to use the AWS Systems Manager console to create the required permissions and roles for maintenance windows.

**Topics**
+ [Task 1: Create a custom policy for your maintenance window service role using the console](#create-custom-policy-console)
+ [Task 2: Create a custom service role for maintenance windows using the console](#create-custom-role-console)
+ [Task 3: Grant permissions to specified users to register maintenance window tasks using the console](#allow-maintenance-window-access-console)
+ [Task 4: Prevent specified users from registering maintenance window tasks using the console](#deny-maintenance-window-access-console)

## Task 1: Create a custom policy for your maintenance window service role using the console
<a name="create-custom-policy-console"></a>

Maintenance window tasks require an IAM role to provide the permissions required to run on the target resources. The permissions are provided through an IAM policy attached to the role. The types of tasks you run and your other operational requirements determine the contents of this policy. We provide a base policy you can adapt to your needs. Depending on the tasks and types of tasks your maintenance windows run, you might not need all the permissions in this policy, and you might need to include additional permissions. You attach this policy to the role that you create later in [Task 2: Create a custom service role for maintenance windows using the console](#create-custom-role-console).

**To create a custom policy using the console**

1. Open the IAM console at [https://console.aws.amazon.com/iam/](https://console.aws.amazon.com/iam/).

1. In the navigation pane, choose **Policies**, and then choose **Create policy**.

1. In the **Policy editor** area, choose **JSON**.

1. Replace the default contents with the following:

------
#### [ JSON ]

****  

   ```
   {
       "Version":"2012-10-17",		 	 	 
       "Statement": [
           {
               "Effect": "Allow",
               "Action": [
                   "ssm:SendCommand",
                   "ssm:CancelCommand",
                   "ssm:ListCommands",
                   "ssm:ListCommandInvocations",
                   "ssm:GetCommandInvocation",
                   "ssm:GetAutomationExecution",
                   "ssm:StartAutomationExecution",
                   "ssm:ListTagsForResource",
                   "ssm:DescribeInstanceInformation",
                   "ssm:GetParameters"
               ],
               "Resource": "*"
           },
           {
               "Effect": "Allow",
               "Action": [
                   "states:DescribeExecution",
                   "states:StartExecution"
               ],
               "Resource": [
                   "arn:aws:states:*:*:execution:*:*",
                   "arn:aws:states:*:*:stateMachine:*"
               ]
           },
           {
               "Effect": "Allow",
               "Action": [
                   "lambda:InvokeFunction"
               ],
               "Resource": [
                   "arn:aws:lambda:*:*:function:*"
               ]
           },
           {
               "Effect": "Allow",
               "Action": [
                   "resource-groups:ListGroups",
                   "resource-groups:ListGroupResources"
               ],
               "Resource": [
                   "*"
               ]
           },
           {
               "Effect": "Allow",
               "Action": [
                   "tag:GetResources"
               ],
               "Resource": [
                   "*"
               ]
           },
           {
               "Effect": "Allow",
               "Action": "iam:PassRole",
               "Resource": "arn:aws:iam::111122223333:role/maintenance-window-role-name",
               "Condition": {
                   "StringEquals": {
                       "iam:PassedToService": [
                           "ssm.amazonaws.com"
                       ]
                   }
               }
           }
       ]
   }
   ```

------

1. Modify the JSON content as needed for the maintenance tasks that you run in your account. The changes you make are specific to your planned operations. 

   For example:
   + You can provide Amazon Resource Names (ARNs) for specific functions and state machines instead of using wildcard (\$1) qualifiers.
   + If you don’t plan to run AWS Step Functions tasks, you can remove the `states` permissions and (ARNs).
   + If you don’t plan to run AWS Lambda tasks, you can remove the `lambda` permissions and ARNs.
   + If you don't plan to run Automation tasks, you can remove the `ssm:GetAutomationExecution` and `ssm:StartAutomationExecution` permissions.
   + Add additional permissions that might be needed for the tasks to run. For example, some Automation actions work with AWS CloudFormation stacks. Therefore, the permissions `cloudformation:CreateStack`, `cloudformation:DescribeStacks`, and `cloudformation:DeleteStack` are required. 

     For another example, the Automation runbook `AWS-CopySnapshot` requires permissions to create an Amazon Elastic Block Store (Amazon EBS) snapshot. Therefore, the service role needs the permission `ec2:CreateSnapshot`. 

     For information about the role permissions needed by Automation runbooks, see the runbook descriptions in the [AWS Systems Manager Automation Runbook Reference](https://docs.aws.amazon.com/systems-manager-automation-runbooks/latest/userguide/automation-runbook-reference.html).

1. After completing the policy revisions, choose **Next**.

1. For **Policy name**, enter a name that identifies this as the policy attached to the service role you create. For example: **my-maintenance-window-role-policy**.

1. (Optional) In the **Add tags** area, add one or more tag-key value pairs to organize, track, or control access for this policy. 

1. Choose **Create policy**.

   Make a note of the name you specified for the policy. You refer to it in the next procedure, [Task 2: Create a custom service role for maintenance windows using the console](#create-custom-role-console).

## Task 2: Create a custom service role for maintenance windows using the console
<a name="create-custom-role-console"></a>

The policy you created in the previous task is attached to the maintenance window service role you create in this task. When users register a maintenance window task, they specify this IAM role as part of the task configuration. The permissions in this role allow Systems Manager to run tasks in maintenance windows on your behalf.

**Important**  
Previously, the Systems Manager console provided you with the ability to choose the AWS managed IAM service-linked role `AWSServiceRoleForAmazonSSM` to use as the maintenance role for your tasks. Using this role and its associated policy, `AmazonSSMServiceRolePolicy`, for maintenance window tasks is no longer recommended. If you're using this role for maintenance window tasks now, we encourage you to stop using it. Instead, create your own IAM role that enables communication between Systems Manager and other AWS services when your maintenance window tasks run.

Use the following procedure to create a custom service role for Maintenance Windows, so that Systems Manager can run Maintenance Windows tasks on your behalf. You attach the policy you created in the previous task to the custom service role you create.

**To create a custom service role for maintenance windows using the console**

1. Open the IAM console at [https://console.aws.amazon.com/iam/](https://console.aws.amazon.com/iam/).

1. In the navigation pane, choose **Roles**, and then choose **Create role**.

1. For **Select trusted entity**, make the following choices:

   1. For **Trusted entity type**, choose **AWS service**.

   1. For **Use case**, choose **Systems Manager**

   1. Choose **Systems Manager**.

      The following image highlights the location of the Systems Manager option.  
![\[Systems Manager is one of the options for Use case.\]](http://docs.aws.amazon.com/systems-manager/latest/userguide/images/iam_use_cases_for_MWs.png)

1. Choose **Next**. 

1. In the **Permissions policies** area, in the search box, enter the name of the policy you created in [Task 1: Create a custom policy for your maintenance window service role using the console](#create-custom-policy-console), select the box next to its name, and then choose **Next**.

1. For **Role name**, enter a name that identifies this role as a Maintenance Windows role. For example: **my-maintenance-window-role**.

1. (Optional) Change the default role description to reflect the purpose of this role. For example: **Performs maintenance window tasks on your behalf**.

1. For **Step 1: Select trusted entities**, verify that the following policy is displayed in the **Trusted policy** box.

------
#### [ JSON ]

****  

   ```
   {
     "Version":"2012-10-17",		 	 	 
     "Statement": [
       {
         "Sid": "",
         "Effect": "Allow",
         "Principal": {
           "Service": "ssm.amazonaws.com"
         },
         "Action": "sts:AssumeRole"
       }
     ]
   }
   ```

------

1. For **Step 2: Add permissions**, verify that policy you created in [Task 1: Create a custom policy for your maintenance window service role using the console](#create-custom-policy-console) is present.

1. (Optional) In **Step 3: Add tags**, add one or more tag-key value pairs to organize, track, or control access for this role. 

1. Choose **Create role**. The system returns you to the **Roles** page.

1. Choose the name of the IAM role you just created.

1. Copy or make a note of the role name and the **ARN** value in the **Summary** area. Users in your account specify this information when they create maintenance windows.

## Task 3: Grant permissions to specified users to register maintenance window tasks using the console
<a name="allow-maintenance-window-access-console"></a>

Providing users with permissions to access the custom service role for maintenance windows lets them use it with their maintenance windows tasks. This is in addition to permissions that you’ve already given them to work with the Systems Manager API commands for the Maintenance Windows tool. This IAM role conveys the permissions need to run a maintenance window task. As a result, a user can't register tasks with a maintenance window using your custom service role without the ability to pass these IAM permissions.

When you register a task with a maintenance window, you specify a service role to run the actual task operations. This is the role that the service assumes when it runs tasks on your behalf. Before that, to register the task itself, assign the IAM `PassRole` policy to an IAM entity (such as a user or group). This allows the IAM entity to specify, as part of registering those tasks with the maintenance window, the role that should be used when running tasks. For information, see [Grant a user permissions to pass a role to an AWS service](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_use_passrole.html) in the *IAM User Guide*.

**To configure permissions to allow users to register maintenance window tasks**

If an IAM entity (user, role, or group) is set up with administrator permissions, then the IAM user or role has access to Maintenance Windows. For IAM entities without administrator permissions, an administrator must grant the following permissions to the IAM entity. These are the minimum permissions required to register tasks with a maintenance window:
+ The `AmazonSSMFullAccess` managed policy, or a policy that provides comparable permissions.
+ The following `iam:PassRole` and `iam:ListRoles`permissions.

------
#### [ JSON ]

****  

  ```
  {
      "Version":"2012-10-17",		 	 	 
      "Statement": [
          {
              "Effect": "Allow",
              "Action": "iam:PassRole",
              "Resource": "arn:aws:iam::111122223333:role/my-maintenance-window-role"
          },
          {
              "Effect": "Allow",
              "Action": "iam:ListRoles",
              "Resource": "arn:aws:iam::111122223333:role/"
          },
          {
              "Effect": "Allow",
              "Action": "iam:ListRoles",
              "Resource": "arn:aws:iam::111122223333:role/aws-service-role/ssm.amazonaws.com/"
          }
      ]
  }
  ```

------

  *my-maintenance-window-role* represents the name of the custom maintenance window service role you created earlier.

  *account-id* represents the ID of your AWS account. Adding this permission for the resource `arn:aws:iam::account-id:role/` allows a user to view and choose from customer roles in the console when they create a maintenance window task. Adding this permission for `arn:aws:iam::account-id:role/aws-service-role/ssm.amazonaws.com/` allows a user to choose the Systems Manager service-linked role in the console when they create a maintenance window task. 

  To provide access, add permissions to your users, groups, or roles:
  + Users and groups in AWS IAM Identity Center:

    Create a permission set. Follow the instructions in [Create a permission set](https://docs.aws.amazon.com//singlesignon/latest/userguide/howtocreatepermissionset.html) in the *AWS IAM Identity Center User Guide*.
  + Users managed in IAM through an identity provider:

    Create a role for identity federation. Follow the instructions in [Create a role for a third-party identity provider (federation)](https://docs.aws.amazon.com//IAM/latest/UserGuide/id_roles_create_for-idp.html) in the *IAM User Guide*.
  + IAM users:
    + Create a role that your user can assume. Follow the instructions in [Create a role for an IAM user](https://docs.aws.amazon.com//IAM/latest/UserGuide/id_roles_create_for-user.html) in the *IAM User Guide*.
    + (Not recommended) Attach a policy directly to a user or add a user to a user group. Follow the instructions in [Adding permissions to a user (console)](https://docs.aws.amazon.com//IAM/latest/UserGuide/id_users_change-permissions.html#users_change_permissions-add-console) in the *IAM User Guide*.

**To configure permissions for groups that are allowed to register maintenance window tasks using the console**

1. Open the IAM console at [https://console.aws.amazon.com/iam/](https://console.aws.amazon.com/iam/).

1. In the navigation pane, choose **User groups**.

1. In the list of groups, select the name of the group you want to assign the `iam:PassRole` permission to, or first create a new group if necessary 

1. On the **Permissions** tab, choose **Add permissions, Create inline policy**.

1. In the **Policy editor** area, choose **JSON**, and replace the default contents of the box with the following.

------
#### [ JSON ]

****  

   ```
   {
       "Version":"2012-10-17",		 	 	 
       "Statement": [
           {
               "Effect": "Allow",
               "Action": "iam:PassRole",
               "Resource": "arn:aws:iam::111122223333:role/my-maintenance-window-role"
           },
           {
               "Effect": "Allow",
               "Action": "iam:ListRoles",
               "Resource": "arn:aws:iam::111122223333:role/"
           },
           {
               "Effect": "Allow",
               "Action": "iam:ListRoles",
               "Resource": "arn:aws:iam::111122223333:role/aws-service-role/ssm.amazonaws.com/"
           }
       ]
   }
   ```

------

   *my-maintenance-window-role* represents the name of the custom maintenance window role you created earlier.

   *account-id* represents the ID of your AWS account. Adding this permission for the resource `arn:aws:iam::account-id:role/` allows a user to view and choose from customer roles in the console when they create a maintenance window task. Adding this permission for `arn:aws:iam::account-id:role/aws-service-role/ssm.amazonaws.com/` allows a user to choose the Systems Manager service-linked role in the console when they create a maintenance window task. 

1. Choose **Next**.

1. On the **Review and create** page, enter a name in the **Policy name** box to identify this `PassRole` policy, such as **my-group-iam-passrole-policy**, and then choose **Create policy**.

## Task 4: Prevent specified users from registering maintenance window tasks using the console
<a name="deny-maintenance-window-access-console"></a>

You can deny the `ssm:RegisterTaskWithMaintenanceWindow` permission for the users in your AWS account who you don't want to register tasks with maintenance windows. This provides an extra layer of prevention for users who shouldn’t register maintenance window tasks.

**To configure permissions for groups that aren't allowed to register maintenance window tasks using the console**

1. Open the IAM console at [https://console.aws.amazon.com/iam/](https://console.aws.amazon.com/iam/).

1. In the navigation pane, choose **User groups**.

1. In the list of groups, select the name of the group you want to deny the `ssm:RegisterTaskWithMaintenanceWindow` permission from, or first create a new group if necessary.

1. On the **Permissions** tab, choose **Add permissions, Create inline policy**.

1. In the **Policy editor** area, choose **JSON**, and then replace the default contents of the box with the following.

------
#### [ JSON ]

****  

   ```
   {
       "Version":"2012-10-17",		 	 	 
       "Statement": [
           {
               "Effect": "Deny",
               "Action": "ssm:RegisterTaskWithMaintenanceWindow",
               "Resource": "*"
           }
       ]
   }
   ```

------

1. Choose **Next**.

1. On the **Review and create** page, for **Policy name**, enter a name to identify this policy, such as **my-groups-deny-mw-tasks-policy**, and then choose **Create policy**.

# Control access to maintenance windows using the AWS CLI
<a name="configuring-maintenance-window-permissions-cli"></a>

The following procedures describe how to use the AWS Command Line Interface (AWS CLI) to create the required permissions and roles for Maintenance Windows, a tool in AWS Systems Manager.

**Topics**
+ [Task 1: Create trust policy and customer managed policy files in JSON format](#create-custom-policy-json-files-cli)
+ [Task 2: Create and verify a custom service role for maintenance windows using the AWS CLI](#create-custom-role-cli)
+ [Task 3: Grant permissions to specified users to register maintenance window tasks using the AWS CLI](#allow-maintenance-window-access-cli)
+ [Task 4: Prevent specified users from registering maintenance window tasks using the AWS CLI](#deny-maintenance-window-access-cli)

## Task 1: Create trust policy and customer managed policy files in JSON format
<a name="create-custom-policy-json-files-cli"></a>

Maintenance window tasks require an IAM role to provide the permissions required to run on the target resources. The permissions are provided through an IAM policy attached to the role. The types of tasks you run and your other operational requirements determine the contents of this policy. We provide a base policy you can adapt to your needs. Depending on the tasks and types of tasks your maintenance windows run, you might not need all the permissions in this policy, and you might need to include additional permissions. 

In this task, you specify the permissions needed for your custom maintenance window role in a pair of JSON files. You attach this policy to the role that you create later in [Task 2: Create and verify a custom service role for maintenance windows using the AWS CLI](#create-custom-role-cli). 

**To create trust policy and customer managed policy files**

1. Copy and paste the following trust policy into a text file. Save this file with the following name and file extension: **mw-role-trust-policy.json**.

------
#### [ JSON ]

****  

   ```
   {
       "Version":"2012-10-17",		 	 	 
       "Statement": [
           {
               "Effect": "Allow",
               "Principal": {
                   "Service": "ssm.amazonaws.com"
               },
               "Action": "sts:AssumeRole"
           }
       ]
   }
   ```

------

1. Copy and paste the following JSON policy into a different text file. In the same directory where you created the first file, save this file with the following name and file extension: **mw-role-custom-policy.json**.

------
#### [ JSON ]

****  

   ```
   {
       "Version":"2012-10-17",		 	 	 
       "Statement": [
           {
               "Effect": "Allow",
               "Action": [
                   "ssm:SendCommand",
                   "ssm:CancelCommand",
                   "ssm:ListCommands",
                   "ssm:ListCommandInvocations",
                   "ssm:GetCommandInvocation",
                   "ssm:GetAutomationExecution",
                   "ssm:StartAutomationExecution",
                   "ssm:ListTagsForResource",
                   "ssm:GetParameters"
               ],
               "Resource": "*"
           },
           {
               "Effect": "Allow",
               "Action": [
                   "states:DescribeExecution",
                   "states:StartExecution"
               ],
               "Resource": [
                   "arn:aws:states:*:*:execution:*:*",
                   "arn:aws:states:*:*:stateMachine:*"
               ]
           },
           {
               "Effect": "Allow",
               "Action": [
                   "lambda:InvokeFunction"
               ],
               "Resource": [
                   "arn:aws:lambda:*:*:function:*"
               ]
           },
           {
               "Effect": "Allow",
               "Action": [
                   "resource-groups:ListGroups",
                   "resource-groups:ListGroupResources"
               ],
               "Resource": [
                   "*"
               ]
           },
           {
               "Effect": "Allow",
               "Action": [
                   "tag:GetResources"
               ],
               "Resource": [
                   "*"
               ]
           },
           {
               "Effect": "Allow",
               "Action": "iam:PassRole",
               "Resource": "arn:aws:iam::111122223333:role/maintenance-window-role-name",
               "Condition": {
                   "StringEquals": {
                       "iam:PassedToService": [
                           "ssm.amazonaws.com"
                       ]
                   }
               }
           }
       ]
   }
   ```

------

1. Modify the the content of `mw-role-custom-policy.json` as needed for the maintenance tasks that you run in your account. The changes you make are specific to your planned operations. 

   For example:
   + You can provide Amazon Resource Names (ARNs) for specific functions and state machines instead of using wildcard (\$1) qualifiers.
   + If you don’t plan to run AWS Step Functions tasks, you can remove the `states` permissions and (ARNs).
   + If you don’t plan to run AWS Lambda tasks, you can remove the `lambda` permissions and ARNs.
   + If you don't plan to run Automation tasks, you can remove the `ssm:GetAutomationExecution` and `ssm:StartAutomationExecution` permissions.
   + Add additional permissions that might be needed for the tasks to run. For example, some Automation actions work with AWS CloudFormation stacks. Therefore, the permissions `cloudformation:CreateStack`, `cloudformation:DescribeStacks`, and `cloudformation:DeleteStack` are required. 

     For another example, the Automation runbook `AWS-CopySnapshot` requires permissions to create an Amazon Elastic Block Store (Amazon EBS) snapshot. Therefore, the service role needs the permission `ec2:CreateSnapshot`. 

     For information about the role permissions needed by Automation runbooks, see the runbook descriptions in the [AWS Systems Manager Automation Runbook Reference](https://docs.aws.amazon.com/systems-manager-automation-runbooks/latest/userguide/automation-runbook-reference.html).

   Save the file again after making any needed changes.

## Task 2: Create and verify a custom service role for maintenance windows using the AWS CLI
<a name="create-custom-role-cli"></a>

The policy you created in the previous task is attached to the maintenance window service role you create in this task. When users register a maintenance window task, they specify this IAM role as part of the task configuration. The permissions in this role allow Systems Manager to run tasks in maintenance windows on your behalf.

**Important**  
Previously, the Systems Manager console provided you with the ability to choose the AWS managed IAM service-linked role `AWSServiceRoleForAmazonSSM` to use as the maintenance role for your tasks. Using this role and its associated policy, `AmazonSSMServiceRolePolicy`, for maintenance window tasks is no longer recommended. If you're using this role for maintenance window tasks now, we encourage you to stop using it. Instead, create your own IAM role that enables communication between Systems Manager and other AWS services when your maintenance window tasks run.

In this task, you run CLI commands to create your maintenance windows service role, adding the policy content from the JSON files you created. 

**Create a custom service role for maintenance windows using the AWS CLI**

1. Open the AWS CLI and run the following command in the directory where you placed `mw-role-custom-policy.json` and `mw-role-trust-policy.json`. The command creates a maintenance window service role called `my-maintenance-window-role` and attaches the *trust policy* to it.

------
#### [ Linux & macOS ]

   ```
   aws iam create-role \
       --role-name "my-maintenance-window-role" \
       --assume-role-policy-document file://mw-role-trust-policy.json
   ```

------
#### [ Windows ]

   ```
   aws iam create-role ^
       --role-name "my-maintenance-window-role" ^
       --assume-role-policy-document file://mw-role-trust-policy.json
   ```

------

   The system returns information similar to the following.

   ```
   {
       "Role": {
           "AssumeRolePolicyDocument": {
               "Version": "2012-10-17", 		 	 	 		 	 	 
               "Statement": [
                   {
                       "Action": "sts:AssumeRole",
                       "Effect": "Allow",
                       "Principal": {
                           "Service": "ssm.amazonaws.com"
                       }
                   }
               ]
           },
           "RoleId": "AROAIIZKPBKS2LEXAMPLE",
           "CreateDate": "2024-08-19T03:40:17.373Z",
           "RoleName": "my-maintenance-window-role",
           "Path": "/",
           "Arn": "arn:aws:iam::123456789012:role/my-maintenance-window-role"
       }
   }
   ```
**Note**  
Make a note of the `RoleName` and the `Arn` values. You include them in the next command.

1. Run the following command to attach the *customer managed policy* to the role. Replace the *account-id* placeholder with your own AWS account ID

------
#### [ Linux & macOS ]

   ```
   aws iam attach-role-policy \
       --role-name "my-maintenance-window-role" \
       --policy-arn "arn:aws:iam::account-id:policy/mw-role-custom-policy.json"
   ```

------
#### [ Windows ]

   ```
   aws iam attach-role-policy ^
       --role-name "my-maintenance-window-role" ^
       --policy-arn "arn:aws:iam::account-id:policy/mw-role-custom-policy.json"
   ```

------

1. Run the following command to verify that your role has been created, and that the trust policy has been attached.

   ```
   aws iam get-role --role-name my-maintenance-window-role
   ```

   The command returns information similar to the following:

   ```
   {
       "Role": {
           "Path": "/",
           "RoleName": "my-maintenance-window-role",
           "RoleId": "AROA123456789EXAMPLE",
           "Arn": "arn:aws:iam::123456789012:role/my-maintenance-window-role",
           "CreateDate": "2024-08-19T14:13:32+00:00",
           "AssumeRolePolicyDocument": {
               "Version": "2012-10-17", 		 	 	 		 	 	 
               "Statement": [
                   {
                       "Effect": "Allow",
                       "Principal": {
                           "Service": "ssm.amazonaws.com"
                       },
                       "Action": "sts:AssumeRole"
                   }
               ]
           },
           "MaxSessionDuration": 3600,
           "RoleLastUsed": {
               "LastUsedDate": "2024-08-19T14:30:44+00:00",
               "Region": "us-east-2"
           }
       }
   }
   ```

1. Run the following command to verify that the customer managed policy has been attached to the role.

   ```
   aws iam list-attached-role-policies --role-name my-maintenance-window-role
   ```

   The command returns information similar to the following:

   ```
   {
       "AttachedPolicies": [
           {
               "PolicyName": "mw-role-custom-policy",
               "PolicyArn": "arn:aws:iam::123456789012:policy/mw-role-custom-policy"
           }
       ]
   }
   ```

## Task 3: Grant permissions to specified users to register maintenance window tasks using the AWS CLI
<a name="allow-maintenance-window-access-cli"></a>

Providing users with permissions to access the custom service role for maintenance windows lets them use it with their maintenance windows tasks. This is in addition to permissions that you’ve already given them to work with the Systems Manager API commands for the Maintenance Windows tool. This IAM role conveys the permissions need to run a maintenance window task. As a result, a user can't register tasks with a maintenance window using your custom service role without the ability to pass these IAM permissions.

When you register a task with a maintenance window, you specify a service role to run the actual task operations. This is the role that the service assumes when it runs tasks on your behalf. Before that, to register the task itself, assign the IAM `PassRole` policy to an IAM entity (such as a user or group). This allows the IAM entity to specify, as part of registering those tasks with the maintenance window, the role that should be used when running tasks. For information, see [Grant a user permissions to pass a role to an AWS service](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_use_passrole.html) in the *IAM User Guide*.

**To configure permissions for users who are allowed to register maintenance window tasks using the AWS CLI**

1. Copy and paste the following AWS Identity and Access Management (IAM) policy into a text editor and save it with the following name and file extension: `mw-passrole-policy.json`.

------
#### [ JSON ]

****  

   ```
   {
       "Version":"2012-10-17",		 	 	 
       "Statement": [
           {
               "Effect": "Allow",
               "Action": "iam:PassRole",
               "Resource": "arn:aws:iam::111122223333:role/my-maintenance-window-role"
           },
           {
               "Effect": "Allow",
               "Action": "iam:ListRoles",
               "Resource": "arn:aws:iam::111122223333:role/"
           },
           {
               "Effect": "Allow",
               "Action": "iam:ListRoles",
               "Resource": "arn:aws:iam::111122223333:role/aws-service-role/ssm.amazonaws.com/"
           }
       ]
   }
   ```

------

   Replace *my-maintenance-window-role* with the name of the custom maintenance window role you created earlier.

   Replace *account-id* with the ID of your AWS account. Adding this permission for the resource `arn:aws:iam::account-id:role/` allows users in the group to view and choose from customer roles in the console when they create a maintenance window task. Adding this permission for `arn:aws:iam::account-id:role/aws-service-role/ssm.amazonaws.com/` allows users in the group to choose the Systems Manager service-linked role in the console when they create a maintenance window task. 

1. Open the AWS CLI.

1. Depending on whether you're assigning the permission to an IAM entity (user or group), run one of the following commands.
   + **For an IAM entity:**

------
#### [ Linux & macOS ]

     ```
     aws iam put-user-policy \
         --user-name "user-name" \
         --policy-name "policy-name" \
         --policy-document file://path-to-document
     ```

------
#### [ Windows ]

     ```
     aws iam put-user-policy ^
         --user-name "user-name" ^
         --policy-name "policy-name" ^
         --policy-document file://path-to-document
     ```

------

     For *user-name*, specify the user who assigns tasks to maintenance windows. For *policy-name*, specify the name you want to use to identify the policy, such as **my-iam-passrole-policy**. For *path-to-document*, specify the path to the file you saved in step 1. For example: `file://C:\Temp\mw-passrole-policy.json`
**Note**  
To grant access for a user to register tasks for maintenance windows using the Systems Manager console, you must also assign the `AmazonSSMFullAccess` policy to your user (or an IAM policy that provides a smaller set of access permissions for Systems Manager that covers maintenance window tasks). Run the following command to assign the `AmazonSSMFullAccess` policy to your user.  

     ```
     aws iam attach-user-policy \
         --policy-arn "arn:aws:iam::aws:policy/AmazonSSMFullAccess" \
         --user-name "user-name"
     ```

     ```
     aws iam attach-user-policy ^
         --policy-arn "arn:aws:iam::aws:policy/AmazonSSMFullAccess" ^
         --user-name "user-name"
     ```
   + **For an IAM group:**

------
#### [ Linux & macOS ]

     ```
     aws iam put-group-policy \
         --group-name "group-name" \
         --policy-name "policy-name" \
         --policy-document file://path-to-document
     ```

------
#### [ Windows ]

     ```
     aws iam put-group-policy ^
         --group-name "group-name" ^
         --policy-name "policy-name" ^
         --policy-document file://path-to-document
     ```

------

     For *group-name*, specify the group whose members assign tasks to maintenance windows. For *policy-name*, specify the name you want to use to identify the policy, such as **my-iam-passrole-policy**. For *path-to-document*, specify the path to the file you saved in step 1. For example: `file://C:\Temp\mw-passrole-policy.json`
**Note**  
To grant access for members of a group to register tasks for maintenance windows using the Systems Manager console, you must also assign the `AmazonSSMFullAccess` policy to your group. Run the following command to assign this policy to your group.  

     ```
     aws iam attach-group-policy \
         --policy-arn "arn:aws:iam::aws:policy/AmazonSSMFullAccess" \
         --group-name "group-name"
     ```

     ```
     aws iam attach-group-policy ^
         --policy-arn "arn:aws:iam::aws:policy/AmazonSSMFullAccess" ^
         --group-name "group-name"
     ```

1. Run the following command to verify that the policy has been assigned to the group.

------
#### [ Linux & macOS ]

   ```
   aws iam list-group-policies \
       --group-name "group-name"
   ```

------
#### [ Windows ]

   ```
   aws iam list-group-policies ^
       --group-name "group-name"
   ```

------

## Task 4: Prevent specified users from registering maintenance window tasks using the AWS CLI
<a name="deny-maintenance-window-access-cli"></a>

You can deny the `ssm:RegisterTaskWithMaintenanceWindow` permission for the users in your AWS account who you don't want to register tasks with maintenance windows. This provides an extra layer of prevention for users who shouldn’t register maintenance window tasks.

Depending on whether you're denying the `ssm:RegisterTaskWithMaintenanceWindow` permission for an individual user or a group, use one of the following procedures to prevent users from registering tasks with a maintenance window. 

**To configure permissions for users who aren't allowed to register maintenance window tasks using the AWS CLI**

1. Copy and paste the following IAM policy into a text editor and save it with the following name and file extension: **deny-mw-tasks-policy.json**.

------
#### [ JSON ]

****  

   ```
   {
       "Version":"2012-10-17",		 	 	 
       "Statement": [
           {
               "Effect": "Deny",
               "Action": "ssm:RegisterTaskWithMaintenanceWindow",
               "Resource": "*"
           }
       ]
   }
   ```

------

1. Open the AWS CLI.

1. Depending on whether you're assigning the permission to an IAM entity (user or group), run one of the following commands.
   + **For a user:**

------
#### [ Linux & macOS ]

     ```
     aws iam put-user-policy \
         --user-name "user-name" \
         --policy-name "policy-name" \
         --policy-document file://path-to-document
     ```

------
#### [ Windows ]

     ```
     aws iam put-user-policy ^
         --user-name "user-name" ^
         --policy-name "policy-name" ^
         --policy-document file://path-to-document
     ```

------

     For *user-name*, specify the user to prevent from assigning tasks to maintenance windows. For *policy-name*, specify the name you want to use to identify the policy, such as **my-deny-mw-tasks-policy**. For *path-to-document*, specify the path to the file you saved in step 1. For example: `file://C:\Temp\deny-mw-tasks-policy.json`
   + **For a group:**

------
#### [ Linux & macOS ]

     ```
     aws iam put-group-policy \
         --group-name "group-name" \
         --policy-name "policy-name" \
         --policy-document file://path-to-document
     ```

------
#### [ Windows ]

     ```
     aws iam put-group-policy ^
         --group-name "group-name" ^
         --policy-name "policy-name" ^
         --policy-document file://path-to-document
     ```

------

     For *group-name*, specify the group whose to prevent from assigning tasks to maintenance windows. For *policy-name*, specify the name you want to use to identify the policy, such as **my-deny-mw-tasks-policy**. For *path-to-document*, specify the path to the file you saved in step 1. For example: `file://C:\Temp\deny-mw-tasks-policy.json`

1. Run the following command to verify that the policy has been assigned to the group.

------
#### [ Linux & macOS ]

   ```
   aws iam list-group-policies \
       --group-name "group-name"
   ```

------
#### [ Windows ]

   ```
   aws iam list-group-policies ^
       --group-name "group-name"
   ```

------

# Create and manage maintenance windows using the console
<a name="sysman-maintenance-working"></a>

This section describes how to create, configure, update, and delete maintenance windows using the AWS Systems Manager console. This section also provides information about managing the targets and tasks of a maintenance window.

**Important**  
We recommend that you initially create and configure maintenance windows in a test environment. 

**Before you begin**  
Before you create a maintenance window, you must configure access to Maintenance Windows, a tool in AWS Systems Manager. For more information, see [Setting up Maintenance Windows](setting-up-maintenance-windows.md).

**Topics**
+ [Create a maintenance window using the console](sysman-maintenance-create-mw.md)
+ [Assign targets to a maintenance window using the console](sysman-maintenance-assign-targets.md)
+ [Assign tasks to a maintenance window using the console](sysman-maintenance-assign-tasks.md)
+ [Disable or enable a maintenance window using the console](sysman-maintenance-disable.md)
+ [Update or delete maintenance window resources using the console](sysman-maintenance-update.md)

# Create a maintenance window using the console
<a name="sysman-maintenance-create-mw"></a>

In this procedure, you create a maintenance window in Maintenance Windows, a tool in AWS Systems Manager. You can specify its basic options, such as name, schedule, and duration. In later steps, you choose the targets, or resources, that it updates and the tasks that run when the maintenance window runs.

**Note**  
For an explanation of how the various schedule-related options for maintenance windows relate to one another, see [Maintenance window scheduling and active period options](maintenance-windows-schedule-options.md).  
For more information about working with the `--schedule` option, see [Reference: Cron and rate expressions for Systems Manager](reference-cron-and-rate-expressions.md).

**To create a maintenance window using the console**

1. Open the AWS Systems Manager console at [https://console.aws.amazon.com/systems-manager/](https://console.aws.amazon.com/systems-manager/).

1. In the navigation pane, choose **Maintenance Windows**. 

1. Choose **Create maintenance window**.

1. For **Name**, enter a descriptive name to help you identify this maintenance window.

1. (Optional) For **Description**, enter a description to identify how this maintenance window will be used.

1. (Optional) If you want to allow a maintenance window task to run on managed nodes, even if you haven't registered those nodes as targets, choose **Allow unregistered targets**. 

   If you choose this option, then you can choose the unregistered nodes (by node ID) when you register a task with the maintenance window. 

   If you don't choose this option, then you must choose previously registered targets when you register a task with the maintenance window.

1. Specify a schedule for the maintenance window by using one of the three scheduling options.

   For information about building cron/rate expressions, see [Reference: Cron and rate expressions for Systems Manager](reference-cron-and-rate-expressions.md).

1. For **Duration**, enter the number of hours the maintenance window will run. The value you specify determines the specific end time for the maintenance window based on the time it begins. No maintenance window tasks are permitted to start after the resulting endtime minus the number of hours you specify for **Stop initiating tasks** in the next step.

   For example, if the maintenance window starts at 3 PM, the duration is three hours, and the **Stop initiating tasks** value is one hour, no maintenance window tasks can start after 5 PM.

1. For **Stop initiating tasks**, enter the number of hours before the end of the maintenance window that the system should stop scheduling new tasks to run.

1. (Optional) For **Window start date**, specify a date and time, in ISO-8601 Extended format, for when you want the maintenance window to become active. This allows you to delay activation of the maintenance window until the specified future date.
**Note**  
You can't specify a start date and time that occurs in the past.

1. (Optional) For **Window end date**, specify a date and time, in ISO-8601 Extended format, for when you want the maintenance window to become inactive. This allows you to set a date and time in the future after which the maintenance window no longer runs.

1. (Optional) For **Schedule timezone**, specify the time zone to use as the basis for when scheduled maintenance windows run, in Internet Assigned Numbers Authority (IANA) format. For example: "America/Los\$1Angeles", "etc/UTC", or "Asia/Seoul".

   For more information about valid formats, see the [Time Zone Database](https://www.iana.org/time-zones) on the IANA website.

1. (Optional) For **Schedule offset**, enter the number of days to wait after the date and time specified by a cron or rate expression before running the maintenance window. You can specify between one and six days.
**Note**  
This option is available only if you specified a schedule by entering a cron or rate expression manually.

1. (Optional) In the **Manage tags** area, apply one or more tag key name/value pairs to the maintenance window.

   Tags are optional metadata that you assign to a resource. Tags allow you to categorize a resource in different ways, such as by purpose, owner, or environment. For example, you might want to tag a maintenance window to identify the type of tasks it runs, the types of targets, and the environment it runs in. In this case, you could specify the following key name/value pairs:
   + `Key=TaskType,Value=AgentUpdate`
   + `Key=OS,Value=Windows`
   + `Key=Environment,Value=Production`

1. Choose **Create maintenance window**. The system returns you to the maintenance window page. The state of the maintenance window you just created is **Enabled**.

# Assign targets to a maintenance window using the console
<a name="sysman-maintenance-assign-targets"></a>

In this procedure, you register a target with a maintenance window. In other words, you specify which resources the maintenance window performs actions on.

**Note**  
If a single maintenance window task is registered with multiple targets, its task invocations occur sequentially and not in parallel. If your task must run on multiple targets at the same time, register a task for each target individually and assign each task the same priority level.

**To assign targets to a maintenance window using the console**

1. Open the AWS Systems Manager console at [https://console.aws.amazon.com/systems-manager/](https://console.aws.amazon.com/systems-manager/).

1. In the navigation pane, choose **Maintenance Windows**. 

1. In the list of maintenance windows, choose the maintenance window to add targets to.

1. Choose **Actions**, and then choose **Register targets**.

1. (Optional) For **Target name**, enter a name for the targets.

1. (Optional) For **Description**, enter a description.

1. (Optional) For **Owner information**, specify information to include in any Amazon EventBridge event raised while running tasks for these targets in this maintenance window.

   For information about using EventBridge to monitor Systems Manager events, see [Monitoring Systems Manager events with Amazon EventBridge](monitoring-eventbridge-events.md).

1. In the **Targets** area, choose one of the options described in the following table.    
[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/systems-manager/latest/userguide/sysman-maintenance-assign-targets.html)

1. Choose **Register target**.

If you want to assign more targets to this maintenance window, choose the **Targets** tab, and then choose **Register target**. With this option, you can choose a different means of targeting. For example, if you previously targeted nodes by node ID, you can register new targets and target nodes by specifying tags applied to managed nodes or choosing resource types from a resource group.

# Assign tasks to a maintenance window using the console
<a name="sysman-maintenance-assign-tasks"></a>

In this procedure, you add a task to a maintenance window. Tasks are the actions performed when a maintenance window runs.

The following four types of tasks can be added to a maintenance window:
+ AWS Systems Manager Run Command commands
+ Systems Manager Automation workflows
+ AWS Step Functions tasks
+ AWS Lambda functions
**Important**  
The IAM policy for Maintenance Windows requires that you add the prefix `SSM` to Lambda function (or alias) names. Before you proceed to register this type of task, update its name in AWS Lambda to include `SSM`. For example, if your Lambda function name is `MyLambdaFunction`, change it to `SSMMyLambdaFunction`.

**To assign tasks to a maintenance window**

1. Open the AWS Systems Manager console at [https://console.aws.amazon.com/systems-manager/](https://console.aws.amazon.com/systems-manager/).

1. In the navigation pane, choose **Maintenance Windows**. 

1. In the list of maintenance windows, choose a maintenance window.

1. Choose **Actions**, and then choose the option for the type of task you want to register with the maintenance window.
   + **Register Run command task**
   + **Register Automation task**
   + **Register Lambda task**
   + **Register Step Functions task**
**Note**  
Maintenance window tasks support Step Functions Standard state machine workflows only. They don't support Express state machine workflows. For information about state machine workflow types, see [Standard vs. Express Workflows](https://docs.aws.amazon.com/step-functions/latest/dg/concepts-standard-vs-express.html) in the *AWS Step Functions Developer Guide*.

1. (Optional) For **Name**, enter a name for the task.

1. (Optional) For **Description**, enter a description.

1. For **New task invocation cutoff**, if you don't want any new task invocations to start after the maintenance window cutoff time is reached, choose **Enabled**.

   When this option is *not* enabled, the task continues running when the cutoff time is reached and starts new task invocations until completion. 
**Note**  
The status for tasks that are not completed when you enable this option is `TIMED_OUT`. 

1. For this step, choose the tab for your selected task type.

------
#### [ Run Command ]

   1. In the **Command document** list, choose the Systems Manager Command document (SSM document) that defines the tasks to run.

   1. For **Document version**, choose the document version to use.

   1. For **Task priority**, specify a priority for this task. Zero (`0`) is the highest priority. Tasks in a maintenance window are scheduled in priority order with tasks that have the same priority scheduled in parallel.

------
#### [ Automation ]

   1.  In the **Automation document** list, choose the Automation runbook that defines the tasks to run.

   1. For **Document version**, choose the runbook version to use.

   1. For **Task priority**, specify a priority for this task. Zero (`0`) is the highest priority. Tasks in a maintenance window are scheduled in priority order with tasks that have the same priority scheduled in parallel.

------
#### [ Lambda ]

   1. In the **Lambda parameters** area, choose a Lambda function from the list.

   1. (Optional) Provide any content for **Payload**, **Client Context**, or **Qualifier** that you want to include.
**Note**  
In some cases, you can use a *pseudo parameter* as part of your `Payload` value. Then when the maintenance window task runs, it passes the correct values instead of the pseudo parameter placeholders. For information, see [Using pseudo parameters when registering maintenance window tasks](maintenance-window-tasks-pseudo-parameters.md).

   1. For **Task priority**, specify a priority for this task. Zero (`0`) is the highest priority. Tasks in a maintenance window are scheduled in priority order with tasks that have the same priority scheduled in parallel.

------
#### [ Step Functions ]

   1. In the **Step Functions parameters** area, choose a state machine from the list.

   1. (Optional) Provide a name for the state machine execution and any content for **Input** that you want to include.
**Note**  
In some cases, you can use a *pseudo parameter* as part of your `Input` value. Then when the maintenance window task runs, it passes the correct values instead of the pseudo parameter placeholders. For information, see [Using pseudo parameters when registering maintenance window tasks](maintenance-window-tasks-pseudo-parameters.md).

   1. For **Task priority**, specify a priority for this task. Zero (`0`) is the highest priority. Tasks in a maintenance window are scheduled in priority order with tasks that have the same priority scheduled in parallel.

------

1. In the **Targets** area, choose one of the following:
   + **Selecting registered target groups**: Select one or more maintenance window targets you have registered with the current maintenance window.
   + **Selecting unregistered targets**: Choose available resources one by one as targets for the task.

     If a managed node you expect to see isn't listed, see [Troubleshooting managed node availability](fleet-manager-troubleshooting-managed-nodes.md) for troubleshooting tips.
   + **Task target not required**: Targets for the task might already be specified in other functions for all but Run Command-type tasks.

     Specify one or more targets for maintenance window Run Command-type tasks. Depending on the task, targets are optional for other maintenance window task types (Automation, AWS Lambda, and AWS Step Functions). For more information about running tasks that don't specify targets, see [Registering maintenance window tasks without targets](maintenance-windows-targetless-tasks.md).
**Note**  
In many cases, you don't need to explicitly specify a target for an automation task. For example, say that you're creating an Automation-type task to update an Amazon Machine Image (AMI) for Linux using the `AWS-UpdateLinuxAmi` runbook. When the task runs, the AMI is updated with the latest available Linux distribution packages and Amazon software. New instances created from the AMI already have these updates installed. Because the ID of the AMI to be updated is specified in the input parameters for the runbook, there is no need to specify a target again in the maintenance window task.

1. *Automation tasks only:*

   In the **Input parameters** area, provide values for any required or optional parameters needed to run your task.
**Note**  
In some cases, you can use a *pseudo parameter* for certain input parameter values. Then when the maintenance window task runs, it passes the correct values instead of the pseudo parameter placeholders. For information, see [Using pseudo parameters when registering maintenance window tasks](maintenance-window-tasks-pseudo-parameters.md).

1. For **Rate control**:
   + For **Concurrency**, specify either a number or a percentage of managed nodes on which to run the command at the same time.
**Note**  
If you selected targets by specifying tags applied to managed nodes or by specifying AWS resource groups, and you aren't certain how many managed nodes are targeted, then restrict the number of targets that can run the document at the same time by specifying a percentage.
   + For **Error threshold**, specify when to stop running the command on other managed nodes after it fails on either a number or a percentage of nodes. For example, if you specify three errors, then Systems Manager stops sending the command when the fourth error is received. Managed nodes still processing the command might also send errors.

1. (Optional) For **IAM service role**, choose a role to provide permissions for Systems Manager to assume when running a maintenance window task.

   If you don't specify a service role ARN, Systems Manager uses a service-linked role in your account. This role is not listed in the drop-down menu. If no appropriate service-linked role for Systems Manager exists in your account, it's created when the task is registered successfully. 
**Note**  
For an improved security posture, we strongly recommend creating a custom policy and custom service role for running your maintenance window tasks. The policy can be crafted to provide only the permissions needed for your particular maintenance window tasks. For more information, see [Setting up Maintenance Windows](setting-up-maintenance-windows.md).

1. *Run Command tasks only:*

   (Optional) For **Output options**, do the following:
   + Select the **Enable writing to S3** check box to save the command output to a file. Enter the bucket and prefix (folder) names in the boxes.
   + Select the **CloudWatch output** check box to write complete output to Amazon CloudWatch Logs. Enter the name of a CloudWatch Logs log group.
**Note**  
The permissions that grant the ability to write data to an S3 bucket or CloudWatch Logs are those of the instance profile assigned to the node, not those of the IAM user performing this task. For more information, see [Configure instance permissions required for Systems Manager](setup-instance-permissions.md). In addition, if the specified S3 bucket or log group is in a different AWS account, verify that the instance profile associated with the node has the necessary permissions to write to that bucket.

1. *Run Command tasks only:*

   In the **SNS notifications** section, if you want notifications sent about the status of the command execution, select the **Enable SNS notifications** check box.

   For more information about configuring Amazon SNS notifications for Run Command, see [Monitoring Systems Manager status changes using Amazon SNS notifications](monitoring-sns-notifications.md).

1. *Run Command tasks only:*

   In the **Parameters** area, specify parameters for the document. 
**Note**  
In some cases, you can use a *pseudo parameter* for certain input parameter values. Then when the maintenance window task runs, it passes the correct values instead of the pseudo parameter placeholders. For information, see [Using pseudo parameters when registering maintenance window tasks](maintenance-window-tasks-pseudo-parameters.md).

1. * Run Command and Automation tasks only:*

   (Optional) In the **CloudWatch alarm** area, for **Alarm name**, choose an existing CloudWatch alarm to apply to your task for monitoring. 

   If the alarm activates, the task is stopped.
**Note**  
To attach a CloudWatch alarm to your task, the IAM principal that runs the task must have permission for the `iam:createServiceLinkedRole` action. For more information about CloudWatch alarms, see [Using Amazon CloudWatch alarms](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/AlarmThatSendsEmail.html).

1. Depending on your task type, choose one of the following:
   + **Register Run command task**
   + **Register Automation task**
   + **Register Lambda task**
   + **Register Step Functions task**

# Disable or enable a maintenance window using the console
<a name="sysman-maintenance-disable"></a>

You can disable or enable a maintenance window in Maintenance Windows, a tool in AWS Systems Manager. You can choose one maintenance window at a time to either disable or enable the maintenance window from running. You can also select multiple or all maintenance windows to enable and disable.

This section describes how to disable or enable a maintenance window by using the Systems Manager console. For examples of how to do this by using the AWS Command Line Interface (AWS CLI), see [Tutorial: Update a maintenance window using the AWS CLI](maintenance-windows-cli-tutorials-update.md). 

**Topics**
+ [Disable a maintenance window using the console](#sysman-maintenance-disable-mw)
+ [Enable a maintenance window using the console](#sysman-maintenance-enable-mw)

## Disable a maintenance window using the console
<a name="sysman-maintenance-disable-mw"></a>

You can disable a maintenance window to pause a task for a specified period, and it will remain available to enable again later.

**To disable a maintenance window**

1. Open the AWS Systems Manager console at [https://console.aws.amazon.com/systems-manager/](https://console.aws.amazon.com/systems-manager/).

1. In the navigation pane, choose **Maintenance Windows**. 

1. Using the check box next to the maintenance window that you want to disable, select one or more maintenance windows.

1. Choose **Disable maintenance window** in the **Actions** menu. The system prompts you to confirm your actions. 

## Enable a maintenance window using the console
<a name="sysman-maintenance-enable-mw"></a>

You can enable a maintenance window to resume a task.

**Note**  
If the maintenance window uses a rate schedule and the start date is currently set to a past date and time, the current date and time is used as the start date for the maintenance window. You can change the start date of the maintenance window before or after enabling it. For information, see [Update or delete maintenance window resources using the console](sysman-maintenance-update.md).

**To enable a maintenance window**

1. Open the AWS Systems Manager console at [https://console.aws.amazon.com/systems-manager/](https://console.aws.amazon.com/systems-manager/).

1. In the navigation pane, choose **Maintenance Windows**. 

1. Select the check box next to the maintenance window to enable.

1. Choose **Actions, Enable maintenance window**. The system prompts you to confirm your actions. 

# Update or delete maintenance window resources using the console
<a name="sysman-maintenance-update"></a>

You can update or delete a maintenance window in Maintenance Windows, a tool in AWS Systems Manager. You can also update or delete the targets or tasks of a maintenance window. If you edit the details of a maintenance window, you can change the schedule, targets, and tasks. You can also specify names and descriptions for windows, targets, and tasks, which helps you better understand their purpose, and makes it easier to manage your queue of windows.

This section describes how to update or delete a maintenance window, targets, and tasks by using the Systems Manager console. For examples of how to do this by using the AWS Command Line Interface (AWS CLI), see [Tutorial: Update a maintenance window using the AWS CLI](maintenance-windows-cli-tutorials-update.md). 

**Topics**
+ [Updating or deleting a maintenance window using the console](#sysman-maintenance-update-mw)
+ [Updating or deregistering maintenance window targets using the console](#sysman-maintenance-update-target)
+ [Updating or deregistering maintenance window tasks using the console](#sysman-maintenance-update-tasks)

## Updating or deleting a maintenance window using the console
<a name="sysman-maintenance-update-mw"></a>

You can update a maintenance window to change its name, description, and schedule, and whether the maintenance window should allow unregistered targets.

**To update or delete a maintenance window**

1. Open the AWS Systems Manager console at [https://console.aws.amazon.com/systems-manager/](https://console.aws.amazon.com/systems-manager/).

1. In the navigation pane, choose **Maintenance Windows**. 

1. Select the button next to the maintenance window that you want to update or delete, and then do one of the following:
   + Choose **Delete**. The system prompts you to confirm your actions. 
   + Choose **Edit**. On the **Edit maintenance window** page, change the values and options that you want, and then choose **Save changes**.

     For information about the configuration choices you can make, see [Create a maintenance window using the console](sysman-maintenance-create-mw.md).

## Updating or deregistering maintenance window targets using the console
<a name="sysman-maintenance-update-target"></a>

You can update or deregister the targets of a maintenance window. If you choose to update a maintenance window target you can specify a new target name, description, and owner. You can also choose different targets. 

**To update or delete the targets of a maintenance window**

1. Open the AWS Systems Manager console at [https://console.aws.amazon.com/systems-manager/](https://console.aws.amazon.com/systems-manager/).

1. In the navigation pane, choose **Maintenance Windows**. 

1. Choose the name of the maintenance window that you want to update, choose the **Targets** tab, and then do one of the following:
   + To update targets, select the button next to the target to update, and then choose **Edit**.
   + To deregister targets, select the button next to the target to deregister, and then choose **Deregister target**. In the **Deregister maintenance windows target** dialog box, choose **Deregister**.

## Updating or deregistering maintenance window tasks using the console
<a name="sysman-maintenance-update-tasks"></a>

You can update or deregister the tasks of a maintenance window. If you choose to update, you can specify a new task name, description, and owner. For Run Command and Automation tasks, you can choose a different SSM document for the tasks. You can't, however, edit a task to change its type. For example, if you created an Automation task, you can't edit that task and change it to a Run Command task. 

**To update or delete the tasks of a maintenance window using the console**

1. Open the AWS Systems Manager console at [https://console.aws.amazon.com/systems-manager/](https://console.aws.amazon.com/systems-manager/).

1. In the navigation pane, choose **Maintenance Windows**. 

1. Choose the name of the maintenance window that you want to update.

1. Choose the **Tasks** tab, and then select the button next to the task to update.

1. Do one of the following:
   + To deregister a task, choose **Deregister task**.
   + To edit the task, choose **Edit**. Change the values and options that you want, and then choose **Edit task**.

# Tutorials
<a name="maintenance-windows-tutorials"></a>

The tutorials in this section show you how to perform common tasks when working with maintenance windows.

**Complete prerequisites**  
Before trying these tutorials, complete the following prerequisites.
+ **Configure the AWS CLI on your local machine** – Before you can run AWS CLI commands, you must install and configure the CLI on your local machine. For information, see [Installing or updating the latest version of the AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html) and [Installing the AWS Tools for PowerShell](https://docs.aws.amazon.com/powershell/latest/userguide/pstools-getting-set-up.html).
+ **Verify maintenance window roles and permissions** – An AWS administrator in your account must grant you the AWS Identity and Access Management (IAM) permissions you need to manage maintenance windows using the CLI. For information, see [Setting up Maintenance Windows](setting-up-maintenance-windows.md).
+ **Create or configure an instance that is compatible with Systems Manager ** – You need at least one Amazon Elastic Compute Cloud (Amazon EC2) instance that is configured for use with Systems Manager to complete the tutorials. This means that SSM Agent is installed on the instance, and an IAM instance profile for Systems Manager is attached to the instance. 

  We recommend launching an instance from one AWS managed Amazon Machine Image (AMI) with the agent preinstalled. For more information, see [Find AMIs with the SSM Agent preinstalled](ami-preinstalled-agent.md).

  For information about installing SSM Agent on an instance, see the following topics:
  + [Manually installing and uninstalling SSM Agent on EC2 instances for Windows Server](manually-install-ssm-agent-windows.md)
  + [Manually installing and uninstalling SSM Agent on EC2 instances for Linux](manually-install-ssm-agent-linux.md)

  For information about configuring IAM permissions for Systems Manager to your instance, see [Configure instance permissions required for Systems Manager](setup-instance-permissions.md).
+ **Create additional resources as needed** – Run Command, a tool in Systems Manager, includes many tasks that don't require you to create resources other than those listed in this prerequisites topic. For that reason, we provide a simple Run Command task for you to use your first time through the tutorials. You also need an EC2 instance that is configured to use with Systems Manager, as described earlier in this topic. After you configure that instance, you can register a simple Run Command task. 

  The Systems Manager Maintenance Windows tool supports running the following four types of tasks: 
  + Run Command commands
  + Systems Manager Automation workflows
  + AWS Lambda functions
  + AWS Step Functions tasks

  In general, if a maintenance window task that you want to run requires additional resources, you should create them first. For example, if you want a maintenance window that runs an AWS Lambda function, create the Lambda function before you begin; for a Run Command task, create the S3 bucket that you can save command output to (if you plan to do so); and so on.

**Topics**
+ [Tutorials: Create and manage maintenance windows using the AWS CLI](maintenance-window-tutorial-cli.md)
+ [Tutorial: Create a maintenance window for patching using the console](maintenance-window-tutorial-patching.md)

# Tutorials: Create and manage maintenance windows using the AWS CLI
<a name="maintenance-window-tutorial-cli"></a>

This section includes tutorials that help you learn how to use the AWS Command Line Interface (AWS CLI) to do the following:
+ Create and configure a maintenance window
+ View information about a maintenance window
+ View information about maintenance windows tasks and task executions
+ Update a maintenance window
+ Delete a maintenance window

**Keep track of resource IDs**  
As you complete the tasks in these AWS CLI tutorials, keep track of resource IDs generated by the commands you run. You use many of these as input for subsequent commands. For example, when you create the maintenance window, the system provides you with a maintenance window ID in the following format.

```
{
   "WindowId":"mw-0c50858d01EXAMPLE"
}
```

Make a note of the following system-generated IDs because the tutorials in this section use them:
+ `WindowId`
+ `WindowTargetId`
+ `WindowTaskId`
+ `WindowExecutionId`
+ `TaskExecutionId`
+ `InvocationId`
+ `ExecutionId`

You also need the ID of the EC2 instance that you plan to use in the tutorials. For example: `i-02573cafcfEXAMPLE`

**Topics**
+ [Tutorial: Create and configure a maintenance window using the AWS CLI](maintenance-windows-cli-tutorials-create.md)
+ [Tutorial: View information about maintenance windows using the AWS CLI](maintenance-windows-cli-tutorials-describe.md)
+ [Tutorial: View information about tasks and task executions using the AWS CLI](mw-cli-tutorial-task-info.md)
+ [Tutorial: Update a maintenance window using the AWS CLI](maintenance-windows-cli-tutorials-update.md)
+ [Tutorial: Delete a maintenance window using the AWS CLI](mw-cli-tutorial-delete-mw.md)

# Tutorial: Create and configure a maintenance window using the AWS CLI
<a name="maintenance-windows-cli-tutorials-create"></a>

This tutorial demonstrates how to use the AWS Command Line Interface (AWS CLI) to create and configure a maintenance window, its targets, and its tasks. The main path through the tutorial consists of simple steps. You create a single maintenance window, identify a single target, and set up a simple task for the maintenance window to run. Along the way, we provide information you can use to try more complicated scenarios.

As you follow the steps in this tutorial, replace the values in italicized *red* text with your own options and IDs. For example, replace the maintenance window ID *mw-0c50858d01EXAMPLE* and the instance ID *i-02573cafcfEXAMPLE* with IDs of resources you create.

**Topics**
+ [Step 1: Create the maintenance window using the AWS CLI](mw-cli-tutorial-create-mw.md)
+ [Step 2: Register a target node with the maintenance window using the AWS CLI](mw-cli-tutorial-targets.md)
+ [Step 3: Register a task with the maintenance window using the AWS CLI](mw-cli-tutorial-tasks.md)

# Step 1: Create the maintenance window using the AWS CLI
<a name="mw-cli-tutorial-create-mw"></a>

In this step, you create a maintenance window and specify its basic options, such as name, schedule, and duration. In later steps, you choose the instance it updates and the task it runs.

In our example, you create a maintenance window that runs every five minutes. Normally, you wouldn't run a maintenance window this frequently. However, with this rate you can see your tutorial results quickly. We will show you how to change to a less frequent rate after the task has run successfully.

**Note**  
For an explanation of how the various schedule-related options for maintenance windows relate to one another, see [Maintenance window scheduling and active period options](maintenance-windows-schedule-options.md).  
For more information about working with the `--schedule` option, see [Reference: Cron and rate expressions for Systems Manager](reference-cron-and-rate-expressions.md).

**To create a maintenance window using the AWS CLI**

1. Open the AWS Command Line Interface (AWS CLI) and run the following command on your local machine to create a maintenance window that does the following:
   + Runs every five minutes for up to two hours (as needed).
   + Prevents new tasks from starting within one hour of the end of the maintenance window operation.
   + Allows unassociated targets (instances that you haven't registered with the maintenance window).
   + Indicates through the use of custom tags that its creator intends to use it in a tutorial.

------
#### [ Linux & macOS ]

   ```
   aws ssm create-maintenance-window \
       --name "My-First-Maintenance-Window" \
       --schedule "rate(5 minutes)" \
       --duration 2 \
       --cutoff 1 \
       --allow-unassociated-targets \
       --tags "Key=Purpose,Value=Tutorial"
   ```

------
#### [ Windows ]

   ```
   aws ssm create-maintenance-window ^
       --name "My-First-Maintenance-Window" ^
       --schedule "rate(5 minutes)" ^
       --duration 2 ^
       --cutoff 1 ^
       --allow-unassociated-targets ^
       --tags "Key"="Purpose","Value"="Tutorial"
   ```

------

   The system returns information similar to the following.

   ```
   {
      "WindowId":"mw-0c50858d01EXAMPLE"
   }
   ```

1. Now run the following command to view details about this and any other maintenance windows already in your account.

   ```
   aws ssm describe-maintenance-windows
   ```

   The system returns information similar to the following.

   ```
   {
      "WindowIdentities":[
         {
               "WindowId": "mw-0c50858d01EXAMPLE",
               "Name": "My-First-Maintenance-Window",
               "Enabled": true,
               "Duration": 2,
               "Cutoff": 1,
               "NextExecutionTime": "2019-05-11T16:46:16.991Z"
         }
      ]
   }
   ```

Continue to [Step 2: Register a target node with the maintenance window using the AWS CLI](mw-cli-tutorial-targets.md).

# Step 2: Register a target node with the maintenance window using the AWS CLI
<a name="mw-cli-tutorial-targets"></a>

In this step, you register a target with your new maintenance window. In this case, you specify which node to update when the maintenance window runs. 

For an example of registering more than one node at a time using node IDs, examples of using tags to identify multiple nodes, and examples of specifying resource groups as targets, see [Examples: Register targets with a maintenance window](mw-cli-tutorial-targets-examples.md).

**Note**  
You should already have created an Amazon Elastic Compute Cloud (Amazon EC2) instance to use in this step, as described in the [Maintenance Windows tutorial prerequisites](maintenance-windows-tutorials.md).

**To register a target node with a maintenance window using the AWS CLI**

1. Run the following command on your local machine. Replace each *example resource placeholder* with your own information.

------
#### [ Linux & macOS ]

   ```
   aws ssm register-target-with-maintenance-window \
       --window-id "mw-0c50858d01EXAMPLE" \
       --resource-type "INSTANCE" \
       --target "Key=InstanceIds,Values=i-02573cafcfEXAMPLE"
   ```

------
#### [ Windows ]

   ```
   aws ssm register-target-with-maintenance-window ^
       --window-id "mw-0c50858d01EXAMPLE" ^
       --resource-type "INSTANCE" ^
       --target "Key=InstanceIds,Values=i-02573cafcfEXAMPLE"
   ```

------

   The system returns information similar to the following.

   ```
   {
      "WindowTargetId":"e32eecb2-646c-4f4b-8ed1-205fbEXAMPLE"
   }
   ```

1. Now run the following command on your local machine to view details about your maintenance window target.

------
#### [ Linux & macOS ]

   ```
   aws ssm describe-maintenance-window-targets \
       --window-id "mw-0c50858d01EXAMPLE"
   ```

------
#### [ Windows ]

   ```
   aws ssm describe-maintenance-window-targets ^
       --window-id "mw-0c50858d01EXAMPLE"
   ```

------

   The system returns information similar to the following.

   ```
   {
       "Targets": [
           {
               "WindowId": "mw-0c50858d01EXAMPLE",
               "WindowTargetId": "e32eecb2-646c-4f4b-8ed1-205fbEXAMPLE",
               "ResourceType": "INSTANCE",
               "Targets": [
                   {
                       "Key": "InstanceIds",
                       "Values": [
                           "i-02573cafcfEXAMPLE"
                       ]
                   }
               ]
           }
       ]
   }
   ```

Continue to [Step 3: Register a task with the maintenance window using the AWS CLI](mw-cli-tutorial-tasks.md). 

# Examples: Register targets with a maintenance window
<a name="mw-cli-tutorial-targets-examples"></a>

You can register a single node as a target using its node ID, as demonstrated in [Step 2: Register a target node with the maintenance window using the AWS CLI](mw-cli-tutorial-targets.md). You can also register one or more nodes as targets using the command formats on this page.

In general, there are two methods for identifying the nodes you want to use as maintenance window targets: specifying individual nodes, and using resource tags. The resource tags method provides more options, as shown in examples 2-3. 

You can also specify one or more resource groups as the target of a maintenance window. A resource group can include nodes and many other types of supported AWS resources. Examples 4 and 5, next, demonstrate how to add resource groups to your maintenance window targets.

**Note**  
If a single maintenance window task is registered with multiple targets, its task invocations occur sequentially and not in parallel. If your task must run on multiple targets at the same time, register a task for each target individually and assign each task the same priority level.

For more information about creating and managing resource groups, see [What are resource groups?](https://docs.aws.amazon.com/ARG/latest/userguide/resource-groups.html) in the *AWS Resource Groups User Guide* and [Resource Groups and Tagging for AWS](https://aws.amazon.com/blogs/aws/resource-groups-and-tagging/) in the *AWS News Blog*.

For information about quotas for Maintenance Windows, a tool in AWS Systems Manager, in addition to those specified in the following examples, see [Systems Manager service quotas](https://docs.aws.amazon.com/general/latest/gr/ssm.html#limits_ssm) in the *Amazon Web Services General Reference*.

## Example 1: Register multiple targets using node IDs
<a name="mw-target-example-1"></a>

Run the following command on your local machine format to register multiple nodes as targets using their node IDs. Replace each *example resource placeholder* with your own information.

------
#### [ Linux & macOS ]

```
aws ssm register-target-with-maintenance-window \
    --window-id "mw-0c50858d01EXAMPLE" \
    --resource-type "INSTANCE" \
    --target "Key=InstanceIds,Values=i-02573cafcfEXAMPLE,i-0471e04240EXAMPLE,i-07782c72faEXAMPLE"
```

------
#### [ Windows ]

```
aws ssm register-target-with-maintenance-window ^
    --window-id "mw-0c50858d01EXAMPLE ^
    --resource-type "INSTANCE" ^
    --target "Key=InstanceIds,Values=i-02573cafcfEXAMPLE,i-0471e04240EXAMPLE,i-07782c72faEXAMPLE
```

------

**Recommended use**: Most useful when registering a unique group of nodes with any maintenance window for the first time and they do *not* share a common node tag.

**Quotas:** You can specify up to 50 nodes total for each maintenance window target.

## Example 2: Register targets using resource tags applied to nodes
<a name="mw-target-example-2"></a>

Run the following command on your local machine to register nodes that are all already tagged with a key-value pair you have assigned. Replace each *example resource placeholder* with your own information.

------
#### [ Linux & macOS ]

```
aws ssm register-target-with-maintenance-window \
    --window-id "mw-0c50858d01EXAMPLE" \
    --resource-type "INSTANCE" \
    --target "Key=tag:Region,Values=East"
```

------
#### [ Windows ]

```
aws ssm register-target-with-maintenance-window ^
    --window-id "mw-0c50858d01EXAMPLE" ^
    --resource-type "INSTANCE" ^
    --target "Key=tag:Region,Values=East"
```

------

**Recommended use**: Most useful when registering a unique group of nodes with any maintenance window for the first time and they *do* share a common node tag.

**Quotas:** You can specify up to five key-value pairs total for each target. If you specify more than one key-value pair, a node must be tagged with *all* the tag keys and values you specify to be included in the target group.

**Note**  
You can tag a group of nodes with the tag-key `Patch Group` or `PatchGroup` and assign the nodes a common key value, such as `my-patch-group`. (You must use `PatchGroup`, without a space, if you have [allowed tags in EC2 instance metadata](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/Using_Tags.html#allow-access-to-tags-in-IMDS).) Patch Manager, a tool in Systems Manager, evaluates the `Patch Group` or `PatchGroup` key on nodes to help determine which patch baseline applies to them. If your task will run the `AWS-RunPatchBaseline` SSM document (or the legacy `AWS-ApplyPatchBaseline` SSM document), you can specify the same `Patch Group` or `PatchGroup` key-value pair when you register targets with a maintenance window. For example: `--target "Key=tag:PatchGroup,Values=my-patch-group`. Doing so allows you to use a maintenance window to update patches on a group of nodes that are already associated with the same patch baseline. For more information, see [Patch groups](patch-manager-patch-groups.md).

## Example 3: Register targets using a group of tag keys (without tag values)
<a name="mw-target-example-3"></a>

Run the following command on your local machine to register nodes that all have one or more tag keys assigned to them, regardless of their key values. Replace each *example resource placeholder* with your own information.

------
#### [ Linux & macOS ]

```
aws ssm register-target-with-maintenance-window \
    --window-id "mw-0c50858d01EXAMPLE" \
    --resource-type "INSTANCE" \
    --target "Key=tag-key,Values=Name,Instance-Type,CostCenter"
```

------
#### [ Windows ]

```
aws ssm register-target-with-maintenance-window ^
    --window-id "mw-0c50858d01EXAMPLE" ^
    --resource-type "INSTANCE" ^
    --target "Key=tag-key,Values=Name,Instance-Type,CostCenter"
```

------

**Recommended use**: Useful when you want to target nodes by specifying multiple tag *keys* (without their values) rather than just one tag-key or a tag key-value pair.

**Quotas:** You can specify up to five tag-keys total for each target. If you specify more than one tag key, a node must be tagged with *all* the tag keys you specify to be included in the target group.

## Example 4: Register targets using a resource group name
<a name="mw-target-example-4"></a>

Run the following command on your local machine to register a specified resource group, regardless of the type of resources it contains. Replace *mw-0c50858d01EXAMPLE* with your own information. If the tasks you assign to the maintenance window don't act on a type of resource included in this resource group, the system might report an error. Tasks for which a supported resource type is found continue to run despite these errors.

------
#### [ Linux & macOS ]

```
aws ssm register-target-with-maintenance-window \
    --window-id "mw-0c50858d01EXAMPLE" \
    --resource-type "RESOURCE_GROUP" \
    --target "Key=resource-groups:Name,Values=MyResourceGroup"
```

------
#### [ Windows ]

```
aws ssm register-target-with-maintenance-window ^
    --window-id "mw-0c50858d01EXAMPLE" ^
    --resource-type "RESOURCE_GROUP" ^
    --target "Key=resource-groups:Name,Values=MyResourceGroup"
```

------

**Recommended use**: Useful when you want to quickly specify a resource group as a target without evaluating whether all of its resource types will be targeted by a maintenance window, or when you know that the resource group contains only the resource types that your tasks perform actions on.

**Quotas:** You can specify only one resource group as a target.

## Example 5: Register targets by filtering resource types in a resource group
<a name="mw-target-example-5"></a>

Run the following command on your local machine to register only certain resource types that belong to a resource group that you specify. Replace *mw-0c50858d01EXAMPLE* with your own information. With this option, even if you add a task for a resource type that belongs to the resource group, the task won’t run if you haven’t explicitly added the resource type to the filter.

------
#### [ Linux & macOS ]

```
aws ssm register-target-with-maintenance-window \
    --window-id "mw-0c50858d01EXAMPLE" \
    --resource-type "RESOURCE_GROUP" \
    --target "Key=resource-groups:Name,Values=MyResourceGroup" \
    "Key=resource-groups:ResourceTypeFilters,Values=AWS::EC2::Instance,AWS::ECS::Cluster"
```

------
#### [ Windows ]

```
aws ssm register-target-with-maintenance-window ^
    --window-id "mw-0c50858d01EXAMPLE" ^
    --resource-type "RESOURCE_GROUP" ^
    --target "Key=resource-groups:Name,Values=MyResourceGroup" ^
    "Key=resource-groups:ResourceTypeFilters,Values=AWS::EC2::Instance,AWS::ECS::Cluster"
```

------

**Recommended use**: Useful when you want to maintain strict control over the types of AWS resources your maintenance window can run actions on, or when your resource group contains a large number of resource types and you want to avoid unnecessary error reports in your maintenance window logs.

**Quotas:** You can specify only one resource group as a target.

# Step 3: Register a task with the maintenance window using the AWS CLI
<a name="mw-cli-tutorial-tasks"></a>

In this step of the tutorial, you register an AWS Systems Manager Run Command task that runs the `df` command on your Amazon Elastic Compute Cloud (Amazon EC2) instance for Linux. The results of this standard Linux command show how much space is free and how much is used on the disk file system of your instance.

-or-

If you're targeting an Amazon EC2 instance for Windows Server instead of Linux, replace **df** in the following command with **ipconfig**. Output from this command lists details about the IP address, subnet mask, and default gateway for adapters on the target instance.

When you're ready to register other task types, or use more of the available Systems Manager Run Command options, see [Examples: Register tasks with a maintenance window](mw-cli-register-tasks-examples.md). There, we provide more information about all four task types, and some of their most important options, to help you plan for more extensive real-world scenarios. 

**To register a task with a maintenance window**

1. Run the following command on your local machine. Replace each *example resource placeholder* with your own information. The version to run from a local Windows machine includes the escape characters ("/") that you need to run the command from your command line tool.

------
#### [ Linux & macOS ]

   ```
   aws ssm register-task-with-maintenance-window \
       --window-id mw-0c50858d01EXAMPLE \
       --task-arn "AWS-RunShellScript" \
       --max-concurrency 1 --max-errors 1 \
       --priority 10 \
       --targets "Key=InstanceIds,Values=i-0471e04240EXAMPLE" \
       --task-type "RUN_COMMAND" \
       --task-invocation-parameters '{"RunCommand":{"Parameters":{"commands":["df"]}}}'
   ```

------
#### [ Windows ]

   ```
   aws ssm register-task-with-maintenance-window ^
       --window-id mw-0c50858d01EXAMPLE ^
       --task-arn "AWS-RunShellScript" ^
       --max-concurrency 1 --max-errors 1 ^
       --priority 10 ^
       --targets "Key=InstanceIds,Values=i-02573cafcfEXAMPLE" ^
       --task-type "RUN_COMMAND" ^
       --task-invocation-parameters={\"RunCommand\":{\"Parameters\":{\"commands\":[\"df\"]}}}
   ```

------

   The system returns information similar to the following:

   ```
   {
       "WindowTaskId": "4f7ca192-7e9a-40fe-9192-5cb15EXAMPLE"
   }
   ```

1. Now run the following command to view details about the maintenance window task you created. 

------
#### [ Linux & macOS ]

   ```
   aws ssm describe-maintenance-window-tasks \
       --window-id mw-0c50858d01EXAMPLE
   ```

------
#### [ Windows ]

   ```
   aws ssm describe-maintenance-window-tasks ^
       --window-id mw-0c50858d01EXAMPLE
   ```

------

1. The system returns information similar to the following.

   ```
   {
       "Tasks": [
           {
               "WindowId": "mw-0c50858d01EXAMPLE",
               "WindowTaskId": "4f7ca192-7e9a-40fe-9192-5cb15EXAMPLE",
               "TaskArn": "AWS-RunShellScript",
               "Type": "RUN_COMMAND",
               "Targets": [
                   {
                       "Key": "InstanceIds",
                       "Values": [
                           "i-02573cafcfEXAMPLE"
                       ]
                   }
               ],
               "TaskParameters": {},
               "Priority": 10,
               "ServiceRoleArn": "arn:aws:iam::123456789012:role/MyMaintenanceWindowServiceRole",
               "MaxConcurrency": "1",
               "MaxErrors": "1"
           }
       ]
   }
   ```

1. Wait until the task has had time to run, based on the schedule you specified in [Step 1: Create the maintenance window using the AWS CLI](mw-cli-tutorial-create-mw.md). For example, if you specified **--schedule "rate(5 minutes)"**, wait five minutes. Then run the following command to view information about any executions that occurred for this task. 

------
#### [ Linux & macOS ]

   ```
   aws ssm describe-maintenance-window-executions \
       --window-id mw-0c50858d01EXAMPLE
   ```

------
#### [ Windows ]

   ```
   aws ssm describe-maintenance-window-executions ^
       --window-id mw-0c50858d01EXAMPLE
   ```

------

   The system returns information similar to the following.

   ```
   {
       "WindowExecutions": [
           {
               "WindowId": "mw-0c50858d01EXAMPLE",
               "WindowExecutionId": "14bea65d-5ccc-462d-a2f3-e99c8EXAMPLE",
               "Status": "SUCCESS",
               "StartTime": 1557593493.096,
               "EndTime": 1557593498.611
           }
       ]
   }
   ```

**Tip**  
After the task runs successfully, you can decrease the rate at which the maintenance window runs. For example, run the following command to decrease the frequency to once a week. Replace *mw-0c50858d01EXAMPLE* with your own information.  

```
aws ssm update-maintenance-window \
    --window-id mw-0c50858d01EXAMPLE \
    --schedule "rate(7 days)"
```

```
aws ssm update-maintenance-window ^
    --window-id mw-0c50858d01EXAMPLE ^
    --schedule "rate(7 days)"
```
For information about managing maintenance window schedules, see [Reference: Cron and rate expressions for Systems Manager](reference-cron-and-rate-expressions.md) and [Maintenance window scheduling and active period options](maintenance-windows-schedule-options.md).  
For information about using the AWS Command Line Interface (AWS CLI) to modify a maintenance window, see [Tutorial: Update a maintenance window using the AWS CLI](maintenance-windows-cli-tutorials-update.md).

For practice running AWS CLI commands to view more details about your maintenance window task and its executions, continue to [Tutorial: View information about tasks and task executions using the AWS CLI](mw-cli-tutorial-task-info.md).

**Accessing tutorial command output**  
It's beyond the scope of this tutorial to use the AWS CLI to view the *output* of the Run Command command associated with your maintenance window task executions.

You could view this data, however, using the AWS CLI. (You could also view the output in the Systems Manager console or in a log file stored in an Amazon Simple Storage Service (Amazon S3) bucket, if you had configured the maintenance window to store command output there.) You would find that the output of the **df** command on an EC2 instance for Linux is similar to the following.

```
Filesystem 1K-blocks Used Available Use% Mounted on

devtmpfs 485716 0 485716 0% /dev

tmpfs 503624 0 503624 0% /dev/shm

tmpfs 503624 328 503296 1% /run

tmpfs 503624 0 503624 0% /sys/fs/cgroup

/dev/xvda1 8376300 1464160 6912140 18% /
```

The output of the **ipconfig** command on an EC2 instance for Windows Server is similar to the following:

```
Windows IP Configuration


Ethernet adapter Ethernet 2:

   Connection-specific DNS Suffix  . : example.com
   IPv4 Address. . . . . . . . . . . : 10.24.34.0/23
   Subnet Mask . . . . . . . . . . . : 255.255.255.255
   Default Gateway . . . . . . . . . : 0.0.0.0

Ethernet adapter Ethernet:

   Media State . . . . . . . . . . . : Media disconnected
   Connection-specific DNS Suffix  . : abc1.wa.example.net

Wireless LAN adapter Local Area Connection* 1:

   Media State . . . . . . . . . . . : Media disconnected
   Connection-specific DNS Suffix  . :

Wireless LAN adapter Wi-Fi:

   Connection-specific DNS Suffix  . :
   Link-local IPv6 Address . . . . . : fe80::100b:c234:66d6:d24f%4
   IPv4 Address. . . . . . . . . . . : 192.0.2.0
   Subnet Mask . . . . . . . . . . . : 255.255.255.0
   Default Gateway . . . . . . . . . : 192.0.2.0

Ethernet adapter Bluetooth Network Connection:

   Media State . . . . . . . . . . . : Media disconnected
   Connection-specific DNS Suffix  . :
```

# Examples: Register tasks with a maintenance window
<a name="mw-cli-register-tasks-examples"></a>

You can register a task in Run Command, a tool in AWS Systems Manager, with a maintenance window using the AWS Command Line Interface (AWS CLI), as demonstrated in [Register tasks with the maintenance window](mw-cli-tutorial-tasks.md). You can also register tasks for Systems Manager Automation workflows, AWS Lambda functions, and AWS Step Functions tasks, as demonstrated later in this topic.

**Note**  
Specify one or more targets for maintenance window Run Command-type tasks. Depending on the task, targets are optional for other maintenance window task types (Automation, AWS Lambda, and AWS Step Functions). For more information about running tasks that don't specify targets, see [Registering maintenance window tasks without targets](maintenance-windows-targetless-tasks.md).

In this topic, we provide examples of using the AWS Command Line Interface (AWS CLI) command `register-task-with-maintenance-window` to register each of the four supported task types with a maintenance window. The examples are for demonstration only, but you can modify them to create working task registration commands. 

**Using the --cli-input-json option**  
To better manage your task options, you can use the command option `--cli-input-json`, with option values referenced in a JSON file. 

To use the sample JSON file content we provide in the following examples, do the following on your local machine:

1. Create a file with a name such as `MyRunCommandTask.json`, `MyAutomationTask.json`, or another name that you prefer.

1. Copy the contents of our JSON sample into the file.

1. Modify the contents of the file for your task registration, and then save the file.

1. In the same directory where you stored the file, run the following command. Substitute your file name for *MyFile.json*. 

------
#### [ Linux & macOS ]

   ```
   aws ssm register-task-with-maintenance-window \
       --cli-input-json file://MyFile.json
   ```

------
#### [ Windows ]

   ```
   aws ssm register-task-with-maintenance-window ^
       --cli-input-json file://MyFile.json
   ```

------

**Pseudo parameters in maintenance window tasks**  
In some examples, we use *pseudo parameters* as the method to pass ID information to your tasks. For instance, `{{TARGET_ID}}` and `{{RESOURCE_ID}}` can be used to pass IDs of AWS resources to Automation, Lambda, and Step Functions tasks. For more information about pseudo parameters in `--task-invocation-parameters` content, see [Using pseudo parameters when registering maintenance window tasks](maintenance-window-tasks-pseudo-parameters.md). 

**More info**  
+ [Parameter options for the register-task-with-maintenance-windows command](mw-cli-task-options.md).
+ [https://docs.aws.amazon.com/cli/latest/reference/ssm/register-task-with-maintenance-window.html](https://docs.aws.amazon.com/cli/latest/reference/ssm/register-task-with-maintenance-window.html) in the *AWS CLI Command Reference*
+ [https://docs.aws.amazon.com/systems-manager/latest/APIReference/API_RegisterTaskWithMaintenanceWindow.html](https://docs.aws.amazon.com/systems-manager/latest/APIReference/API_RegisterTaskWithMaintenanceWindow.html) in the *AWS Systems Manager API Reference*

## Task registration examples
<a name="task-examples"></a>

The following sections provide a sample AWS CLI command for registering a supported task type and a JSON sample that can be used with the `--cli-input-json` option.

### Register a Systems Manager Run Command task
<a name="register-tasks-tutorial-run-command"></a>

The following examples demonstrate how to register Systems Manager Run Command tasks with a maintenance window using the AWS CLI.

------
#### [ Linux & macOS ]

```
aws ssm register-task-with-maintenance-window \
    --window-id mw-0c50858d01EXAMPLE \
    --task-arn "AWS-RunShellScript" \
    --max-concurrency 1 --max-errors 1 --priority 10 \
    --targets "Key=InstanceIds,Values=i-02573cafcfEXAMPLE" \
    --task-type "RUN_COMMAND" \
    --task-invocation-parameters '{"RunCommand":{"Parameters":{"commands":["df"]}}}'
```

------
#### [ Windows ]

```
aws ssm register-task-with-maintenance-window ^
    --window-id mw-0c50858d01EXAMPLE ^
    --task-arn "AWS-RunShellScript" ^
    --max-concurrency 1 --max-errors 1 --priority 10 ^
    --targets "Key=InstanceIds,Values=i-02573cafcfEXAMPLE" ^
    --task-type "RUN_COMMAND" ^
    --task-invocation-parameters "{\"RunCommand\":{\"Parameters\":{\"commands\":[\"df\"]}}}"
```

------

**JSON content to use with `--cli-input-json` file option:**

```
{
    "TaskType": "RUN_COMMAND",
    "WindowId": "mw-0c50858d01EXAMPLE",
    "Description": "My Run Command task to update SSM Agent on an instance",
    "MaxConcurrency": "1",
    "MaxErrors": "1",
    "Name": "My-Run-Command-Task",
    "Priority": 10,
    "Targets": [
        {
            "Key": "WindowTargetIds",
            "Values": [
                "e32eecb2-646c-4f4b-8ed1-205fbEXAMPLE"
            ]
        }
    ],
    "TaskArn": "AWS-UpdateSSMAgent",
    "TaskInvocationParameters": {
        "RunCommand": {
            "Comment": "A TaskInvocationParameters test comment",
            "NotificationConfig": {
                "NotificationArn": "arn:aws:sns:region:123456789012:my-sns-topic-name",
                "NotificationEvents": [
                    "All"
                ],
                "NotificationType": "Invocation"
            },
            "OutputS3BucketName": "amzn-s3-demo-bucket",
            "OutputS3KeyPrefix": "S3-PREFIX",
            "TimeoutSeconds": 3600
        }
    }
}
```

### Register a Systems Manager Automation task
<a name="register-tasks-tutorial-automation"></a>

The following examples demonstrate how to register Systems Manager Automation tasks with a maintenance window using the AWS CLI: 

**AWS CLI command:**

------
#### [ Linux & macOS ]

```
aws ssm register-task-with-maintenance-window \
    --window-id "mw-0c50858d01EXAMPLE" \
    --task-arn "AWS-RestartEC2Instance" \
    --service-role-arn arn:aws:iam::123456789012:role/MyMaintenanceWindowServiceRole \
    --task-type AUTOMATION \
    --task-invocation-parameters "Automation={DocumentVersion=5,Parameters={InstanceId='{{RESOURCE_ID}}'}}" \
    --priority 0 --name "My-Restart-EC2-Instances-Automation-Task" \
    --description "Automation task to restart EC2 instances"
```

------
#### [ Windows ]

```
aws ssm register-task-with-maintenance-window ^
    --window-id "mw-0c50858d01EXAMPLE" ^
    --task-arn "AWS-RestartEC2Instance" ^
    --service-role-arn arn:aws:iam::123456789012:role/MyMaintenanceWindowServiceRole ^
    --task-type AUTOMATION ^
    --task-invocation-parameters "Automation={DocumentVersion=5,Parameters={InstanceId='{{TARGET_ID}}'}}" ^
    --priority 0 --name "My-Restart-EC2-Instances-Automation-Task" ^
    --description "Automation task to restart EC2 instances"
```

------

**JSON content to use with `--cli-input-json` file option:**

```
{
    "WindowId": "mw-0c50858d01EXAMPLE",
        "TaskArn": "AWS-PatchInstanceWithRollback",
    "TaskType": "AUTOMATION","TaskInvocationParameters": {
        "Automation": {
            "DocumentVersion": "1",
            "Parameters": {
                "instanceId": [
                    "{{RESOURCE_ID}}"
                ]
            }
        }
    }
}
```

### Register an AWS Lambda task
<a name="register-tasks-tutorial-lambda"></a>

The following examples demonstrate how to register Lambda function tasks with a maintenance window using the AWS CLI. 

For these examples, the user who created the Lambda function named it `SSMrestart-my-instances` and created two parameters called `instanceId` and `targetType`.

**Important**  
The IAM policy for Maintenance Windows requires that you add the prefix `SSM` to Lambda function (or alias) names. Before you proceed to register this type of task, update its name in AWS Lambda to include `SSM`. For example, if your Lambda function name is `MyLambdaFunction`, change it to `SSMMyLambdaFunction`.

**AWS CLI command:**

------
#### [ Linux & macOS ]

**Important**  
If you are using version 2 of the AWS CLI, you must include the option `--cli-binary-format raw-in-base64-out` in the following command if your Lambda payload is not base64 encoded. The `cli_binary_format` option is available only in version 2. For information about this and other AWS CLI `config` file settings, see [Supported `config` file settings](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-files.html#cli-configure-files-settings) in the *AWS Command Line Interface User Guide*.

```
aws ssm register-task-with-maintenance-window \
    --window-id "mw-0c50858d01EXAMPLE" \
    --targets "Key=WindowTargetIds,Values=e32eecb2-646c-4f4b-8ed1-205fbEXAMPLE" \
    --priority 2 --max-concurrency 10 --max-errors 5 --name "My-Lambda-Example" \
    --description "A description for my LAMBDA example task" --task-type "LAMBDA" \
    --task-arn "arn:aws:lambda:region:123456789012:function:serverlessrepo-SSMrestart-my-instances-C4JF9EXAMPLE" \
    --task-invocation-parameters '{"Lambda":{"Payload":"{\"InstanceId\":\"{{RESOURCE_ID}}\",\"targetType\":\"{{TARGET_TYPE}}\"}","Qualifier": "$LATEST"}}'
```

------
#### [ PowerShell ]

**Important**  
If you are using version 2 of the AWS CLI, you must include the option `--cli-binary-format raw-in-base64-out` in the following command if your Lambda payload is not base64 encoded. The `cli_binary_format` option is available only in version 2. For information about this and other AWS CLI `config` file settings, see [Supported `config` file settings](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-files.html#cli-configure-files-settings) in the *AWS Command Line Interface User Guide*.

```
aws ssm register-task-with-maintenance-window `
    --window-id "mw-0c50858d01EXAMPLE" `
    --targets "Key=WindowTargetIds,Values=e32eecb2-646c-4f4b-8ed1-205fbEXAMPLE" `
    --priority 2 --max-concurrency 10 --max-errors 5 --name "My-Lambda-Example" `
    --description "A description for my LAMBDA example task" --task-type "LAMBDA" `
    --task-arn "arn:aws:lambda:region:123456789012:function:serverlessrepo-SSMrestart-my-instances-C4JF9EXAMPLE" `
    --task-invocation-parameters '{\"Lambda\":{\"Payload\":\"{\\\"InstanceId\\\":\\\"{{RESOURCE_ID}}\\\",\\\"targetType\\\":\\\"{{TARGET_TYPE}}\\\"}\",\"Qualifier\": \"$LATEST\"}}'
```

------

**JSON content to use with `--cli-input-json` file option:**

```
{
    "WindowId": "mw-0c50858d01EXAMPLE",
    "Targets": [
        {
            "Key": "WindowTargetIds",
            "Values": [
                "e32eecb2-646c-4f4b-8ed1-205fbEXAMPLE"
            ]
        }
    ],
    "TaskArn": "SSM_RestartMyInstances",
    "TaskType": "LAMBDA",
    "MaxConcurrency": "10",
    "MaxErrors": "10",
    "TaskInvocationParameters": {
        "Lambda": {
            "ClientContext": "ew0KICAi--truncated--0KIEXAMPLE",
            "Payload": "{ \"instanceId\": \"{{RESOURCE_ID}}\", \"targetType\": \"{{TARGET_TYPE}}\" }",
            "Qualifier": "$LATEST"
        }
    },
    "Name": "My-Lambda-Task",
    "Description": "A description for my LAMBDA task",
    "Priority": 5
}
```

### Register a Step Functions task
<a name="register-tasks-tutorial-step-functions"></a>

The following examples demonstrate how to register Step Functions state machine tasks with a maintenance window using the AWS CLI.

**Note**  
Maintenance window tasks support Step Functions Standard state machine workflows only. They don't support Express state machine workflows. For information about state machine workflow types, see [Standard vs. Express Workflows](https://docs.aws.amazon.com/step-functions/latest/dg/concepts-standard-vs-express.html) in the *AWS Step Functions Developer Guide*.

For these examples, the user who created the Step Functions state machine created a state machine named `SSMMyStateMachine` with a parameter called `instanceId`.

**Important**  
The AWS Identity and Access Management (IAM) policy for Maintenance Windows requires that you prefix Step Functions state machine names with `SSM`. Before you proceed to register this type of task, you must update its name in AWS Step Functions to include `SSM`. For example, if your state machine name is `MyStateMachine`, change it to `SSMMyStateMachine`.

**AWS CLI command:**

------
#### [ Linux & macOS ]

```
aws ssm register-task-with-maintenance-window \
    --window-id "mw-0c50858d01EXAMPLE" \
    --targets "Key=WindowTargetIds,Values=e32eecb2-646c-4f4b-8ed1-205fbEXAMPLE" \
    --task-arn arn:aws:states:region:123456789012:stateMachine:SSMMyStateMachine-MggiqEXAMPLE \
    --task-type STEP_FUNCTIONS \
    --task-invocation-parameters '{"StepFunctions":{"Input":"{\"InstanceId\":\"{{RESOURCE_ID}}\"}", "Name":"{{INVOCATION_ID}}"}}' \
    --priority 0 --max-concurrency 10 --max-errors 5 \
    --name "My-Step-Functions-Task" --description "A description for my Step Functions task"
```

------
#### [ PowerShell ]

```
aws ssm register-task-with-maintenance-window `
    --window-id "mw-0c50858d01EXAMPLE" `
    --targets "Key=WindowTargetIds,Values=e32eecb2-646c-4f4b-8ed1-205fbEXAMPLE" `
    --task-arn arn:aws:states:region:123456789012:stateMachine:SSMMyStateMachine-MggiqEXAMPLE `
    --task-type STEP_FUNCTIONS `
    --task-invocation-parameters '{\"StepFunctions\":{\"Input\":\"{\\\"InstanceId\\\":\\\"{{RESOURCE_ID}}\\\"}\", \"Name\":\"{{INVOCATION_ID}}\"}}' `
    --priority 0 --max-concurrency 10 --max-errors 5 `
    --name "My-Step-Functions-Task" --description "A description for my Step Functions task"
```

------

**JSON content to use with `--cli-input-json` file option:**

```
{
    "WindowId": "mw-0c50858d01EXAMPLE",
    "Targets": [
        {
            "Key": "WindowTargetIds",
            "Values": [
                "e32eecb2-646c-4f4b-8ed1-205fbEXAMPLE"
            ]
        }
    ],
    "TaskArn": "SSM_MyStateMachine",
    "TaskType": "STEP_FUNCTIONS",
    "MaxConcurrency": "10",
    "MaxErrors": "10",
    "TaskInvocationParameters": {
        "StepFunctions": {
            "Input": "{ \"instanceId\": \"{{TARGET_ID}}\" }",
            "Name": "{{INVOCATION_ID}}"
        }
    },
    "Name": "My-Step-Functions-Task",
    "Description": "A description for my Step Functions task",
    "Priority": 5
}
```

# Parameter options for the register-task-with-maintenance-windows command
<a name="mw-cli-task-options"></a>

The **register-task-with-maintenance-window** command provides several options for configuring a task according to your needs. Some are required, some are optional, and some apply to only a single maintenance window task type.

This topic provides information about some of these options to help you work with samples in this tutorial section. For information about all command options, see **[https://docs.aws.amazon.com/cli/latest/reference/ssm/register-task-with-maintenance-window.html](https://docs.aws.amazon.com/cli/latest/reference/ssm/register-task-with-maintenance-window.html)** in the *AWS CLI Command Reference*.

**Command option: `--task-arn`**  
The option `--task-arn` is used to specify the resource that the task operates on. The value that you specify depends on the type of task you're registering, as described in the following table.


**TaskArn formats for maintenance window tasks**  

| Maintenance window task type | TaskArn value | 
| --- | --- | 
|  **`RUN_COMMAND`** and ** `AUTOMATION`**  |  `TaskArn` is the SSM document name or Amazon Resource Name (ARN). For example:  `AWS-RunBatchShellScript`  -or- `arn:aws:ssm:region:111122223333:document/My-Document`.  | 
|  **`LAMBDA`**  |  `TaskArn` is the function name or ARN. For example:  `SSMMy-Lambda-Function` -or- `arn:aws:lambda:region:111122223333:function:SSMMyLambdaFunction`.  The IAM policy for Maintenance Windows requires that you add the prefix `SSM` to Lambda function (or alias) names. Before you proceed to register this type of task, update its name in AWS Lambda to include `SSM`. For example, if your Lambda function name is `MyLambdaFunction`, change it to `SSMMyLambdaFunction`.   | 
|  **`STEP_FUNCTIONS`**  |  `TaskArn` is the state machine ARN. For example:  `arn:aws:states:us-east-2:111122223333:stateMachine:SSMMyStateMachine`.  The IAM policy for maintenance windows requires that you prefix Step Functions state machine names with `SSM`. Before you register this type of task, you must update its name in AWS Step Functions to include `SSM`. For example, if your state machine name is `MyStateMachine`, change it to `SSMMyStateMachine`.   | 

**Command option: `--service-role-arn`**  
The role for AWS Systems Manager to assume when running the maintenance window task. 

For more information, see [Setting up Maintenance Windows](setting-up-maintenance-windows.md)

**Command option: `--task-invocation-parameters`**  
The `--task-invocation-parameters` option is used to specify the parameters that are unique to each of the four task types. The supported parameters for each of the four task types are described in the following table.

**Note**  
For information about using pseudo parameters in `--task-invocation-parameters` content, such as \$1\$1TARGET\$1ID\$1\$1, see [Using pseudo parameters when registering maintenance window tasks](maintenance-window-tasks-pseudo-parameters.md). 

Task invocation parameters options for maintenance window tasks


| Maintenance window task type | Available parameters  | Example | 
| --- | --- | --- | 
|  **`RUN_COMMAND`**  |  `Comment` `DocumentHash` `DocumentHashType` `NotificationConfig` `OutputS3BucketName` `OutPutS3KeyPrefix` `Parameters` `ServiceRoleArn` `TimeoutSeconds`  |  <pre>"TaskInvocationParameters": {<br />        "RunCommand": {<br />            "Comment": "My Run Command task comment",<br />            "DocumentHash": "6554ed3d--truncated--5EXAMPLE",<br />            "DocumentHashType": "Sha256",<br />            "NotificationConfig": {<br />                "NotificationArn": "arn:aws:sns:region:123456789012:my-sns-topic-name",<br />                "NotificationEvents": [<br />                    "FAILURE"<br />                ],<br />                "NotificationType": "Invocation"<br />            },<br />            "OutputS3BucketName": "amzn-s3-demo-bucket",<br />            "OutputS3KeyPrefix": "S3-PREFIX",<br />            "Parameters": {<br />                "commands": [<br />                    "Get-ChildItem$env: temp-Recurse|Remove-Item-Recurse-force"<br />                ]<br />            },<br />            "ServiceRoleArn": "arn:aws:iam::123456789012:role/MyMaintenanceWindowServiceRole",<br />            "TimeoutSeconds": 3600<br />        }<br />    }</pre>  | 
|  **`AUTOMATION`**  |  `DocumentVersion` `Parameters`  |  <pre>"TaskInvocationParameters": {<br />        "Automation": {<br />            "DocumentVersion": "3",<br />            "Parameters": {<br />                "instanceid": [<br />                    "{{TARGET_ID}}"<br />                ]<br />            }<br />        }<br />    }</pre>  | 
|  **`LAMBDA`**  |  `ClientContext` `Payload` `Qualifier`  |  <pre>"TaskInvocationParameters": {<br />        "Lambda": {<br />            "ClientContext": "ew0KICAi--truncated--0KIEXAMPLE",<br />            "Payload": "{ \"targetId\": \"{{TARGET_ID}}\", \"targetType\": \"{{TARGET_TYPE}}\" }",<br />            "Qualifier": "$LATEST"<br />        }<br />    }</pre>  | 
|  **`STEP_FUNCTIONS`**  |  `Input` `Name`  |  <pre>"TaskInvocationParameters": {<br />        "StepFunctions": {<br />            "Input": "{ \"targetId\": \"{{TARGET_ID}}\" }",<br />            "Name": "{{INVOCATION_ID}}"<br />        }<br />    }</pre>  | 

# Tutorial: View information about maintenance windows using the AWS CLI
<a name="maintenance-windows-cli-tutorials-describe"></a>

This tutorial includes commands to help you update or get information about your maintenance windows, tasks, executions, and invocations. The examples are organized by command to demonstrate how to use command options to filter for the type of detail you want to see.

As you follow the steps in this tutorial, replace the values in italicized *red* text with your own options and IDs. For example, replace the maintenance window ID *mw-0c50858d01EXAMPLE* and the instance ID *i-02573cafcfEXAMPLE* with IDs of resources you create.

For information about setting up and configuring the AWS Command Line Interface (AWS CLI), see [Installing, updating, and uninstalling the AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-install.html) and [Configuring the AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-configure.html).

**Topics**
+ [Examples for 'describe-maintenance-windows'](#mw-cli-tutorials-describe-maintenance-windows)
+ [Examples for 'describe-maintenance-window-targets'](#mw-cli-tutorials-describe-maintenance-window-targets)
+ [Examples for 'describe-maintenance-window-tasks'](#mw-cli-tutorials-describe-maintenance-window-tasks)
+ [Examples for 'describe-maintenance-windows-for-target'](#mw-cli-tutorials-describe-maintenance-windows-for-target)
+ [Examples for 'describe-maintenance-window-executions'](#mw-cli-tutorials-describe-maintenance-window-executions)
+ [Examples for 'describe-maintenance-window-schedule'](#mw-cli-tutorials-describe-maintenance-window-schedule)

## Examples for 'describe-maintenance-windows'
<a name="mw-cli-tutorials-describe-maintenance-windows"></a>

**List all maintenance windows in your AWS account**  
Run the following command.

```
aws ssm describe-maintenance-windows
```

The system returns information similar to the following.

```
{
   "WindowIdentities":[
      {
         "WindowId":"mw-0c50858d01EXAMPLE",
         "Name":"My-First-Maintenance-Window",
         "Enabled":true,
         "Duration":2,
         "Cutoff":0,
         "NextExecutionTime": "2019-05-18T17:01:01.137Z"        
      },
      {
         "WindowId":"mw-9a8b7c6d5eEXAMPLE",
         "Name":"My-Second-Maintenance-Window",
         "Enabled":true,
         "Duration":4,
         "Cutoff":1,
         "NextExecutionTime": "2019-05-30T03:30:00.137Z"        
      },
   ]
}
```

**List all enabled maintenance windows**  
Run the following command.

```
aws ssm describe-maintenance-windows --filters "Key=Enabled,Values=true"
```

The system returns information similar to the following.

```
{
   "WindowIdentities":[
      {
         "WindowId":"mw-0c50858d01EXAMPLE",
         "Name":"My-First-Maintenance-Window",
         "Enabled":true,
         "Duration":2,
         "Cutoff":0,
         "NextExecutionTime": "2019-05-18T17:01:01.137Z"        
      },
      {
         "WindowId":"mw-9a8b7c6d5eEXAMPLE",
         "Name":"My-Second-Maintenance-Window",
         "Enabled":true,
         "Duration":4,
         "Cutoff":1,
         "NextExecutionTime": "2019-05-30T03:30:00.137Z"        
      },
   ]
}
```

**List all disabled maintenance windows**  
Run the following command.

```
aws ssm describe-maintenance-windows --filters "Key=Enabled,Values=false"
```

The system returns information similar to the following.

```
{
    "WindowIdentities": [
        {
            "WindowId": "mw-6e5c9d4b7cEXAMPLE",
            "Name": "My-Disabled-Maintenance-Window",
            "Enabled": false,
            "Duration": 2,
            "Cutoff": 1
        }
    ]
}
```

**List all maintenance windows having names that start with a certain prefix**  
Run the following command.

```
aws ssm describe-maintenance-windows --filters "Key=Name,Values=My"
```

The system returns information similar to the following.

```
{
    "WindowIdentities": [
        {
            "WindowId": "mw-0c50858d01EXAMPLE",
            "Name": "My-First-Maintenance-Window",
            "Enabled": true,
            "Duration": 2,
            "Cutoff": 0,
            "NextExecutionTime": "2019-05-18T17:01:01.137Z"
        },
        {
            "WindowId": "mw-9a8b7c6d5eEXAMPLE",
            "Name": "My-Second-Maintenance-Window",
            "Enabled": true,
            "Duration": 4,
            "Cutoff": 1,
            "NextExecutionTime": "2019-05-30T03:30:00.137Z"
        },
        {
            "WindowId": "mw-6e5c9d4b7cEXAMPLE",
            "Name": "My-Disabled-Maintenance-Window",
            "Enabled": false,
            "Duration": 2,
            "Cutoff": 1
        }
    ]
}
```

## Examples for 'describe-maintenance-window-targets'
<a name="mw-cli-tutorials-describe-maintenance-window-targets"></a>

**Display the targets for a maintenance window matching a specific owner information value**  
Run the following command.

------
#### [ Linux & macOS ]

```
aws ssm describe-maintenance-window-targets \
    --window-id "mw-6e5c9d4b7cEXAMPLE" \
    --filters "Key=OwnerInformation,Values=CostCenter1"
```

------
#### [ Windows ]

```
aws ssm describe-maintenance-window-targets ^
    --window-id "mw-6e5c9d4b7cEXAMPLE" ^
    --filters "Key=OwnerInformation,Values=CostCenter1"
```

------

**Note**  
The supported filter keys are `Type`, `WindowTargetId` and `OwnerInformation`.

The system returns information similar to the following.

```
{
    "Targets": [
        {
            "WindowId": "mw-0c50858d01EXAMPLE",
            "WindowTargetId": "e32eecb2-646c-4f4b-8ed1-205fbEXAMPLE",
            "ResourceType": "INSTANCE",
            "Targets": [
                {
                    "Key": "tag:Name",
                    "Values": [
                        "Production"
                    ]
                }
            ],
            "OwnerInformation": "CostCenter1",
            "Name": "Target1"
        }
    ]
}
```

## Examples for 'describe-maintenance-window-tasks'
<a name="mw-cli-tutorials-describe-maintenance-window-tasks"></a>

**Show all registered tasks that invoke the SSM command document `AWS-RunPowerShellScript`**  
Run the following command.

------
#### [ Linux & macOS ]

```
aws ssm describe-maintenance-window-tasks \
    --window-id "mw-0c50858d01EXAMPLE" \
    --filters "Key=TaskArn,Values=AWS-RunPowerShellScript"
```

------
#### [ Windows ]

```
aws ssm describe-maintenance-window-tasks ^
    --window-id "mw-0c50858d01EXAMPLE" ^
    --filters "Key=TaskArn,Values=AWS-RunPowerShellScript"
```

------

The system returns information similar to the following.

```
{
   "Tasks":[
      {
         "ServiceRoleArn": "arn:aws:iam::111122223333:role/MyMaintenanceWindowServiceRole",
         "MaxErrors":"1",
         "TaskArn":"AWS-RunPowerShellScript",
         "MaxConcurrency":"1",
         "WindowTaskId":"4f7ca192-7e9a-40fe-9192-5cb15EXAMPLE",
         "TaskParameters":{
            "commands":{
               "Values":[
                  "driverquery.exe"
               ]
            }
         },
         "Priority":3,
         "Type":"RUN_COMMAND",
         "Targets":[
            {
               "TaskTargetId":"i-02573cafcfEXAMPLE",
               "TaskTargetType":"INSTANCE"
            }
         ]
      },
      {
         "ServiceRoleArn":"arn:aws:iam::111122223333:role/MyMaintenanceWindowServiceRole",
         "MaxErrors":"1",
         "TaskArn":"AWS-RunPowerShellScript",
         "MaxConcurrency":"1",
         "WindowTaskId":"4f7ca192-7e9a-40fe-9192-5cb15EXAMPLE",
         "TaskParameters":{
            "commands":{
               "Values":[
                  "ipconfig"
               ]
            }
         },
         "Priority":1,
         "Type":"RUN_COMMAND",
         "Targets":[
            {
               "TaskTargetId":"i-02573cafcfEXAMPLE",
               "TaskTargetType":"WINDOW_TARGET"
            }
         ]
      }
   ]
}
```

**Show all registered tasks that have a priority of "3"**  
Run the following command.

------
#### [ Linux & macOS ]

```
aws ssm describe-maintenance-window-tasks \
    --window-id "mw-9a8b7c6d5eEXAMPLE" \
    --filters "Key=Priority,Values=3"
```

------
#### [ Windows ]

```
aws ssm describe-maintenance-window-tasks ^
    --window-id "mw-9a8b7c6d5eEXAMPLE" ^
    --filters "Key=Priority,Values=3"
```

------

The system returns information similar to the following.

```
{
   "Tasks":[
      {
         "ServiceRoleArn":"arn:aws:iam::111122223333:role/MyMaintenanceWindowServiceRole",
         "MaxErrors":"1",
         "TaskArn":"AWS-RunPowerShellScript",
         "MaxConcurrency":"1",
         "WindowTaskId":"4f7ca192-7e9a-40fe-9192-5cb15EXAMPLE",
         "TaskParameters":{
            "commands":{
               "Values":[
                  "driverquery.exe"
               ]
            }
         },
         "Priority":3,
         "Type":"RUN_COMMAND",
         "Targets":[
            {
               "TaskTargetId":"i-02573cafcfEXAMPLE",
               "TaskTargetType":"INSTANCE"
            }
         ]
      }
   ]
}
```

**Show all registered tasks that have a priority of "1" and use Run Command**  
Run the following command.

------
#### [ Linux & macOS ]

```
aws ssm describe-maintenance-window-tasks \
    --window-id "mw-0c50858d01EXAMPLE" \
    --filters "Key=Priority,Values=1" "Key=TaskType,Values=RUN_COMMAND"
```

------
#### [ Windows ]

```
aws ssm describe-maintenance-window-tasks ^
    --window-id "mw-0c50858d01EXAMPLE" ^
    --filters "Key=Priority,Values=1" "Key=TaskType,Values=RUN_COMMAND"
```

------

The system returns information similar to the following.

```
{
    "Tasks": [
        {
            "WindowId": "mw-0c50858d01EXAMPLE",
            "WindowTaskId": "4f7ca192-7e9a-40fe-9192-5cb15EXAMPLE",
            "TaskArn": "AWS-RunShellScript",
            "Type": "RUN_COMMAND",
            "Targets": [
                {
                    "Key": "InstanceIds",
                    "Values": [
                        "i-02573cafcfEXAMPLE"
                    ]
                }
            ],
            "TaskParameters": {},
            "Priority": 1,
            "ServiceRoleArn": "arn:aws:iam::111122223333:role/MyMaintenanceWindowServiceRole",
            "MaxConcurrency": "1",
            "MaxErrors": "1"
        },
        {
            "WindowId": "mw-0c50858d01EXAMPLE",
            "WindowTaskId": "8a5c4629-31b0-4edd-8aea-33698EXAMPLE",
            "TaskArn": "AWS-UpdateSSMAgent",
            "Type": "RUN_COMMAND",
            "Targets": [
                {
                    "Key": "InstanceIds",
                    "Values": [
                        "i-0471e04240EXAMPLE"
                    ]
                }
            ],
            "TaskParameters": {},
            "Priority": 1,
            "ServiceRoleArn": "arn:aws:iam::111122223333:role/MyMaintenanceWindowServiceRole",
            "MaxConcurrency": "1",
            "MaxErrors": "1",
            "Name": "My-Run-Command-Task",
            "Description": "My Run Command task to update SSM Agent on an instance"
        }
    ]
}
```

## Examples for 'describe-maintenance-windows-for-target'
<a name="mw-cli-tutorials-describe-maintenance-windows-for-target"></a>

**List information about the maintenance window targets or tasks associated with a specific node**  
Run the following command.

------
#### [ Linux & macOS ]

```
aws ssm describe-maintenance-windows-for-target \
    --resource-type INSTANCE \
    --targets "Key=InstanceIds,Values=i-02573cafcfEXAMPLE" \
    --max-results 10
```

------
#### [ Windows ]

```
aws ssm describe-maintenance-windows-for-target ^
    --resource-type INSTANCE ^
    --targets "Key=InstanceIds,Values=i-02573cafcfEXAMPLE" ^
    --max-results 10
```

------

The system returns information similar to the following.

```
{
    "WindowIdentities": [
        {
            "WindowId": "mw-0c50858d01EXAMPLE",
            "Name": "My-First-Maintenance-Window"
        },
        {
            "WindowId": "mw-9a8b7c6d5eEXAMPLE",
            "Name": "My-Second-Maintenance-Window"
        }
    ]
}
```

## Examples for 'describe-maintenance-window-executions'
<a name="mw-cli-tutorials-describe-maintenance-window-executions"></a>

**List all tasks run before a certain date**  
Run the following command.

------
#### [ Linux & macOS ]

```
aws ssm describe-maintenance-window-executions \
    --window-id "mw-9a8b7c6d5eEXAMPLE" \
    --filters "Key=ExecutedBefore,Values=2019-05-12T05:00:00Z"
```

------
#### [ Windows ]

```
aws ssm describe-maintenance-window-executions ^
    --window-id "mw-9a8b7c6d5eEXAMPLE" ^
    --filters "Key=ExecutedBefore,Values=2019-05-12T05:00:00Z"
```

------

The system returns information similar to the following.

```
{
    "WindowExecutions": [
        {
            "WindowId": "mw-0c50858d01EXAMPLE",
            "WindowExecutionId": "14bea65d-5ccc-462d-a2f3-e99c8EXAMPLE",
            "Status": "FAILED",
            "StatusDetails": "The following SSM parameters are invalid: LevelUp",
            "StartTime": 1557617747.993,
            "EndTime": 1557617748.101
        },
        {
            "WindowId": "mw-9a8b7c6d5eEXAMPLE",
            "WindowExecutionId": "791b72e0-f0da-4021-8b35-f95dfEXAMPLE",
            "Status": "SUCCESS",
            "StartTime": 1557594085.428,
            "EndTime": 1557594090.978
        },
        {
            "WindowId": "mw-0c50858d01EXAMPLE",
            "WindowExecutionId": "ecec60fa-6bb0-4d26-98c7-140308EXAMPLE",
            "Status": "SUCCESS",
            "StartTime": 1557593793.483,
            "EndTime": 1557593798.978
        }
    ]
}
```

**List all tasks run after a certain date**  
Run the following command.

------
#### [ Linux & macOS ]

```
aws ssm describe-maintenance-window-executions \
    --window-id "mw-9a8b7c6d5eEXAMPLE" \
    --filters "Key=ExecutedAfter,Values=2018-12-31T17:00:00Z"
```

------
#### [ Windows ]

```
aws ssm describe-maintenance-window-executions ^
    --window-id "mw-9a8b7c6d5eEXAMPLE" ^
    --filters "Key=ExecutedAfter,Values=2018-12-31T17:00:00Z"
```

------

The system returns information similar to the following.

```
{
    "WindowExecutions": [
        {
            "WindowId": "mw-0c50858d01EXAMPLE",
            "WindowExecutionId": "14bea65d-5ccc-462d-a2f3-e99c8EXAMPLE",
            "Status": "FAILED",
            "StatusDetails": "The following SSM parameters are invalid: LevelUp",
            "StartTime": 1557617747.993,
            "EndTime": 1557617748.101
        },
        {
            "WindowId": "mw-9a8b7c6d5eEXAMPLE",
            "WindowExecutionId": "791b72e0-f0da-4021-8b35-f95dfEXAMPLE",
            "Status": "SUCCESS",
            "StartTime": 1557594085.428,
            "EndTime": 1557594090.978
        },
        {
            "WindowId": "mw-0c50858d01EXAMPLE",
            "WindowExecutionId": "ecec60fa-6bb0-4d26-98c7-140308EXAMPLE",
            "Status": "SUCCESS",
            "StartTime": 1557593793.483,
            "EndTime": 1557593798.978
        }
    ]
}
```

## Examples for 'describe-maintenance-window-schedule'
<a name="mw-cli-tutorials-describe-maintenance-window-schedule"></a>

**Display the next ten scheduled maintenance window runs for a particular node**  
Run the following command.

------
#### [ Linux & macOS ]

```
aws ssm describe-maintenance-window-schedule \
    --resource-type INSTANCE \
    --targets "Key=InstanceIds,Values=i-07782c72faEXAMPLE" \
    --max-results 10
```

------
#### [ Windows ]

```
aws ssm describe-maintenance-window-schedule ^
    --resource-type INSTANCE ^
    --targets "Key=InstanceIds,Values=i-07782c72faEXAMPLE" ^
    --max-results 10
```

------

The system returns information similar to the following.

```
{
    "ScheduledWindowExecutions": [
        {
            "WindowId": "mw-0c50858d01EXAMPLE",
            "Name": "My-First-Maintenance-Window",
            "ExecutionTime": "2019-05-18T23:35:24.902Z"
        },
        {
            "WindowId": "mw-0c50858d01EXAMPLE",
            "Name": "My-First-Maintenance-Window",
            "ExecutionTime": "2019-05-25T23:35:24.902Z"
        },
        {
            "WindowId": "mw-0c50858d01EXAMPLE",
            "Name": "My-First-Maintenance-Window",
            "ExecutionTime": "2019-06-01T23:35:24.902Z"
        },
        {
            "WindowId": "mw-0c50858d01EXAMPLE",
            "Name": "My-First-Maintenance-Window",
            "ExecutionTime": "2019-06-08T23:35:24.902Z"
        },
        {
            "WindowId": "mw-9a8b7c6d5eEXAMPLE",
            "Name": "My-Second-Maintenance-Window",
            "ExecutionTime": "2019-06-15T23:35:24.902Z"
        },
        {
            "WindowId": "mw-0c50858d01EXAMPLE",
            "Name": "My-First-Maintenance-Window",
            "ExecutionTime": "2019-06-22T23:35:24.902Z"
        },
        {
            "WindowId": "mw-9a8b7c6d5eEXAMPLE",
            "Name": "My-Second-Maintenance-Window",
            "ExecutionTime": "2019-06-29T23:35:24.902Z"
        },
        {
            "WindowId": "mw-0c50858d01EXAMPLE",
            "Name": "My-First-Maintenance-Window",
            "ExecutionTime": "2019-07-06T23:35:24.902Z"
        },
        {
            "WindowId": "mw-9a8b7c6d5eEXAMPLE",
            "Name": "My-Second-Maintenance-Window",
            "ExecutionTime": "2019-07-13T23:35:24.902Z"
        },
        {
            "WindowId": "mw-0c50858d01EXAMPLE",
            "Name": "My-First-Maintenance-Window",
            "ExecutionTime": "2019-07-20T23:35:24.902Z"
        }
    ],
    "NextToken": "AAEABUXdceT92FvtKld/dGHELj5Mi+GKW/EXAMPLE"
}
```

**Display the maintenance window schedule for nodes tagged with a certain key-value pair**  
Run the following command.

------
#### [ Linux & macOS ]

```
aws ssm describe-maintenance-window-schedule \
    --resource-type INSTANCE \
    --targets "Key=tag:prod,Values=rhel7"
```

------
#### [ Windows ]

```
aws ssm describe-maintenance-window-schedule ^
    --resource-type INSTANCE ^
    --targets "Key=tag:prod,Values=rhel7"
```

------

The system returns information similar to the following.

```
{
    "ScheduledWindowExecutions": [
        {
            "WindowId": "mw-0c50858d01EXAMPLE",
            "Name": "DemoRateStartDate",
            "ExecutionTime": "2019-10-20T05:34:56-07:00"
        },
        {
            "WindowId": "mw-0c50858d01EXAMPLE",
            "Name": "DemoRateStartDate",
            "ExecutionTime": "2019-10-21T05:34:56-07:00"
        },
        {
            "WindowId": "mw-0c50858d01EXAMPLE",
            "Name": "DemoRateStartDate",
            "ExecutionTime": "2019-10-22T05:34:56-07:00"
        },
        {
            "WindowId": "mw-0c50858d01EXAMPLE",
            "Name": "DemoRateStartDate",
            "ExecutionTime": "2019-10-23T05:34:56-07:00"
        },
        {
            "WindowId": "mw-0c50858d01EXAMPLE",
            "Name": "DemoRateStartDate",
            "ExecutionTime": "2019-10-24T05:34:56-07:00"
        }
    ],
    "NextToken": "AAEABccwSXqQRGKiTZ1yzGELR6cxW4W/EXAMPLE"
}
```

**Display start times for next four runs of a maintenance window**  
Run the following command.

------
#### [ Linux & macOS ]

```
aws ssm describe-maintenance-window-schedule \
    --window-id "mw-0c50858d01EXAMPLE" \
    --max-results "4"
```

------
#### [ Windows ]

```
aws ssm describe-maintenance-window-schedule ^
    --window-id "mw-0c50858d01EXAMPLE" ^
    --max-results "4"
```

------

The system returns information similar to the following.

```
{
    "WindowSchedule": [
        {
            "ScheduledWindowExecutions": [
                {
                    "ExecutionTime": "2019-10-04T10:10:10Z",
                    "Name": "My-First-Maintenance-Window",
                    "WindowId": "mw-0c50858d01EXAMPLE"
                },
                {
                    "ExecutionTime": "2019-10-11T10:10:10Z",
                    "Name": "My-First-Maintenance-Window",
                    "WindowId": "mw-0c50858d01EXAMPLE"
                },
                {
                    "ExecutionTime": "2019-10-18T10:10:10Z",
                    "Name": "My-First-Maintenance-Window",
                    "WindowId": "mw-0c50858d01EXAMPLE"
                },
                {
                    "ExecutionTime": "2019-10-25T10:10:10Z",
                    "Name": "My-First-Maintenance-Window",
                    "WindowId": "mw-0c50858d01EXAMPLE"
                }
            ]
        }
    ]
}
```

# Tutorial: View information about tasks and task executions using the AWS CLI
<a name="mw-cli-tutorial-task-info"></a>

This tutorial demonstrates how to use the AWS Command Line Interface (AWS CLI) to view details about your completed maintenance window tasks. 

If you're continuing directly from [Tutorial: Create and configure a maintenance window using the AWS CLI](maintenance-windows-cli-tutorials-create.md), make sure you have allowed enough time for your maintenance window to run at least once in order to see its execution results.

As you follow the steps in this tutorial, replace the values in italicized *red* text with your own options and IDs. For example, replace the maintenance window ID *mw-0c50858d01EXAMPLE* and the instance ID *i-02573cafcfEXAMPLE* with IDs of resources you create.

**To view information about tasks and task executions using the AWS CLI**

1. Run the following command to view a list of task executions for a specific maintenance window.

------
#### [ Linux & macOS ]

   ```
   aws ssm describe-maintenance-window-executions \
       --window-id "mw-0c50858d01EXAMPLE"
   ```

------
#### [ Windows ]

   ```
   aws ssm describe-maintenance-window-executions ^
       --window-id "mw-0c50858d01EXAMPLE"
   ```

------

   The system returns information similar to the following.

   ```
   {
       "WindowExecutions": [
           {
               "WindowId": "mw-0c50858d01EXAMPLE",
               "WindowExecutionId": "14bea65d-5ccc-462d-a2f3-e99c8EXAMPLE",
               "Status": "SUCCESS",
               "StartTime": 1557593793.483,
               "EndTime": 1557593798.978
           },
           {
               "WindowId": "mw-0c50858d01EXAMPLE",
               "WindowExecutionId": "791b72e0-f0da-4021-8b35-f95dfEXAMPLE",
               "Status": "SUCCESS",
               "StartTime": 1557593493.096,
               "EndTime": 1557593498.611
           },
           {
               "WindowId": "mw-0c50858d01EXAMPLE",
               "WindowExecutionId": "ecec60fa-6bb0-4d26-98c7-140308EXAMPLE",
               "Status": "SUCCESS",
               "StatusDetails": "No tasks to execute.",
               "StartTime": 1557593193.309,
               "EndTime": 1557593193.334
           }
       ]
   }
   ```

1. Run the following command to get information about a maintenance window task execution.

------
#### [ Linux & macOS ]

   ```
   aws ssm get-maintenance-window-execution \
       --window-execution-id "14bea65d-5ccc-462d-a2f3-e99c8EXAMPLE"
   ```

------
#### [ Windows ]

   ```
   aws ssm get-maintenance-window-execution ^
       --window-execution-id "14bea65d-5ccc-462d-a2f3-e99c8EXAMPLE"
   ```

------

   The system returns information similar to the following.

   ```
   {
       "WindowExecutionId": "14bea65d-5ccc-462d-a2f3-e99c8EXAMPLE",
       "TaskIds": [
           "c9b05aba-197f-4d8d-be34-e73fbEXAMPLE"
       ],
       "Status": "SUCCESS",
       "StartTime": 1557593493.096,
       "EndTime": 1557593498.611
   }
   ```

1. Run the following command to list the tasks run as part of a maintenance window execution.

------
#### [ Linux & macOS ]

   ```
   aws ssm describe-maintenance-window-execution-tasks \
       --window-execution-id "14bea65d-5ccc-462d-a2f3-e99c8EXAMPLE"
   ```

------
#### [ Windows ]

   ```
   aws ssm describe-maintenance-window-execution-tasks ^
       --window-execution-id "14bea65d-5ccc-462d-a2f3-e99c8EXAMPLE"
   ```

------

   The system returns information similar to the following.

   ```
   {
       "WindowExecutionTaskIdentities": [
           {
               "WindowExecutionId": "14bea65d-5ccc-462d-a2f3-e99c8EXAMPLE",
               "TaskExecutionId": "c9b05aba-197f-4d8d-be34-e73fbEXAMPLE",
               "Status": "SUCCESS",
               "StartTime": 1557593493.162,
               "EndTime": 1557593498.57,
               "TaskArn": "AWS-RunShellScript",
               "TaskType": "RUN_COMMAND"
           }
       ]
   }
   ```

1. Run the following command to get the details of a task execution.

------
#### [ Linux & macOS ]

   ```
   aws ssm get-maintenance-window-execution-task \
       --window-execution-id "14bea65d-5ccc-462d-a2f3-e99c8EXAMPLE" \
       --task-id "c9b05aba-197f-4d8d-be34-e73fbEXAMPLE"
   ```

------
#### [ Windows ]

   ```
   aws ssm get-maintenance-window-execution-task ^
       --window-execution-id "14bea65d-5ccc-462d-a2f3-e99c8EXAMPLE" ^
       --task-id "c9b05aba-197f-4d8d-be34-e73fbEXAMPLE"
   ```

------

   The system returns information similar to the following.

   ```
   {
       "WindowExecutionId": "14bea65d-5ccc-462d-a2f3-e99c8EXAMPLE",
       "TaskExecutionId": "c9b05aba-197f-4d8d-be34-e73fbEXAMPLE",
       "TaskArn": "AWS-RunShellScript",
       "ServiceRole": "arn:aws:iam::111122223333:role/MyMaintenanceWindowServiceRole",
       "Type": "RUN_COMMAND",
       "TaskParameters": [
           {
               "aws:InstanceId": {
                   "Values": [
                       "i-02573cafcfEXAMPLE"
                   ]
               },
               "commands": {
                   "Values": [
                       "df"
                   ]
               }
           }
       ],
       "Priority": 10,
       "MaxConcurrency": "1",
       "MaxErrors": "1",
       "Status": "SUCCESS",
       "StartTime": 1557593493.162,
       "EndTime": 1557593498.57
   }
   ```

1. Run the following command to get the specific task invocations performed for a task execution.

------
#### [ Linux & macOS ]

   ```
   aws ssm describe-maintenance-window-execution-task-invocations \
       --window-execution-id "14bea65d-5ccc-462d-a2f3-e99c8EXAMPLE" \
       --task-id "c9b05aba-197f-4d8d-be34-e73fbEXAMPLE"
   ```

------
#### [ Windows ]

   ```
   aws ssm describe-maintenance-window-execution-task-invocations ^
       --window-execution-id "14bea65d-5ccc-462d-a2f3-e99c8EXAMPLE" ^
       --task-id "c9b05aba-197f-4d8d-be34-e73fbEXAMPLE"
   ```

------

   The system returns information similar to the following.

   ```
   {
       "WindowExecutionTaskInvocationIdentities": [
           {
               "WindowExecutionId": "14bea65d-5ccc-462d-a2f3-e99c8EXAMPLE",
               "TaskExecutionId": "c9b05aba-197f-4d8d-be34-e73fbEXAMPLE",
               "InvocationId": "c336d2ab-09de-44ba-8f6a-6136cEXAMPLE",
               "ExecutionId": "76a5a04f-caf6-490c-b448-92c02EXAMPLE",
               "TaskType": "RUN_COMMAND",
               "Parameters": "{\"documentName\":\"AWS-RunShellScript\",\"instanceIds\":[\"i-02573cafcfEXAMPLE\"],\"maxConcurrency\":\"1\",\"maxErrors\":\"1\",\"parameters\":{\"commands\":[\"df\"]}}",
               "Status": "SUCCESS",
               "StatusDetails": "Success",
               "StartTime": 1557593493.222,
               "EndTime": 1557593498.466
           }
       ]
   }
   ```

# Tutorial: Update a maintenance window using the AWS CLI
<a name="maintenance-windows-cli-tutorials-update"></a>

This tutorial demonstrates how to use the AWS Command Line Interface (AWS CLI) to update a maintenance window. It also shows you how to update different task types, including those for AWS Systems Manager Run Command and Automation, AWS Lambda, and AWS Step Functions. 

The examples in this section use the following Systems Manager actions for updating a maintenance window:
+ [UpdateMaintenanceWindow](https://docs.aws.amazon.com/systems-manager/latest/APIReference/API_UpdateMaintenanceWindow.html)
+ [UpdateMaintenanceWindowTarget](https://docs.aws.amazon.com/systems-manager/latest/APIReference/API_UpdateMaintenanceWindowTarget.html)
+ [UpdateMaintenanceWindowTask](https://docs.aws.amazon.com/systems-manager/latest/APIReference/API_UpdateMaintenanceWindowTask.html)
+ [DeregisterTargetFromMaintenanceWindow](https://docs.aws.amazon.com/systems-manager/latest/APIReference/API_DeregisterTargetFromMaintenanceWindow.html)

For information about using the Systems Manager console to update a maintenance window, see [Update or delete maintenance window resources using the console](sysman-maintenance-update.md). 

As you follow the steps in this tutorial, replace the values in italicized *red* text with your own options and IDs. For example, replace the maintenance window ID *mw-0c50858d01EXAMPLE* and the instance ID *i-02573cafcfEXAMPLE* with IDs of resources you create.

**To update a maintenance window using the AWS CLI**

1. Open the AWS CLI and run the following command to update a target to include a name and a description.

------
#### [ Linux & macOS ]

   ```
   aws ssm update-maintenance-window-target \
       --window-id "mw-0c50858d01EXAMPLE" \
       --window-target-id "e32eecb2-646c-4f4b-8ed1-205fbEXAMPLE" \
       --name "My-Maintenance-Window-Target" \
       --description "Description for my maintenance window target"
   ```

------
#### [ Windows ]

   ```
   aws ssm update-maintenance-window-target ^
       --window-id "mw-0c50858d01EXAMPLE" ^
       --window-target-id "e32eecb2-646c-4f4b-8ed1-205fbEXAMPLE" ^
       --name "My-Maintenance-Window-Target" ^
       --description "Description for my maintenance window target"
   ```

------

   The system returns information similar to the following.

   ```
   {
       "WindowId": "mw-0c50858d01EXAMPLE",
       "WindowTargetId": "e32eecb2-646c-4f4b-8ed1-205fbEXAMPLE",
       "Targets": [
           {
               "Key": "InstanceIds",
               "Values": [
                   "i-02573cafcfEXAMPLE"
               ]
           }
       ],
       "Name": "My-Maintenance-Window-Target",
       "Description": "Description for my maintenance window target"
   }
   ```

1. Run the following command to use the `replace` option to remove the description field and add an additional target. The description field is removed, because the update doesn't include the field (a null value). Be sure to specify an additional node that has been configured for use with Systems Manager.

------
#### [ Linux & macOS ]

   ```
   aws ssm update-maintenance-window-target \
       --window-id "mw-0c50858d01EXAMPLE" \
       --window-target-id "d208dedf-3f6b-41ff-ace8-8e751EXAMPLE" \
       --targets "Key=InstanceIds,Values=i-02573cafcfEXAMPLE,i-0471e04240EXAMPLE" \
       --name "My-Maintenance-Window-Target" \
       --replace
   ```

------
#### [ Windows ]

   ```
   aws ssm update-maintenance-window-target ^
       --window-id "mw-0c50858d01EXAMPLE" ^
       --window-target-id "d208dedf-3f6b-41ff-ace8-8e751EXAMPLE" ^
       --targets "Key=InstanceIds,Values=i-02573cafcfEXAMPLE,i-0471e04240EXAMPLE" ^
       --name "My-Maintenance-Window-Target" ^
       --replace
   ```

------

   The system returns information similar to the following.

   ```
   {
       "WindowId": "mw-0c50858d01EXAMPLE",
       "WindowTargetId": "e32eecb2-646c-4f4b-8ed1-205fbEXAMPLE",
       "Targets": [
           {
               "Key": "InstanceIds",
               "Values": [
                   "i-02573cafcfEXAMPLE",
                   "i-0471e04240EXAMPLE"
               ]
           }
       ],
       "Name": "My-Maintenance-Window-Target"
   }
   ```

1. The `start-date` option allows you to delay activation of a maintenance window until a specified future date. The `end-date` option allows you to set a date and time in the future after which the maintenance window no longer runs. Specify the options in ISO-8601 Extended format.

   Run the following command to specify a date and time range for regularly scheduled maintenance window executions.

------
#### [ Linux & macOS ]

   ```
   aws ssm update-maintenance-window \
       --window-id "mw-0c50858d01EXAMPLE" \
       --start-date "2020-10-01T10:10:10Z" \
       --end-date "2020-11-01T10:10:10Z"
   ```

------
#### [ Windows ]

   ```
   aws ssm update-maintenance-window ^
       --window-id "mw-0c50858d01EXAMPLE" ^
       --start-date "2020-10-01T10:10:10Z" ^
       --end-date "2020-11-01T10:10:10Z"
   ```

------

1. Run the following command to update a Run Command task.
**Tip**  
If your target is an Amazon Elastic Compute Cloud (Amazon EC2) instance for Windows Server, change `df` to `ipconfig`, and `AWS-RunShellScript` to `AWS-RunPowerShellScript` in the following command.

------
#### [ Linux & macOS ]

   ```
   aws ssm update-maintenance-window-task \
       --window-id "mw-0c50858d01EXAMPLE" \
       --window-task-id "4f7ca192-7e9a-40fe-9192-5cb15EXAMPLE" \
       --targets "Key=WindowTargetIds,Values=e32eecb2-646c-4f4b-8ed1-205fbEXAMPLE" \
       --task-arn "AWS-RunShellScript" \
       --service-role-arn "arn:aws:iam::account-id:role/MaintenanceWindowsRole" \
       --task-invocation-parameters "RunCommand={Comment=Revising my Run Command task,Parameters={commands=df}}" \
       --priority 1 --max-concurrency 10 --max-errors 4 \
       --name "My-Task-Name" --description "A description for my Run Command task"
   ```

------
#### [ Windows ]

   ```
   aws ssm update-maintenance-window-task ^
       --window-id "mw-0c50858d01EXAMPLE" ^
       --window-task-id "4f7ca192-7e9a-40fe-9192-5cb15EXAMPLE" ^
       --targets "Key=WindowTargetIds,Values=e32eecb2-646c-4f4b-8ed1-205fbEXAMPLE" ^
       --task-arn "AWS-RunShellScript" ^
       --service-role-arn "arn:aws:iam::account-id:role/MaintenanceWindowsRole" ^
       --task-invocation-parameters "RunCommand={Comment=Revising my Run Command task,Parameters={commands=df}}" ^
       --priority 1 --max-concurrency 10 --max-errors 4 ^
       --name "My-Task-Name" --description "A description for my Run Command task"
   ```

------

   The system returns information similar to the following.

   ```
   {
       "WindowId": "mw-0c50858d01EXAMPLE",
       "WindowTaskId": "4f7ca192-7e9a-40fe-9192-5cb15EXAMPLE",
       "Targets": [
           {
               "Key": "WindowTargetIds",
               "Values": [
                   "e32eecb2-646c-4f4b-8ed1-205fbEXAMPLE"
               ]
           }
       ],
       "TaskArn": "AWS-RunShellScript",
       "ServiceRoleArn": "arn:aws:iam::111122223333:role/MaintenanceWindowsRole",
       "TaskParameters": {},
       "TaskInvocationParameters": {
           "RunCommand": {
               "Comment": "Revising my Run Command task",
               "Parameters": {
                   "commands": [
                       "df"
                   ]
               }
           }
       },
       "Priority": 1,
       "MaxConcurrency": "10",
       "MaxErrors": "4",
       "Name": "My-Task-Name",
       "Description": "A description for my Run Command task"
   }
   ```

1. Adapt and run the following command to update a Lambda task.

------
#### [ Linux & macOS ]

   ```
   aws ssm update-maintenance-window-task \
       --window-id mw-0c50858d01EXAMPLE \
       --window-task-id 4f7ca192-7e9a-40fe-9192-5cb15EXAMPLE \
       --targets "Key=WindowTargetIds,Values=e32eecb2-646c-4f4b-8ed1-205fbEXAMPLE" \
       --task-arn "arn:aws:lambda:region:111122223333:function:SSMTestLambda" \
       --service-role-arn "arn:aws:iam:account-id:role/MaintenanceWindowsRole" \
       --task-invocation-parameters '{"Lambda":{"Payload":"{\"InstanceId\":\"{{RESOURCE_ID}}\",\"targetType\":\"{{TARGET_TYPE}}\"}"}}' \
       --priority 1 --max-concurrency 10 --max-errors 5 \
       --name "New-Lambda-Task-Name" \
       --description "A description for my Lambda task"
   ```

------
#### [ Windows ]

   ```
   aws ssm update-maintenance-window-task ^
       --window-id mw-0c50858d01EXAMPLE ^
       --window-task-id 4f7ca192-7e9a-40fe-9192-5cb15EXAMPLE ^
       --targets "Key=WindowTargetIds,Values=e32eecb2-646c-4f4b-8ed1-205fbEXAMPLE" ^
       --task-arn --task-arn "arn:aws:lambda:region:111122223333:function:SSMTestLambda" ^
       --service-role-arn "arn:aws:iam:account-id:role/MaintenanceWindowsRole" ^
       --task-invocation-parameters '{"Lambda":{"Payload":"{\"InstanceId\":\"{{RESOURCE_ID}}\",\"targetType\":\"{{TARGET_TYPE}}\"}"}}' ^
       --priority 1 --max-concurrency 10 --max-errors 5 ^
       --name "New-Lambda-Task-Name" ^
       --description "A description for my Lambda task"
   ```

------

   The system returns information similar to the following.

   ```
   {
       "WindowId": "mw-0c50858d01EXAMPLE",
       "WindowTaskId": "4f7ca192-7e9a-40fe-9192-5cb15EXAMPLE",
       "Targets": [
           {
               "Key": "WindowTargetIds",
               "Values": "e32eecb2-646c-4f4b-8ed1-205fbEXAMPLE"
           }
       ],
       "TaskArn": "arn:aws:lambda:us-east-2:111122223333:function:SSMTestLambda",
       "ServiceRoleArn": "arn:aws:iam::111122223333:role/MaintenanceWindowsRole",
       "TaskParameters": {},
       "TaskInvocationParameters": {
           "Lambda": {
               "Payload": "e30="
           }
       },
       "Priority": 1,
       "MaxConcurrency": "10",
       "MaxErrors": "5",
       "Name": "New-Lambda-Task-Name",
       "Description": "A description for my Lambda task"
   }
   ```

1. If you're updating a Step Functions task, adapt and run the following command to update its task-invocation-parameters.

------
#### [ Linux & macOS ]

   ```
   aws ssm update-maintenance-window-task \
       --window-id "mw-0c50858d01EXAMPLE" \
       --window-task-id "4f7ca192-7e9a-40fe-9192-5cb15EXAMPLE" \
       --targets "Key=WindowTargetIds,Values=e32eecb2-646c-4f4b-8ed1-205fbEXAMPLE" \
       --task-arn "arn:aws:states:region:execution:SSMStepFunctionTest" \
       --service-role-arn "arn:aws:iam:account-id:role/MaintenanceWindowsRole" \
       --task-invocation-parameters '{"StepFunctions":{"Input":"{\"InstanceId\":\"{{RESOURCE_ID}}\"}"}}' \
       --priority 0 --max-concurrency 10 --max-errors 5 \
       --name "My-Step-Functions-Task" \
       --description "A description for my Step Functions task"
   ```

------
#### [ Windows ]

   ```
   aws ssm update-maintenance-window-task ^
       --window-id "mw-0c50858d01EXAMPLE" ^
       --window-task-id "4f7ca192-7e9a-40fe-9192-5cb15EXAMPLE" ^
       --targets "Key=WindowTargetIds,Values=e32eecb2-646c-4f4b-8ed1-205fbEXAMPLE" ^
       --task-arn "arn:aws:states:region:execution:SSMStepFunctionTest" ^
       --service-role-arn "arn:aws:iam:account-id:role/MaintenanceWindowsRole" ^
       --task-invocation-parameters '{"StepFunctions":{"Input":"{\"InstanceId\":\"{{RESOURCE_ID}}\"}"}}' ^
       --priority 0 --max-concurrency 10 --max-errors 5 ^
       --name "My-Step-Functions-Task" ^
       --description "A description for my Step Functions task"
   ```

------

   The system returns information similar to the following.

   ```
   {
       "WindowId": "mw-0c50858d01EXAMPLE",
       "WindowTaskId": "4f7ca192-7e9a-40fe-9192-5cb15EXAMPLE",
       "Targets": [
           {
               "Key": "WindowTargetIds",
               "Values": [
                   "e32eecb2-646c-4f4b-8ed1-205fbEXAMPLE"
               ]
           }
       ],
       "TaskArn": "arn:aws:states:us-east-2:111122223333:execution:SSMStepFunctionTest",
       "ServiceRoleArn": "arn:aws:iam::111122223333:role/MaintenanceWindowsRole",
       "TaskParameters": {},
       "TaskInvocationParameters": {
           "StepFunctions": {
               "Input": "{\"instanceId\":\"{{RESOURCE_ID}}\"}"
           }
       },
       "Priority": 0,
       "MaxConcurrency": "10",
       "MaxErrors": "5",
       "Name": "My-Step-Functions-Task",
       "Description": "A description for my Step Functions task"
   }
   ```

1. Run the following command to unregister a target from a maintenance window. This example uses the `safe` parameter to determine if the target is referenced by any tasks and therefore safe to unregister.

------
#### [ Linux & macOS ]

   ```
   aws ssm deregister-target-from-maintenance-window \
       --window-id "mw-0c50858d01EXAMPLE" \
       --window-target-id "e32eecb2-646c-4f4b-8ed1-205fbEXAMPLE" \
       --safe
   ```

------
#### [ Windows ]

   ```
   aws ssm deregister-target-from-maintenance-window ^
       --window-id "mw-0c50858d01EXAMPLE" ^
       --window-target-id "e32eecb2-646c-4f4b-8ed1-205fbEXAMPLE" ^
       --safe
   ```

------

   The system returns information similar to the following.

   ```
   An error occurred (TargetInUseException) when calling the DeregisterTargetFromMaintenanceWindow operation: 
   This Target cannot be deregistered because it is still referenced in Task: 4f7ca192-7e9a-40fe-9192-5cb15EXAMPLE
   ```

1. Run the following command to unregister a target from a maintenance window even if the target is referenced by a task. You can force the unregister operation by using the `no-safe` parameter.

------
#### [ Linux & macOS ]

   ```
   aws ssm deregister-target-from-maintenance-window \
       --window-id "mw-0c50858d01EXAMPLE" \
       --window-target-id "e32eecb2-646c-4f4b-8ed1-205fbEXAMPLE" \
       --no-safe
   ```

------
#### [ Windows ]

   ```
   aws ssm deregister-target-from-maintenance-window ^
       --window-id "mw-0c50858d01EXAMPLE" ^
       --window-target-id "e32eecb2-646c-4f4b-8ed1-205fbEXAMPLE" ^
       --no-safe
   ```

------

   The system returns information similar to the following.

   ```
   {
       "WindowId": "mw-0c50858d01EXAMPLE",
       "WindowTargetId": "e32eecb2-646c-4f4b-8ed1-205fbEXAMPLE"
   }
   ```

1. Run the following command to update a Run Command task. This example uses a Systems Manager Parameter Store parameter called `UpdateLevel`, which is formatted as follows: '`{{ssm:UpdateLevel}}`'

------
#### [ Linux & macOS ]

   ```
   aws ssm update-maintenance-window-task \
       --window-id "mw-0c50858d01EXAMPLE" \
       --window-task-id "4f7ca192-7e9a-40fe-9192-5cb15EXAMPLE" \
       --targets "Key=InstanceIds,Values=i-02573cafcfEXAMPLE"  \
       --task-invocation-parameters "RunCommand={Comment=A comment for my task update,Parameters={UpdateLevel='{{ssm:UpdateLevel}}'}}"
   ```

------
#### [ Windows ]

   ```
   aws ssm update-maintenance-window-task ^
       --window-id "mw-0c50858d01EXAMPLE" ^
       --window-task-id "4f7ca192-7e9a-40fe-9192-5cb15EXAMPLE" ^
       --targets "Key=InstanceIds,Values=i-02573cafcfEXAMPLE"  ^
       --task-invocation-parameters "RunCommand={Comment=A comment for my task update,Parameters={UpdateLevel='{{ssm:UpdateLevel}}'}}"
   ```

------

   The system returns information similar to the following.

   ```
   {
       "WindowId": "mw-0c50858d01EXAMPLE",
       "WindowTaskId": "4f7ca192-7e9a-40fe-9192-5cb15EXAMPLE",
       "Targets": [
           {
               "Key": "InstanceIds",
               "Values": [
                   "i-02573cafcfEXAMPLE"
               ]
           }
       ],
       "TaskArn": "AWS-RunShellScript",
       "ServiceRoleArn": "arn:aws:iam::111122223333:role/MyMaintenanceWindowServiceRole",
       "TaskParameters": {},
       "TaskInvocationParameters": {
           "RunCommand": {
               "Comment": "A comment for my task update",
               "Parameters": {
                   "UpdateLevel": [
                       "{{ssm:UpdateLevel}}"
                   ]
               }
           }
       },
       "Priority": 10,
       "MaxConcurrency": "1",
       "MaxErrors": "1"
   }
   ```

1. Run the following command to update an Automation task to specify `WINDOW_ID` and `WINDOW_TASK_ID` parameters for the `task-invocation-parameters` parameter:

------
#### [ Linux & macOS ]

   ```
   aws ssm update-maintenance-window-task \
       --window-id "mw-0c50858d01EXAMPLE" \
       --window-task-id "4f7ca192-7e9a-40fe-9192-5cb15EXAMPLE" \
       --targets "Key=WindowTargetIds,Values=e32eecb2-646c-4f4b-8ed1-205fbEXAMPLE \
       --task-arn "AutoTestDoc" \
       --service-role-arn "arn:aws:iam:account-id:role/MyMaintenanceWindowServiceRole \
       --task-invocation-parameters "Automation={Parameters={InstanceId='{{RESOURCE_ID}}',initiator='{{WINDOW_ID}}.Task-{{WINDOW_TASK_ID}}'}}" \
       --priority 3 --max-concurrency 10 --max-errors 5
   ```

------
#### [ Windows ]

   ```
   aws ssm update-maintenance-window-task ^
       --window-id "mw-0c50858d01EXAMPLE" ^
       --window-task-id "4f7ca192-7e9a-40fe-9192-5cb15EXAMPLE" ^
       --targets "Key=WindowTargetIds,Values=e32eecb2-646c-4f4b-8ed1-205fbEXAMPLE ^
       --task-arn "AutoTestDoc" ^
       --service-role-arn "arn:aws:iam:account-id:role/MyMaintenanceWindowServiceRole ^
       --task-invocation-parameters "Automation={Parameters={InstanceId='{{RESOURCE_ID}}',initiator='{{WINDOW_ID}}.Task-{{WINDOW_TASK_ID}}'}}" ^
       --priority 3 --max-concurrency 10 --max-errors 5
   ```

------

   The system returns information similar to the following.

   ```
   {
       "WindowId": "mw-0c50858d01EXAMPLE",
       "WindowTaskId": "4f7ca192-7e9a-40fe-9192-5cb15EXAMPLE",
       "Targets": [
           {
               "Key": "WindowTargetIds",
               "Values": [
                   "e32eecb2-646c-4f4b-8ed1-205fbEXAMPLE"
               ]
           }
       ],
       "TaskArn": "AutoTestDoc",
       "ServiceRoleArn": "arn:aws:iam::111122223333:role/MyMaintenanceWindowServiceRole",
       "TaskParameters": {},
       "TaskInvocationParameters": {
           "Automation": {
               "Parameters": {
                   "multi": [
                       "{{WINDOW_TASK_ID}}"
                   ],
                   "single": [
                       "{{WINDOW_ID}}"
                   ]
               }
           }
       },
       "Priority": 0,
       "MaxConcurrency": "10",
       "MaxErrors": "5",
       "Name": "My-Automation-Task",
       "Description": "A description for my Automation task"
   }
   ```

# Tutorial: Delete a maintenance window using the AWS CLI
<a name="mw-cli-tutorial-delete-mw"></a>

To delete a maintenance window you created in these tutorials, run the following command.

```
aws ssm delete-maintenance-window --window-id "mw-0c50858d01EXAMPLE"
```

The system returns information similar to the following.

```
{
   "WindowId":"mw-0c50858d01EXAMPLE"
}
```

# Tutorial: Create a maintenance window for patching using the console
<a name="maintenance-window-tutorial-patching"></a>

**Important**  
You can continue to use this legacy topic to create a maintenance window for patching. However, we recommend that you use a patch policy instead. For more information, see [Patch policy configurations in Quick Setup](patch-manager-policies.md) and [Configure patching for instances in an organization using a Quick Setup patch policy](quick-setup-patch-manager.md). 

To minimize the impact on your server availability, we recommend that you configure a maintenance window to run patching during times that won't interrupt your business operations.

You must configure roles and permissions for Maintenance Windows, a tool in AWS Systems Manager, before beginning this procedure. For more information, see [Setting up Maintenance Windows](setting-up-maintenance-windows.md). 

**To create a maintenance window for patching**

1. Open the AWS Systems Manager console at [https://console.aws.amazon.com/systems-manager/](https://console.aws.amazon.com/systems-manager/).

1. In the navigation pane, choose **Maintenance Windows**.

1. Choose **Create maintenance window**.

1. For **Name**, enter a name that designates this as a maintenance window for patching critical and important updates.

1. (Optional) For **Description**, enter a description. 

1. Choose **Allow unregistered targets** if you want to allow a maintenance window task to run on managed nodes, even if you haven't registered those nodes as targets.

   If you choose this option, then you can choose the unregistered nodes (by node ID) when you register a task with the maintenance window.

   If you don't choose this option, then you must choose previously-registered targets when you register a task with the maintenance window. 

1. In the top of the **Schedule** section, specify a schedule for the maintenance window by using one of the three scheduling options.

   For information about building cron/rate expressions, see [Reference: Cron and rate expressions for Systems Manager](reference-cron-and-rate-expressions.md).

1. For **Duration**, enter the number of hours the maintenance window will run. The value you specify determines the specific end time for the maintenance window based on the time it begins. No maintenance window tasks are permitted to start after the resulting endtime minus the number of hours you specify for **Stop initiating tasks** in the next step. 

   For example, if the maintenance window starts at 3 PM, the duration is three hours, and the **Stop initiating tasks** value is one hour, no maintenance window tasks can start after 5 PM. 

1. For **Stop initiating tasks**, enter the number of hours before the end of the maintenance window that the system should stop scheduling new tasks to run. 

1. (Optional) For **Window start date**, specify a date and time, in ISO-8601 Extended format, for when you want the maintenance window to become active. This allows you to delay activation of the maintenance window until the specified future date.

1. (Optional) For **Window end date**, specify a date and time, in ISO-8601 Extended format, for when you want the maintenance window to become inactive. This allows you to set a date and time in the future after which the maintenance window no longer runs.

1. (Optional) For **Schedule timezone**, specify the time zone to base scheduled maintenance window executions on, in Internet Assigned Numbers Authority (IANA) format. For example: "America/Los\$1Angeles", "etc/UTC", or "Asia/Seoul".

   For more information about valid formats, see the [Time Zone Database](https://www.iana.org/time-zones) on the IANA website.

1. (Optional) In the **Manage tags** area, apply one or more tag key name/value pairs to the maintenance window.

   Tags are optional metadata that you assign to a resource. Tags allow you to categorize a resource in different ways, such as by purpose, owner, or environment. For example, you might want to tag this maintenance window to identify the type of tasks it runs. In this case, you could specify the following key name/value pair:
   + `Key=TaskType,Value=Patching`

1. Choose **Create maintenance window**.

1. In the maintenance windows list, choose the maintenance window you just created, and then choose **Actions**, **Register targets**.

1. (Optional) In the **Maintenance window target details** section, provide a name, a description, and owner information (your name or alias) for this target.

1. For **Target selection**, choose **Specify instance tags**.

1. For **Specify instance tags**, enter a tag key and a tag value to identify the nodes to register with the maintenance window, and then choose **Add**.

1. Choose **Register target**. The system creates a maintenance window target.

1. In the details page of the maintenance window you created, choose **Actions**, **Register Run command task**.

1. (Optional) For **Maintenance window task details**, provide a name and description for this task.

1. For **Command document**, choose `AWS-RunPatchBaseline`.

1. For **Task priority**, choose a priority. Zero (`0`) is the highest priority.

1. For **Targets**, under **Target by**, choose the maintenance window target you created earlier in this procedure.

1. For **Rate control**:
   + For **Concurrency**, specify either a number or a percentage of managed nodes on which to run the command at the same time.
**Note**  
If you selected targets by specifying tags applied to managed nodes or by specifying AWS resource groups, and you aren't certain how many managed nodes are targeted, then restrict the number of targets that can run the document at the same time by specifying a percentage.
   + For **Error threshold**, specify when to stop running the command on other managed nodes after it fails on either a number or a percentage of nodes. For example, if you specify three errors, then Systems Manager stops sending the command when the fourth error is received. Managed nodes still processing the command might also send errors.

1. (Optional) For **IAM service role**, choose a role to provide permissions for Systems Manager to assume when running a maintenance window task.

   If you don't specify a service role ARN, Systems Manager uses a service-linked role in your account. If no appropriate service-linked role for Systems Manager exists in your account, it's created when the task is registered successfully.
**Note**  
For an improved security posture, we strongly recommend creating a custom policy and custom service role for running your maintenance window tasks. The policy can be crafted to provide only the permissions needed for your particular maintenance window tasks. For more information, see [Setting up Maintenance Windows](setting-up-maintenance-windows.md).

1. (Optional) For **Output options**, to save the command output to a file, select the **Enable writing output to S3** box. Enter the bucket and prefix (folder) names in the boxes.
**Note**  
The S3 permissions that grant the ability to write the data to an S3 bucket are those of the instance profile assigned to the managed node, not those of the IAM user performing this task. For more information, see [Configure instance permissions required for Systems Manager](setup-instance-permissions.md) or [Create an IAM service role for a hybrid environment](hybrid-multicloud-service-role.md). In addition, if the specified S3 bucket is in a different AWS account, verify that the instance profile or IAM service role associated with the managed node has the necessary permissions to write to that bucket.

   To stream the output to an Amazon CloudWatch Logs log group, select the **CloudWatch output** box. Enter the log group name in the box.

1. In the **SNS notifications** section, if you want notifications sent about the status of the command execution, select the **Enable SNS notifications** check box.

   For more information about configuring Amazon SNS notifications for Run Command, see [Monitoring Systems Manager status changes using Amazon SNS notifications](monitoring-sns-notifications.md).

1. For **Parameters**:
   + For **Operation**, choose **Scan** to scan for missing patches, or choose **Install** to scan for and install missing patches.
   + You don't need to enter anything in the **Snapshot Id** field. This system automatically generates and provides this parameter.
   + You don't need to enter anything in the **Install Override List** field unless you want Patch Manager to use a different patch set than is specified for the patch baseline. For information, see [Parameter name: `InstallOverrideList`](patch-manager-aws-runpatchbaseline.md#patch-manager-aws-runpatchbaseline-parameters-installoverridelist).
   + For **RebootOption**, specify whether you want nodes to reboot if patches are installed during the `Install` operation, or if Patch Manager detects other patches that were installed since the last node reboot. For information, see [Parameter name: `RebootOption`](patch-manager-aws-runpatchbaseline.md#patch-manager-aws-runpatchbaseline-parameters-norebootoption).
   + (Optional) For **Comment**, enter a tracking note or reminder about this command.
   + For **Timeout (seconds)**, enter the number of seconds the system should wait for the operation to finish before it is considered unsuccessful.

1. Choose **Register Run command task**.

After the maintenance window task is complete, you can view patch compliance details in the Systems Manager console in the [Fleet Manager](fleet-manager.md) tool. 

You can also view compliance information in the [Patch Manager](patch-manager.md) tool, on the **Compliance reporting** tab. 

You can also use the [DescribePatchGroupState](https://docs.aws.amazon.com/systems-manager/latest/APIReference/API_DescribePatchGroupState.html) and [DescribeInstancePatchStatesForPatchGroup](https://docs.aws.amazon.com/systems-manager/latest/APIReference/API_DescribeInstancePatchStatesForPatchGroup.html) APIs to view compliance details. For information about patch compliance data, see [About patch compliance](compliance-about.md#compliance-monitor-patch).

# Patching schedules using maintenance windows
<a name="sysman-patch-scheduletasks"></a>

After you configure a patch baseline (and optionally a patch group), you can apply patches to your node by using a maintenance window. A maintenance window can reduce the impact on server availability by letting you specify a time to perform the patching process that doesn't interrupt business operations. A maintenance window works like this:

1. Create a maintenance window with a schedule for your patching operations.

1. Choose the targets for the maintenance window by specifying the `Patch Group` or `PatchGroup` tag for the tag name, and any value for which you have defined Amazon Elastic Compute Cloud (Amazon EC2) tags, for example, "web servers" or "US-EAST-PROD. (You must use `PatchGroup`, without a space, if you have [allowed tags in EC2 instance metadata](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/Using_Tags.html#allow-access-to-tags-in-IMDS).

1. Create a new maintenance window task, and specify the `AWS-RunPatchBaseline` document. 

When you configure the task, you can choose to either scan nodes or scan and install patches on the nodes. If you choose to scan nodes, Patch Manager, a tool in AWS Systems Manager, scans each node and generates a list of missing patches for you to review.

If you choose to scan and install patches, Patch Manager scans each node and compares the list of installed patches against the list of approved patches in the baseline. Patch Manager identifies missing patches, and then downloads and installs all missing and approved patches.

If you want to perform a one-time scan or install to fix an issue, you can use Run Command to call the `AWS-RunPatchBaseline` document directly.

**Important**  
After installing patches, Systems Manager reboots each node. The reboot is required to make sure that patches are installed correctly and to ensure that the system didn't leave the node in a potentially bad state. (Exception: If the `RebootOption` parameter is set to `NoReboot` in the `AWS-RunPatchBaseline` document, the managed node isn't rebooted after Patch Manager runs. For more information, see [Parameter name: `RebootOption`](patch-manager-aws-runpatchbaseline.md#patch-manager-aws-runpatchbaseline-parameters-norebootoption).) 

# Using pseudo parameters when registering maintenance window tasks
<a name="maintenance-window-tasks-pseudo-parameters"></a>

When you register a task in Maintenance Windows, a tool in AWS Systems Manager, you specify the parameters that are unique to each of the four task types. (In CLI commands, these are provided using the `--task-invocation-parameters` option.)

 You can also reference certain values using *pseudo parameter* syntax, such as `{{RESOURCE_ID}}`, `{{TARGET_TYPE}}`, and `{{WINDOW_TARGET_ID}}`. When the maintenance window task runs, it passes the correct values instead of the pseudo parameter placeholders. The full list of pseudo parameters you can use is provided later in this topic in [Supported pseudo parameters](#pseudo-parameters).

**Important**  
For the target type `RESOURCE_GROUP`, depending on the ID format needed for the task, you can choose between using `{{TARGET_ID}}` and `{{RESOURCE_ID}}` to reference the resource when your task runs. `{{TARGET_ID}}` returns the full ARN of the resource. `{{RESOURCE_ID}}` returns only a shorter name or ID of the resource, as shown in these examples.  
`{{TARGET_ID}}` format: `arn:aws:ec2:us-east-1:123456789012:instance/i-02573cafcfEXAMPLE`
`{{RESOURCE_ID}}` format: `i-02573cafcfEXAMPLE`
For target type `INSTANCE`, both the `{{TARGET_ID}}` and `{{RESOURCE_ID}}` parameters yield the instance ID only. For more information, see [Supported pseudo parameters](#pseudo-parameters).  
`{{TARGET_ID}}` and `{{RESOURCE_ID}}` can be used to pass IDs of AWS resources only to Automation, Lambda, and Step Functions tasks. These two pseudo parameters can't be used with Run Command tasks.

## Pseudo parameter examples
<a name="pseudo-parameter-examples"></a>

Suppose that your payload for an AWS Lambda task needs to reference an instance by its ID.

Whether you’re using an `INSTANCE` or a `RESOURCE_GROUP` maintenance window target, this can be achieved by using the `{{RESOURCE_ID}}` pseudo parameter. For example:

```
"TaskArn": "arn:aws:lambda:us-east-2:111122223333:function:SSMTestFunction",
    "TaskType": "LAMBDA",
    "TaskInvocationParameters": {
        "Lambda": {
            "ClientContext": "ew0KICAi--truncated--0KIEXAMPLE",
            "Payload": "{ \"instanceId\": \"{{RESOURCE_ID}}\" }",
            "Qualifier": "$LATEST"
        }
    }
```

If your Lambda task is intended to run against another supported target type in addition to Amazon Elastic Compute Cloud (Amazon EC2) instances, such as an Amazon DynamoDB table, the same syntax can be used, and `{{RESOURCE_ID}}` yields the name of the table only. However, if you require the full ARN of the table, use `{{TARGET_ID}}`, as shown in the following example.

```
"TaskArn": "arn:aws:lambda:us-east-2:111122223333:function:SSMTestFunction",
    "TaskType": "LAMBDA",
    "TaskInvocationParameters": {
        "Lambda": {
            "ClientContext": "ew0KICAi--truncated--0KIEXAMPLE",
            "Payload": "{ \"tableArn\": \"{{TARGET_ID}}\" }",
            "Qualifier": "$LATEST"
        }
    }
```

The same syntax works for targeting instances or other resource types. When multiple resource types have been added to a resource group, the task runs against each of the appropriate resources. 

**Important**  
Not all resource types that might be included in a resource group yield a value for the `{{RESOURCE_ID}}` parameter. For a list of supported resource types, see [Supported pseudo parameters](#pseudo-parameters).

As another example, to run an Automation task that stops your EC2 instances, you specify the `AWS-StopEC2Instance` Systems Manager document (SSM document) as the `TaskArn` value and use the `{{RESOURCE_ID}}` pseudo parameter:

```
"TaskArn": "AWS-StopEC2Instance",
    "TaskType": "AUTOMATION"
    "TaskInvocationParameters": {
        "Automation": {
            "DocumentVersion": "1",
            "Parameters": {
                "instanceId": [
                    "{{RESOURCE_ID}}"
                ]
            }
        }
    }
```

To run an Automation task that copies a snapshot of an Amazon Elastic Block Store (Amazon EBS) volume, you specify the `AWS-CopySnapshot` SSM document as the `TaskArn` value and use the `{{RESOURCE_ID}}` pseudo parameter.

```
"TaskArn": "AWS-CopySnapshot",
    "TaskType": "AUTOMATION"
    "TaskInvocationParameters": {
        "Automation": {
            "DocumentVersion": "1",
            "Parameters": {
                "SourceRegion": "us-east-2",
                "targetType":"RESOURCE_GROUP",
                "SnapshotId": [
                    "{{RESOURCE_ID}}"
                ]
            }
        }
    }
```

## Supported pseudo parameters
<a name="pseudo-parameters"></a>

The following list describes the pseudo parameters that you can specify using the `{{PSEUDO_PARAMETER}}` syntax in the `--task-invocation-parameters` option.
+ **`WINDOW_ID`**: The ID of the target maintenance window.
+ **`WINDOW_TASK_ID`**: The ID of the window task that is running.
+ **`WINDOW_TARGET_ID`**: The ID of the window target that includes the target (target ID).
+ **`WINDOW_EXECUTION_ID`**: The ID of the current window execution.
+ **`TASK_EXECUTION_ID`**: The ID of the current task execution.
+ **`INVOCATION_ID`**: The ID of the current invocation.
+ **`TARGET_TYPE`**: The type of target. Supported types include `RESOURCE_GROUP` and `INSTANCE`.
+ **`TARGET_ID`**: 

  If the target type you specify is `INSTANCE`, the `TARGET_ID` pseudo parameter is replaced by the ID of the instance. For example, `i-078a280217EXAMPLE`.

  If the target type you specify is `RESOURCE_GROUP`, the value referenced for the task execution is the full ARN of the resource. For example: `arn:aws:ec2:us-east-1:123456789012:instance/i-078a280217EXAMPLE`. The following table provides sample `TARGET_ID` values for particular resource types in a resource group. 
**Note**  
`TARGET_ID` isn't supported for Run Command tasks.    
[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/systems-manager/latest/userguide/maintenance-window-tasks-pseudo-parameters.html)
+ **`RESOURCE_ID`**: The short ID of a resource type contained in a resource group. The following table provides sample `RESOURCE_ID` values for particular resource types in a resource group. 
**Note**  
`RESOURCE_ID` isn't supported for Run Command tasks.    
[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/systems-manager/latest/userguide/maintenance-window-tasks-pseudo-parameters.html)
**Note**  
If the AWS resource group you specify includes resource types that don't yield a `RESOURCE_ID` value, and aren't listed in the preceding table, then the `RESOURCE_ID` parameter isn't populated. An execution invocation will still occur for that resource. In these cases, use the `TARGET_ID` pseudo parameter instead, which will be replaced with the full ARN of the resource.

# Maintenance window scheduling and active period options
<a name="maintenance-windows-schedule-options"></a>

When you create a maintenance window, you must specify how often the maintenance window runs by using a [Cron or rate expression](reference-cron-and-rate-expressions.md). Optionally, you can specify a date range during which the maintenance window can run on its regular schedule and a time zone on which to base that regular schedule. 

Be aware, however, that the time zone option and the start date and end date options don't influence each other. Any start date and end date times that you specify (with or without an offset for your time zone) determine only the *valid period* during which the maintenance window can run on its schedule. A time zone option determines the international time zone that the maintenance window schedule is based on *during* its valid period.

**Note**  
You specify start and end dates in ISO-8601 timestamp format. For example: `2021-04-07T14:29:00-08:00`  
You specify time zones in Internet Assigned Numbers Authority (IANA) format. For example: `America/Chicago`, `Europe/Berlin` or `Asia/Tokyo`

**Topics**
+ [Example 1: Specify a maintenance window start date](#schedule-example-start-date)
+ [Example 2: Specify a maintenance window start date and end date](#schedule-example-start-end-date)
+ [Example 3: Create a maintenance window that runs only once](#schedule-example-one-time)
+ [Example 4: Specify the number of schedule offset days for a maintenance window](#schedule-example-schedule-offset)

## Example 1: Specify a maintenance window start date
<a name="schedule-example-start-date"></a>

Say that you use the AWS Command Line Interface (AWS CLI) to create a maintenance window with the following options:
+ `--start-date 2021-01-01T00:00:00-08:00`
+ `--schedule-timezone "America/Los_Angeles"`
+ `--schedule "cron(0 09 ? * WED *)"`

For example:

------
#### [ Linux & macOS ]

```
aws ssm create-maintenance-window \
    --name "My-LAX-Maintenance-Window" \
    --allow-unassociated-targets \
    --duration 3 \
    --cutoff 1 \
    --start-date 2021-01-01T00:00:00-08:00 \
    --schedule-timezone "America/Los_Angeles" \
    --schedule "cron(0 09 ? * WED *)"
```

------
#### [ Windows ]

```
aws ssm create-maintenance-window ^
    --name "My-LAX-Maintenance-Window" ^
    --allow-unassociated-targets ^
    --duration 3 ^
    --cutoff 1 ^
    --start-date 2021-01-01T00:00:00-08:00 ^
    --schedule-timezone "America/Los_Angeles" ^
    --schedule "cron(0 09 ? * WED *)"
```

------

This means that the first run of the maintenance window won't occur until *after* its specified start date and time, which is at 12:00 AM US Pacific Time on Friday, January 1, 2021. (This time zone is eight hours behind UTC time.) In this case, the start date and time of the window period don't represent when the maintenance windows first runs. Taken together, the `--schedule-timezone` and `--schedule` values mean that the maintenance window runs at 9 AM every Wednesday in the US Pacific Time Zone (represented by "America/Los Angeles" in IANA format). The first execution in the allowed period will be on Wednesday, January 4, 2021, at 9 AM US Pacific Time.

## Example 2: Specify a maintenance window start date and end date
<a name="schedule-example-start-end-date"></a>

Suppose that next you create a maintenance window with these options:
+ `--start-date 2019-01-01T00:03:15+09:00`
+ `--end-date 2019-06-30T00:06:15+09:00`
+ `--schedule-timezone "Asia/Tokyo"`
+ `--schedule "rate(7 days)"`

For example:

------
#### [ Linux & macOS ]

```
aws ssm create-maintenance-window \
    --name "My-NRT-Maintenance-Window" \
    --allow-unassociated-targets \
    --duration 3 \
    --cutoff 1 \
    --start-date 2019-01-01T00:03:15+09:00 \
    --end-date 2019-06-30T00:06:15+09:00 \
    --schedule-timezone "Asia/Tokyo" \
    --schedule "rate(7 days)"
```

------
#### [ Windows ]

```
aws ssm create-maintenance-window ^
    --name "My-NRT-Maintenance-Window" ^
    --allow-unassociated-targets ^
    --duration 3 ^
    --cutoff 1 ^
    --start-date 2019-01-01T00:03:15+09:00 ^
    --end-date 2019-06-30T00:06:15+09:00 ^
    --schedule-timezone "Asia/Tokyo" ^
    --schedule "rate(7 days)"
```

------

The allowed period for this maintenance window begins at 3:15 AM Japan Standard Time on January 1, 2019. The valid period for this maintenance window ends at 6:15 AM Japan Standard Time on Sunday, June 30, 2019. (This time zone is nine hours ahead of UTC time.) Taken together, the `--schedule-timezone` and `--schedule` values mean that the maintenance window runs at 3:15 AM every Tuesday in the Japan Standard Time Zone (represented by "Asia/Tokyo" in IANA format). This is because the maintenance window runs every seven days, and it becomes active at 3:15 AM on Tuesday, January 1. The last execution is at 3:15 AM Japan Standard Time on Tuesday, June 25, 2019. This is the last Tuesday before the allowed maintenance window period ends five days later.

## Example 3: Create a maintenance window that runs only once
<a name="schedule-example-one-time"></a>

Now you create a maintenance window with this option:
+ `--schedule "at(2020-07-07T15:55:00)"`

For example:

------
#### [ Linux & macOS ]

```
aws ssm create-maintenance-window \
    --name "My-One-Time-Maintenance-Window" \
    --schedule "at(2020-07-07T15:55:00)" \
    --duration 5 \
    --cutoff 2 \
    --allow-unassociated-targets
```

------
#### [ Windows ]

```
aws ssm create-maintenance-window ^
    --name "My-One-Time-Maintenance-Window" ^
    --schedule "at(2020-07-07T15:55:00)" ^
    --duration 5 ^
    --cutoff 2 ^
    --allow-unassociated-targets
```

------

This maintenance window runs just once, at 3:55 PM UTC time on July 7, 2020. The maintenance window is allowed to run up to five hours, as needed, but new tasks are prevented from starting two hours before the end of the maintenance window period.

## Example 4: Specify the number of schedule offset days for a maintenance window
<a name="schedule-example-schedule-offset"></a>

Now you create a maintenance window with this option:

```
--schedule-offset 2
```

For example:

------
#### [ Linux & macOS ]

```
aws ssm create-maintenance-window \
    --name "My-Cron-Offset-Maintenance-Window" \
    --schedule "cron(0 30 23 ? * TUE#3 *)" \
    --duration 4 \
    --cutoff 1 \
    --schedule-offset 2 \
    --allow-unassociated-targets
```

------
#### [ Windows ]

```
aws ssm create-maintenance-window ^
    --name "My-Cron-Offset-Maintenance-Window" ^
    --schedule "cron(0 30 23 ? * TUE#3 *)" ^
    --duration 4 ^
    --cutoff 1 ^
    --schedule-offset 2 ^
    --allow-unassociated-targets
```

------

A schedule offset is the number of days to wait after the date and time specified by a CRON expression before running the maintenance window.

In the preceding example, the CRON expression schedules a maintenance window to run the third Tuesday of every month at 11:30 PM: 

```
--schedule "cron(0 30 23 ? * TUE#3 *)
```

However, including `--schedule-offset 2` means that the maintenance window won't run until 11:30 PM two days *after* the third Tuesday of each month. 

Schedule offsets are supported for CRON expressions only. 

**More info**  
+ [Reference: Cron and rate expressions for Systems Manager](reference-cron-and-rate-expressions.md)
+ [Create a maintenance window using the console](sysman-maintenance-create-mw.md)
+ [Tutorial: Create and configure a maintenance window using the AWS CLI](maintenance-windows-cli-tutorials-create.md)
+ [CreateMaintenanceWindow](https://docs.aws.amazon.com/systems-manager/latest/APIReference/API_CreateMaintenanceWindow.html) in the *AWS Systems Manager API Reference*
+ [https://docs.aws.amazon.com/cli/latest/reference/ssm/create-maintenance-window.html](https://docs.aws.amazon.com/cli/latest/reference/ssm/create-maintenance-window.html) in the *AWS Systems Manager section of the AWS CLI Command Reference*
+ [Time Zone Database](https://www.iana.org/time-zones) on the IANA website

# Registering maintenance window tasks without targets
<a name="maintenance-windows-targetless-tasks"></a>

For each maintenance window you create, you can specify one or more tasks to perform when the maintenance window runs. In most cases, you must specify the resources, or targets, that the task is to run on. In some cases, however, you don't need to specify targets explicitly in the task.

One or more targets must be specified for maintenance window Systems Manager Run Command-type tasks. Depending on the nature of the task, targets are optional for other maintenance window task types (Systems Manager Automation, AWS Lambda, and AWS Step Functions). 

For Lambda and Step Functions task types, whether a target is required depends on the content of the function or state machine you have created.

**Note**  
When a task has registered targets, Automation, AWS Lambda, and AWS Step Functions tasks resolve the targets from resource groups and tags and send one invocation per resolved resource, which results in multiple task invocations. But say, for example, that you want only one invocation for a Lambda task that's registered with a resource group containing more than one instance. In this case, if you are working in the AWS Management Console, choose the option **Task target not required** in the **Register Lambda task** or **Edit Lambda task** page. If you are using the AWS CLI command, do not specify targets using the `--targets` parameter when running the [https://docs.aws.amazon.com/cli/latest/reference/ssm/register-task-with-maintenance-window.html](https://docs.aws.amazon.com/cli/latest/reference/ssm/register-task-with-maintenance-window.html) command or [https://docs.aws.amazon.com/cli/latest/reference/ssm/update-maintenance-window-task.html](https://docs.aws.amazon.com/cli/latest/reference/ssm/update-maintenance-window-task.html) command.

In many cases, you don't need to explicitly specify a target for an automation task. For example, say that you're creating an Automation-type task to update an Amazon Machine Image (AMI) for Linux using the `AWS-UpdateLinuxAmi` runbook. When the task runs, the AMI is updated with the latest available Linux distribution packages and Amazon software. New instances created from the AMI already have these updates installed. Because the ID of the AMI to be updated is specified in the input parameters for the runbook, there is no need to specify a target again in the maintenance window task.

Similarly, suppose you're using the AWS Command Line Interface (AWS CLI) to register a maintenance window Automation task that uses the `AWS-RestartEC2Instance` runbook. Because the node to restart is specified in the `--task-invocation-parameters` argument, you don't need to also specify a `--targets` option. 

**Note**  
For maintenance window tasks without a target specified, you can't supply values for `--max-errors` and `--max-concurrency`. Instead, the system inserts a placeholder value of `1`, which might be reported in the response to commands such as [https://docs.aws.amazon.com/cli/latest/reference/ssm/describe-maintenance-window-tasks.html](https://docs.aws.amazon.com/cli/latest/reference/ssm/describe-maintenance-window-tasks.html) and [https://docs.aws.amazon.com/cli/latest/reference/ssm/get-maintenance-window-task.html](https://docs.aws.amazon.com/cli/latest/reference/ssm/get-maintenance-window-task.html). These values don't affect the running of your task and can be ignored.

The following example demonstrates omitting the `--targets`, `--max-errors`, and `--max-concurrency` options for a targetless maintenance window task.

------
#### [ Linux & macOS ]

```
aws ssm register-task-with-maintenance-window \
    --window-id "mw-ab12cd34eEXAMPLE" \
    --service-role-arn "arn:aws:iam::123456789012:role/MaintenanceWindowAndAutomationRole" \
    --task-type "AUTOMATION" \
    --name "RestartInstanceWithoutTarget" \
    --task-arn "AWS-RestartEC2Instance" \
    --task-invocation-parameters "{\"Automation\":{\"Parameters\":{\"InstanceId\":[\"i-02573cafcfEXAMPLE\"]}}}" \
    --priority 10
```

------
#### [ Windows ]

```
aws ssm register-task-with-maintenance-window ^
    --window-id "mw-ab12cd34eEXAMPLE" ^
    --service-role-arn "arn:aws:iam::123456789012:role/MaintenanceWindowAndAutomationRole" ^
    --task-type "AUTOMATION" ^
    --name "RestartInstanceWithoutTarget" ^
    --task-arn "AWS-RestartEC2Instance" ^
    --task-invocation-parameters "{\"Automation\":{\"Parameters\":{\"InstanceId\":[\"i-02573cafcfEXAMPLE\"]}}}" ^
    --priority 10
```

------

**Note**  
For maintenance window tasks registered before December 23, 2020: If you specified targets for the task and one is no longer required, you can update that task to remove the targets using the Systems Manager console or the [https://docs.aws.amazon.com/cli/latest/reference/ssm/update-maintenance-window-task.html](https://docs.aws.amazon.com/cli/latest/reference/ssm/update-maintenance-window-task.html) AWS CLI command.

**More info**  
+ [Error messages: "Maintenance window tasks without targets don't support MaxConcurrency values" and "Maintenance window tasks without targets don't support MaxErrors values"](troubleshooting-maintenance-windows.md#maxconcurrency-maxerrors-not-supported)

# Troubleshooting maintenance windows
<a name="troubleshooting-maintenance-windows"></a>

Use the following information to help you troubleshoot problems with maintenance windows.

**Topics**
+ [Edit task error: On the page for editing a maintenance window task, the IAM role list returns an error message: "We couldn't find the IAM maintenance window role specified for this task. It might have been deleted, or it might not have been created yet."](#maintenance-window-role-troubleshooting)
+ [Not all maintenance window targets are updated](#targets-not-updated)
+ [Task fails with task invocation status: "The provided role does not contain the correct SSM permissions."](#incorrect-ssm-permissions)
+ [Task fails with error message: "Step fails when it is validating and resolving the step inputs"](#step-fails)
+ [Error messages: "Maintenance window tasks without targets don't support MaxConcurrency values" and "Maintenance window tasks without targets don't support MaxErrors values"](#maxconcurrency-maxerrors-not-supported)

## Edit task error: On the page for editing a maintenance window task, the IAM role list returns an error message: "We couldn't find the IAM maintenance window role specified for this task. It might have been deleted, or it might not have been created yet."
<a name="maintenance-window-role-troubleshooting"></a>

**Problem 1**: The AWS Identity and Access Management (IAM) maintenance window role you originally specified was deleted after you created the task.

**Possible fix**: 1) Select a different IAM maintenance window role, if one exists in your account, or create a new one and select it for the task. 

**Problem 2**: If the task was created using the AWS Command Line Interface (AWS CLI), AWS Tools for Windows PowerShell, or an AWS SDK, a non-existent IAM maintenance window role name could have been specified. For example, the IAM maintenance window role could have been deleted before you created the task, or the role name could have been typed incorrectly, such as **myrole** instead of **my-role**.

**Possible fix**: Select the correct name of the IAM maintenance window role you want to use, or create a new one to specify for the task. 

## Not all maintenance window targets are updated
<a name="targets-not-updated"></a>

**Problem:** You notice that maintenance window tasks didn't run on all the resources targeted by your maintenance window. For example, in the maintenance window run results, the task for that resource is marked as failed or timed out.

**Solution:** The most common reasons for a maintenance window task not running on a target resource involve connectivity and availability. For example:
+ Systems Manager lost connection to the resource before or during the maintenance window operation.
+ The resource was offline or stopped during the maintenance window operation.

You can wait for the next scheduled maintenance window time to run tasks on the resources. You can manually run the maintenance window tasks on the resources that weren't available or were offline.

## Task fails with task invocation status: "The provided role does not contain the correct SSM permissions."
<a name="incorrect-ssm-permissions"></a>

**Problem**: You have specified a maintenance window service role for a task, but the task fails to run successfully and the task invocation status reports that "The provided role does not contain the correct SSM permissions." 
+ **Solution**: In [Task 1: Create a custom policy for your maintenance window service role using the console](configuring-maintenance-window-permissions-console.md#create-custom-policy-console), we provide a basic policy you can attach to your [custom maintenance window service role](configuring-maintenance-window-permissions-console.md#create-custom-role-console). The policy includes the permissions needed for many task scenarios. However, due to the wide variety of tasks you can run, you might need to provide additional permissions in the policy for your maintenance window role.

  For example, some Automation actions work with AWS CloudFormation stacks. Therefore, you might need to add the additional permissions `cloudformation:CreateStack`, `cloudformation:DescribeStacks`, and `cloudformation:DeleteStack` to the policy for your maintenance window service role. 

  For another example, the Automation runbook `AWS-CopySnapshot` requires permissions to create an Amazon Elastic Block Store (Amazon EBS) snapshot. Therefore, you might need to add the permission `ec2:CreateSnapshot`.

  For information about the role permissions needed by an AWS managed Automation runbook, see the runbook descriptions in the [AWS Systems Manager Automation Runbook Reference](https://docs.aws.amazon.com/systems-manager-automation-runbooks/latest/userguide/automation-runbook-reference.html).

  For information about the role permissions needed by an AWS managed SSM document, review the content of the document in the [Documents](https://console.aws.amazon.com//systems-manager/documents) section Systems Manager console.

  For information about the role permissions needed for Step Functions tasks, Lambda tasks, and custom Automation runbooks and SSM documents, verify permission requirements with the author of those resources.

## Task fails with error message: "Step fails when it is validating and resolving the step inputs"
<a name="step-fails"></a>

**Problem**: An Automation runbook or Systems Manager Command document you're using in a task requires that you specify inputs such as `InstanceId` or `SnapshotId`, but a value isn't supplied or isn't supplied correctly.
+ **Solution 1**: If your task is targeting a single resource, such as a single node or single snapshot, enter its ID in the input parameters for the task.
+ **Solution 2**: If your task is targeting multiple resources, such as creating images from multiple nodes when you use the runbook `AWS-CreateImage`, you can use one of the pseudo parameters supported for maintenance window tasks in the input parameters to represent node IDs in the command. 

  The following commands register a Systems Manager Automation task with a maintenance window using the AWS CLI. The `--targets` value indicates a maintenance window target ID. Also, even though the `--targets` parameter specifies a window target ID, parameters of the Automation runbook require that a node ID be provided. In this case, the command uses the pseudo parameter `{{RESOURCE_ID}}` as the `InstanceId` value.

  **AWS CLI command:**

------
#### [ Linux & macOS ]

  The following example command restarts Amazon Elastic Compute Cloud (Amazon EC2) instances that belong to the maintenance window target group with the ID e32eecb2-646c-4f4b-8ed1-205fbEXAMPLE.

  ```
  aws ssm register-task-with-maintenance-window \
      --window-id "mw-0c50858d01EXAMPLE" \
      --targets Key=WindowTargetIds,Values=e32eecb2-646c-4f4b-8ed1-205fbEXAMPLE \
      --task-arn "AWS-RestartEC2Instance" \
      --service-role-arn arn:aws:iam::123456789012:role/MyMaintenanceWindowServiceRole \
      --task-type AUTOMATION \
      --task-invocation-parameters "Automation={DocumentVersion=5,Parameters={InstanceId='{{RESOURCE_ID}}'}}" \
      --priority 0 --max-concurrency 10 --max-errors 5 --name "My-Restart-EC2-Instances-Automation-Task" \
      --description "Automation task to restart EC2 instances"
  ```

------
#### [ Windows ]

  ```
  aws ssm register-task-with-maintenance-window ^
      --window-id "mw-0c50858d01EXAMPLE" ^
      --targets Key=WindowTargetIds,Values=e32eecb2-646c-4f4b-8ed1-205fbEXAMPLE ^
      --task-arn "AWS-RestartEC2Instance" ^
      --service-role-arn arn:aws:iam::123456789012:role/MyMaintenanceWindowServiceRole ^
      --task-type AUTOMATION ^
      --task-invocation-parameters "Automation={DocumentVersion=5,Parameters={InstanceId='{{RESOURCE_ID}}'}}" ^
      --priority 0 --max-concurrency 10 --max-errors 5 --name "My-Restart-EC2-Instances-Automation-Task" ^
      --description "Automation task to restart EC2 instances"
  ```

------

  For more information about working with pseudo parameters for maintenance window tasks, see [Using pseudo parameters when registering maintenance window tasks](maintenance-window-tasks-pseudo-parameters.md) and [Task registration examples](mw-cli-register-tasks-examples.md#task-examples).

## Error messages: "Maintenance window tasks without targets don't support MaxConcurrency values" and "Maintenance window tasks without targets don't support MaxErrors values"
<a name="maxconcurrency-maxerrors-not-supported"></a>

**Problem:** When you register a Run Command-type task, you must specify at least one target for the task to run on. For other task types (Automation, AWS Lambda, and AWS Step Functions), depending on the nature of the task, targets are optional. The options `MaxConcurrency` (the number of resources to run a task on at the same time) and `MaxErrors` (the number of failures to run the task on target resources before the task fails) aren't required or supported for maintenance window tasks that don't specify targets. The system generates these error messages if values are specified for either of these options when no task target is specified.

**Solution**: If you receive either of these errors, remove the values for concurrency and error threshold before continuing to register or update the maintenance window task.

For more information about running tasks that don't specify targets, see [Registering maintenance window tasks without targets](maintenance-windows-targetless-tasks.md) in the *AWS Systems Manager User Guide*.

# AWS Systems Manager Quick Setup
<a name="systems-manager-quick-setup"></a>

Use Quick Setup, a tool in AWS Systems Manager, to quickly configure frequently used Amazon Web Services services and features with recommended best practices. Quick Setup simplifies setting up services, including Systems Manager, by automating common or recommended tasks. These tasks include, for example, creating required AWS Identity and Access Management (IAM) instance profile roles and setting up operational best practices, such as periodic patch scans and inventory collection. There is no cost to use Quick Setup. However, costs can be incurred based on the type of services you set up and the usage limits with no fees for the services used to set up your service. To get started with Quick Setup, open the [Systems Manager console](https://console.aws.amazon.com/systems-manager/quick-setup). In the navigation pane, choose **Quick Setup**.

**Note**  
If you were directed to Quick Setup to help you configure your instances to be managed by Systems Manager, complete the procedure in [Set up Amazon EC2 host management using Quick Setup](quick-setup-host-management.md).

## What are the benefits of Quick Setup?
<a name="quick-setup-features"></a>

Benefits of Quick Setup include the following:
+ **Simplify service and feature configuration**

  Quick Setup walks you through configuring operational best practices and automatically deploys those configurations. The Quick Setup dashboard displays a real-time view of your configuration deployment status. 
+ **Deploy configurations automatically across multiple accounts**

  You can use Quick Setup in an individual AWS account or across multiple AWS accounts and AWS Regions by integrating with AWS Organizations. Using Quick Setup across multiple accounts helps to ensure that your organization maintains consistent configurations.
+ **Eliminate configuration drift**

  Configuration drift occurs whenever a user makes any change to a service or feature that conflicts with the selections made through Quick Setup. Quick Setup periodically checks for configuration drift and attempts to remediate it.

## Who should use Quick Setup?
<a name="quick-setup-audience"></a>

Quick Setup is most beneficial for customers who already have some experience with the services and features they're setting up, and want to simplify their setup process. If you're unfamiliar with the AWS service you're configuring with Quick Setup, we recommend that you learn more about the service. Review the content in the relevant User Guide before you create a configuration with Quick Setup.

## Availability of Quick Setup in AWS Regions
<a name="quick-setup-getting-started-regions"></a>

In the following AWS Regions, you can use all Quick Setup configuration types for an entire organization, as configured in AWS Organizations, or for only the organizational accounts and Regions you choose. You can also use Quick Setup with just a single account in these Regions.
+ US East (Ohio)
+ US East (N. Virginia)
+ US West (N. California)
+ US West (Oregon)
+ Asia Pacific (Mumbai)
+ Asia Pacific (Seoul)
+ Asia Pacific (Singapore)
+ Asia Pacific (Sydney)
+ Asia Pacific (Tokyo)
+ Canada (Central)
+ Europe (Frankfurt)
+ Europe (Stockholm)
+ Europe (Ireland)
+ Europe (London)
+ Europe (Paris)
+ South America (São Paulo)

In the following Regions, only the [Host Management](quick-setup-host-management.md) configuration type is available for individual accounts:
+ Europe (Milan)
+ Asia Pacific (Hong Kong)
+ Middle East (Bahrain)
+ China (Beijing)
+ China (Ningxia)
+ AWS GovCloud (US-East)
+ AWS GovCloud (US-West)

 For a list of all supported Regions for Systems Manager, see the **Region** column in [Systems Manager service endpoints](https://docs.aws.amazon.com/general/latest/gr/ssm.html#ssm_region) in the *Amazon Web Services General Reference*.

# Getting started with Quick Setup
<a name="quick-setup-getting-started"></a>

Use the information in this topic to help you prepare to use Quick Setup.

**Topics**
+ [IAM roles and permissions for Quick Setup onboarding](#quick-setup-getting-started-iam)
+ [Manual onboarding for working with Quick Setup API programmatically](#quick-setup-api-manual-onboarding)

## IAM roles and permissions for Quick Setup onboarding
<a name="quick-setup-getting-started-iam"></a>

Quick Setup launched a new console experience and a new API. Now you can interact with this API using the console, AWS CLI, CloudFormation, and SDKs. If you opt in to the new experience, your existing configurations are recreated using the new API. Depending on the number of existing configurations in your account, this process can take several minutes.

To use the new Quick Setup console, you must have permissions for the following actions:

------
#### [ JSON ]

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "ssm-quicksetup:*",
                "cloudformation:DescribeStackSetOperation",
                "cloudformation:ListStacks",
                "cloudformation:DescribeStacks",
                "cloudformation:DescribeStackResources",
                "cloudformation:ListStackSetOperations",
                "cloudformation:ListStackInstances",
                "cloudformation:DescribeStackSet",
                "cloudformation:ListStackSets",
                "cloudformation:DescribeStackInstance",
                "cloudformation:DescribeOrganizationsAccess",
                "cloudformation:ActivateOrganizationsAccess",
                "cloudformation:GetTemplate",
                "cloudformation:ListStackSetOperationResults",
                "cloudformation:DescribeStackEvents",
                "cloudformation:UntagResource",
                "ec2:DescribeInstances",
                "ssm:DescribeAutomationExecutions",
                "ssm:GetAutomationExecution",
                "ssm:ListAssociations",
                "ssm:DescribeAssociation",
                "ssm:GetDocument",
                "ssm:ListDocuments",
                "ssm:DescribeDocument",
                "ssm:ListResourceDataSync",
                "ssm:DescribePatchBaselines",
                "ssm:GetPatchBaseline",
                "ssm:DescribeMaintenanceWindows",
                "ssm:DescribeMaintenanceWindowTasks",
                "ssm:GetOpsSummary",
                "organizations:DeregisterDelegatedAdministrator",
                "organizations:DescribeAccount",
                "organizations:DescribeOrganization",
                "organizations:ListDelegatedAdministrators",
                "organizations:ListRoots",
                "organizations:ListParents",
                "organizations:ListOrganizationalUnitsForParent",
                "organizations:DescribeOrganizationalUnit",
                "organizations:ListAWSServiceAccessForOrganization",
                "s3:GetBucketLocation",
                "s3:ListAllMyBuckets",
                "s3:ListBucket",
                "resource-groups:ListGroups",
                "iam:ListRoles",
                "iam:ListRolePolicies",
                "iam:GetRole",
                "iam:CreatePolicy",
                "organizations:RegisterDelegatedAdministrator",
                "organizations:EnableAWSServiceAccess",
                "cloudformation:TagResource"
            ],
            "Resource": "*"
        },
        {
            "Effect": "Allow",
            "Action": [
                "cloudformation:RollbackStack",
                "cloudformation:CreateStack",
                "cloudformation:UpdateStack",
                "cloudformation:DeleteStack"
            ],
            "Resource": [
                "arn:aws:cloudformation:*:*:stack/StackSet-AWS-QuickSetup-*",
                "arn:aws:cloudformation:*:*:stack/AWS-QuickSetup-*",
                "arn:aws:cloudformation:*:*:type/resource/*",
                "arn:aws:cloudformation:*:*:stack/StackSet-SSMQuickSetup"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "cloudformation:CreateStackSet",
                "cloudformation:UpdateStackSet",
                "cloudformation:DeleteStackSet",
                "cloudformation:DeleteStackInstances",
                "cloudformation:CreateStackInstances",
                "cloudformation:StopStackSetOperation"
            ],
            "Resource": [
                "arn:aws:cloudformation:*:*:stackset/AWS-QuickSetup-*",
                "arn:aws:cloudformation:*:*:stackset/SSMQuickSetup",
                "arn:aws:cloudformation:*:*:type/resource/*",
                "arn:aws:cloudformation:*:*:stackset-target/AWS-QuickSetup-*:*"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "iam:CreateRole",
                "iam:DeleteRole",
                "iam:AttachRolePolicy",
                "iam:DetachRolePolicy",
                "iam:GetRolePolicy",
                "iam:PutRolePolicy"
            ],
            "Resource": [
                "arn:aws:iam::*:role/AWS-QuickSetup-*",
                "arn:aws:iam::*:role/service-role/AWS-QuickSetup-*"
            ]
        },
        {
            "Effect": "Allow",
            "Action": "iam:PassRole",
            "Resource": "arn:aws:iam::111122223333:role/AWS-QuickSetup-*",
            "Condition": {
                "StringEquals": {
	            "iam:PassedToService": [
	                "ssm-quicksetup.amazonaws.com",
	                "cloudformation.amazonaws.com"
	            ]
                }
            }
        },
        {
            "Effect": "Allow",
            "Action": [
                "ssm:DeleteAssociation",
                "ssm:CreateAssociation",
                "ssm:StartAssociationsOnce"
            ],
            "Resource": "*"
        },
        {
            "Effect": "Allow",
            "Action": "ssm:StartAutomationExecution",
            "Resource": [
                "arn:aws:ssm:*:*:document/AWS-EnableExplorer",
                "arn:aws:ssm:*:*:automation-execution/*"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "ssm:GetOpsSummary",
                "ssm:CreateResourceDataSync",
                "ssm:UpdateResourceDataSync"
            ],
            "Resource": "arn:aws:ssm:*:*:resource-data-sync/AWS-QuickSetup-*"
        },
        {
            "Effect": "Allow",
            "Action": [
                "iam:CreateServiceLinkedRole"
            ],
            "Condition": {
                "StringEquals": {
                    "iam:AWSServiceName": [
                        "accountdiscovery.ssm.amazonaws.com",
                        "ssm.amazonaws.com",
                        "ssm-quicksetup.amazonaws.com",
                        "stacksets.cloudformation.amazonaws.com"
                    ]
                }
            },
            "Resource": "*"
        },
        {
            "Effect": "Allow",
            "Action": [
                "iam:CreateServiceLinkedRole"
            ],
            "Resource": "arn:aws:iam::*:role/aws-service-role/stacksets.cloudformation.amazonaws.com/AWSServiceRoleForCloudFormationStackSetsOrgAdmin"
        }
    ]
}
```

------

To restrict users to read-only permissions, only allow `ssm-quicksetup:List*` and `ssm-quicksetup:Get*` operations for the Quick Setup API.

During onboarding, Quick Setup creates the following AWS Identity and Access Management (IAM) roles on your behalf:
+ `AWS-QuickSetup-LocalExecutionRole` – Grants CloudFormation permissions to use any template, excluding the patch policy template, and create the necessary resources.
+ `AWS-QuickSetup-LocalAdministrationRole` – Grants permissions to AWS CloudFormation to assume `AWS-QuickSetup-LocalExecutionRole`.
+ `AWS-QuickSetup-PatchPolicy-LocalExecutionRole` – Grants permissions to AWS CloudFormation to use the patch policy template, and create the necessary resources.
+ `AWS-QuickSetup-PatchPolicy-LocalAdministrationRole` – Grants permissions to AWS CloudFormation to assume `AWS-QuickSetup-PatchPolicy-LocalExecutionRole`.

If you're onboarding a management account—the account that you use to create an organization in AWS Organizations—Quick Setup also creates the following roles on your behalf:
+ `AWS-QuickSetup-SSM-RoleForEnablingExplorer` – Grants permissions to the `AWS-EnableExplorer` automation runbook. The `AWS-EnableExplorer` runbook configures Explorer, a tool in Systems Manager, to display information for multiple AWS accounts and AWS Regions.
+ `AWSServiceRoleForAmazonSSM` – A service-linked role that grants access to AWS resources managed and used by Systems Manager.
+ `AWSServiceRoleForAmazonSSM_AccountDiscovery` – A service-linked role that grants permissions to Systems Manager to call AWS services to discover AWS account information when synchronizing data. For more information, see [Using roles to collect AWS account information for OpsCenter and Explorer](using-service-linked-roles-service-action-2.md).

When onboarding a management account, Quick Setup enables trusted access between AWS Organizations and CloudFormation to deploy Quick Setup configurations across your organization. To enable trusted access, your management account must have administrator permissions. After onboarding, you no longer need administrator permissions. For more information, see [Enable trusted access with Organizations](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/stacksets-orgs-enable-trusted-access.html).

For information about AWS Organizations account types, see [AWS Organizations terminology and concepts](https://docs.aws.amazon.com/organizations/latest/userguide/orgs_getting-started_concepts.html) in the *AWS Organizations User Guide*.

**Note**  
Quick Setup uses CloudFormation StackSets to deploy your configurations across AWS accounts and Regions. If the number of target accounts multiplied by the number of Regions exceeds 10,000, the configuration fails to deploy. We recommend reviewing your use case and creating configurations that use fewer targets to accommodate the growth of your organization. Stack instances aren't deployed to your organization's management account. For more information, see [Considerations when creating a stack set with service-managed permissions](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/stacksets-getting-started-create.html?icmpid=docs_cfn_console#stacksets-orgs-considerations). 

## Manual onboarding for working with Quick Setup API programmatically
<a name="quick-setup-api-manual-onboarding"></a>

If you use the console to work with Quick Setup, the service handles onboarding steps for you. If you plan to use SDKs or the AWS CLI to work with the Quick Setup API, you can still use the console to complete onboarding steps for you so you don't have to perform them manually. However, some customers need to complete onboarding steps for Quick Setup programmatically without interacting with the console. If this method fits your use case, you must complete the following steps. All of these steps must be completed from your AWS Organizations management account.

**To complete manual onboarding for Quick Setup**

1. Activate trusted access for CloudFormation with Organizations. This provides the management account with the permissions needed to create and manage StackSets for your organization. You can use CloudFormation's `ActivateOrganizationsAccess` API action to complete this step. For more information, see [ActivateOrganizationsAccess](https://docs.aws.amazon.com/AWSCloudFormation/latest/APIReference/API_ActivateOrganizationsAccess.html) in the *AWS CloudFormation API Reference*.

1. Enable the integration of Systems Manager with Organizations. This allows Systems Manager to create a service-linked role in all the accounts in your organization. This also allows Systems Manager to perform operations on your behalf in your organization and its accounts. You can use AWS Organizations's `EnableAWSServiceAccess` API action to complete this step. The service principal for Systems Manager is `ssm.amazonaws.com`.For more information, see [EnableAWSServiceAccess](https://docs.aws.amazon.com/organizations/latest/APIReference/API_EnableAWSServiceAccess.html) in the *AWS Organizations API Reference*.

1. Create the required IAM role for Explorer. This allows Quick Setup to create dashboards for your configurations so you can view deployment and association statuses. Create an IAM role and attach the `AWSSystemsManagerEnableExplorerExecutionPolicy` managed policy. Modify the trust policy for the role to match the following. Replace each *account ID* with your information.

------
#### [ JSON ]

****  

   ```
   {
       "Version":"2012-10-17",		 	 	 
       "Statement": [
           {
               "Effect": "Allow",
               "Principal": {
                   "Service": "ssm.amazonaws.com"
               },
               "Action": "sts:AssumeRole",
               "Condition": {
                   "StringEquals": {
                       "aws:SourceAccount": "111122223333"
                   },
                   "ArnLike": {
                       "aws:SourceArn": "arn:*:ssm:*:111122223333:automation-execution/*"
                   }
               }
           }
       ]
   }
   ```

------

1. Update the Quick Setup service setting for Explorer. You can use Quick Setup's `UpdateServiceSettings` API action to complete this step. Specify the ARN for the IAM role you created in the previous step for the `ExplorerEnablingRoleArn` request parameter. For more information, see [UpdateServiceSettings](https://docs.aws.amazon.com/quick-setup/latest/APIReference/API_UpdateServiceSettings.html) in the *Quick Setup API Reference*.

1. Create the required IAM roles for CloudFormation StackSets to use. You must create an *execution* role and an *administration* role.

   1. Create the execution role. The execution role should have at least one of the `AWSQuickSetupDeploymentRolePolicy` or `AWSQuickSetupPatchPolicyDeploymentRolePolicy` managed policies attached. If you're only creating patch policy configurations, you can use `AWSQuickSetupPatchPolicyDeploymentRolePolicy` managed policy. All other configurations use the `AWSQuickSetupDeploymentRolePolicy` policy. Modify the trust policy for the role to match the following. Replace each *account ID* and *administration role name* with your information.

------
#### [ JSON ]

****  

      ```
      {
          "Version":"2012-10-17",		 	 	 
          "Statement": [
              {
                  "Effect": "Allow",
                  "Principal": {
                      "AWS": "arn:aws:iam::111122223333:role/administration role name"
                  },
                  "Action": "sts:AssumeRole"
              }
          ]
      }
      ```

------

   1. Create the administration role. The permissions policy must match the following. Replace each *account ID* and *execution role name* with your information.

------
#### [ JSON ]

****  

      ```
      {
          "Version":"2012-10-17",		 	 	 
          "Statement": [
              {
                  "Action": [
                      "sts:AssumeRole"
                  ],
                  "Resource": "arn:*:iam::111122223333:role/execution role name",
                  "Effect": "Allow"
              }
          ]
      }
      ```

------

      Modify the trust policy for the role to match the following. Replace each *account ID* with your information.

------
#### [ JSON ]

****  

      ```
      {
          "Version":"2012-10-17",		 	 	 
          "Statement": [
              {
                  "Effect": "Allow",
                  "Principal": {
                      "Service": "cloudformation.amazonaws.com"
                  },
                  "Action": "sts:AssumeRole",
                  "Condition": {
                      "StringEquals": {
                          "aws:SourceAccount": "111122223333"
                      },
                      "ArnLike": {
                          "aws:SourceArn": "arn:aws:cloudformation:*:111122223333:stackset/AWS-QuickSetup-*"
                      }
                  }
              }
          ]
      }
      ```

------

# Configuration for Assume Role for Systems Manager
<a name="quick-setup-assume-role"></a>

## To create an assume role for Systems Manager Quick Setup:
<a name="create-assume-role"></a>

Systems Manager Quick Setup requires a role that allows Systems Manager to securely perform actions in your account. This role grants Systems Manager the permissions needed to run commands on your instances and configure EC2 instances, IAM roles, and other Systems Manager resources on your behalf.

1. Open the IAM console at [https://console.aws.amazon.com/iam/](https://console.aws.amazon.com/iam/).

1. In the navigation pane, choose **Policies**, and then **Create Policy**

1. Add the `SsmOnboardingInlinePolicy` policy using the JSON below. (This policy enables actions required in order to attach instance profile permissions to instances you specify. For example allowing creation of instance profiles and associating them with EC2 instances).

1. Once complete, in the navigation pane, choose **Roles**, and then choose **Create role**.

1. For **Trusted entity type**, keep it as default (service).

1. Under **Use case**, choose **Systems Manager**, then choose **Next**.

1. On the **Add permissions** page:

1. Add the `SsmOnboardingInlinePolicy` policy

1. Choose **Next**

1. For **Role name**, enter a descriptive name (for example, `AmazonSSMRoleForAutomationAssumeQuickSetup`).

1. (Optional) Add tags to help identify and organize the role.

1. Choose **Create role**.

**Important**  
The role must include a trust relationship with `ssm.amazonaws.com`. This is automatically configured when you select Systems Manager as the service in step 4.

After creating the role, you can select it when configuring Quick Setup. The role enables Systems Manager to manage EC2 instances, IAM roles, and other Systems Manager resources and run commands on your behalf while maintaining security through specific, limited permissions.

## Permissions Policies
<a name="permissions-policies"></a>

**`SsmOnboardingInlinePolicy`**  
The following policy defines the permissions for Systems Manager Quick Setup:

```
{
    "Version": "2012-10-17" 		 	 	 ,
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "iam:CreateInstanceProfile",
                "iam:ListInstanceProfilesForRole",
                "ec2:DescribeIamInstanceProfileAssociations",
                "iam:GetInstanceProfile",
                "iam:AddRoleToInstanceProfile"
            ],
            "Resource": "*"
        },
        {
            "Effect": "Allow",
            "Action": [
                "ec2:AssociateIamInstanceProfile"
            ],
            "Resource": "arn:aws:ec2:*:*:instance/*",
            "Condition": {
                "Null": {
                    "ec2:InstanceProfile": "true"
                },
                "ArnLike": {
                    "ec2:NewInstanceProfile": "arn:aws:iam::*:instance-profile/[INSTANCE_PROFILE_ROLE_NAME]"
                }
            }
        },
        {
            "Effect": "Allow",
            "Action": "iam:PassRole",
            "Resource": "arn:aws:iam::*:role/[INSTANCE_PROFILE_ROLE_NAME]",
            "Condition": {
                "StringEquals": {
                    "iam:PassedToService": "ec2.amazonaws.com"
                }
            }
        }
    ]
        }
```

**Trust Relationship**  
*This is added automatically via the above steps*

```
{
    "Version": "2012-10-17" 		 	 	 ,
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "Service": "ssm.amazonaws.com"
            },
            "Action": "sts:AssumeRole"
        }
     ]
        }
```

# Using a delegated administrator for Quick Setup
<a name="quick-setup-delegated-administrator"></a>

After you register a delegated administrator account for Quick Setup, users with the appropriate permissions in that account can create, update, view, and delete configuration managers that target organizational units within your AWS Organizations structure. This delegated administrator account can also manage configuration managers previously created by your organization's management account.

The management account in Organizations can designate one account within your organization as a delegated administrator. When you register an account as a delegated administrator for Quick Setup, this account automatically becomes a delegated administrator for AWS CloudFormation StackSets and Systems Manager Explorer as well, since these services are required to deploy and monitor Quick Setup configurations.

**Note**  
At this time, the patch policy configuration type isn't supported by the delegated administrator for Quick Setup. Patch policy configurations for an organization must be created and maintained in the management account for an organization. For more information, see [Creating a patch policy](quick-setup-patch-manager.md#create-patch-policy).

The following topics describe how to register and deregister a delegated administrator for Quick Setup.

**Topics**
+ [Register a delegated administrator for Quick Setup](quick-setup-register-delegated-administrator.md)
+ [Deregister a delegated administrator for Quick Setup](quick-setup-deregister-delegated-administrator.md)

# Register a delegated administrator for Quick Setup
<a name="quick-setup-register-delegated-administrator"></a>

Use the following procedure to register a delegated administrator for Quick Setup.

**To register a Quick Setup delegated administrator**

1. Log into your AWS Organizations management account.

1. Open the AWS Systems Manager console at [https://console.aws.amazon.com/systems-manager/](https://console.aws.amazon.com/systems-manager/).

1. In the navigation pane, choose **Quick Setup**.

1. Choose **Settings**.

1. In the **Delegated administrator for Quick Setup** section, verify that you have configured the required service-linked role and service access options. If necessary, choose the **Create role** and **Enable access** buttons to configure these options.

1. For **Account ID**, enter the AWS account ID. This account must be a member account in AWS Organizations.

1. Choose **Register delegated administrator**.

# Deregister a delegated administrator for Quick Setup
<a name="quick-setup-deregister-delegated-administrator"></a>

Use the following procedure to deregister a delegated administrator for Quick Setup.

**To deregister a Quick Setup delegated administrator**

1. Log into your AWS Organizations management account.

1. Open the AWS Systems Manager console at [https://console.aws.amazon.com/systems-manager/](https://console.aws.amazon.com/systems-manager/).

1. In the navigation pane, choose **Quick Setup**.

1. Choose **Settings**.

1. In the **Delegated administrator for Quick Setup** section, choose **Deregister** from the **Actions** dropdown.

1. Select **Confirm**.

# Learn Quick Setup terminology and details
<a name="quick-setup-using"></a>

Quick Setup, a tool in AWS Systems Manager, displays the results of all configuration managers you've created across all AWS Regions in the **Configuration managers** table on the Quick Setup home page. From this page, you can **View details** of each configuration, delete configurations from the **Actions** drop down, or **Create** configurations. The **Configuration managers** table contains the following information:
+ **Name** – The name of the configuration manager if provided when created.
+ **Configuration type** – The configuration type chosen when creating the configuration. 
+ **Version** – The version of the configuration type currently deployed.
+ **Organizational units** – Displays the organizational units (OUs) that the configuration is deployed to if you chose a **Custom** set of targets. Organizational units and custom targets are only available to the management account of your organization. The management account is the account that you use to create an organization in AWS Organizations.
+ **Deployment type** – Indicates whether the deployment applies to the entire organization (`Organizational`) or only your account (`Local`).
+ **Regions** – The Regions that the configuration is deployed to if you chose a **Custom** set of targets or targets within your **Current account**. 
+ **Deployment status** – The deployment status indicates if AWS CloudFormation successfully deployed the target or stack instance. The target and stack instances contain the configuration options that you chose during configuration creation.
+ **Association status** – The association status is the state of all associations created by the configuration that you created. The associations for all targets must run successfully; otherwise, the status is **Failed**.

  Quick Setup creates and runs a State Manager association for each configuration target. State Manager is a tool in AWS Systems Manager.

To view configurations deployed to the Region you're currently browsing, select the **Configurations** tab.

## Configuration details
<a name="quick-setup-details"></a>

The **Configuration details** page displays information about the deployment of the configuration and its related associations. From this page, you can edit configuration options, update targets, or delete the configuration. You can also view the details of each configuration deployment to get more information about the associations. 

Depending on the type of configuration, one or more of the following status graphs are displayed:

**Configuration deployment status**  
Displays the number of deployments that have succeeded, failed, or are running or pending. Deployments occur in the specified target accounts and Regions that contain nodes affected by the configuration. 

**Configuration association status**  
Displays the number of State Manager associations that have succeeded, failed, or are pending. Quick Setup creates an association in each deployment for the configuration options selected.

**Setup status**  
Displays the number of actions performed by the configuration type and their current statuses. 

**Resource compliance**  
Displays the number of resources that are compliant to the configurations specified policy.

The **Configuration details** table displays information about the deployment of your configuration. You can view more details about each deployment by selecting the deployment and then choosing **View details**. The details page of each deployment displays the associations deployed to the nodes in that deployment.

## Editing and deleting your configuration
<a name="quick-setup-edit-delete"></a>

You can edit configuration options of a configuration from the **Configuration details** page by choosing **Actions** and then **Edit configuration options**. When you add new options to the configuration, Quick Setup runs your deployments and creates new associations. When you remove options from a configuration, Quick Setup runs your deployments and removes any related associations.

**Note**  
You can edit Quick Setup configurations for your account at anytime. To edit an **Organization** configuration, the **Configuration status** must be **Success** or **Failed**. 

You can also update the targets included in your configurations by choosing **Actions** and **Add OUs**, **Add Regions**, **Remove OUs**, or **Remove Regions**. If your account isn't configured as the management account or you created the configuration for only the current account, you can't update the target organizational units (OUs). Removing a Region or OU removes the associations from those Regions or OUs. 

Periodically, Quick Setup releases new versions of configurations. You can select the **Upgrade configuration** option to upgrade your configuration to the latest version.

You can delete a configuration from Quick Setup by choosing the configuration, then **Actions**, and then **Delete configuration**. Or, you can delete the configuration from the **Configuration details** page under the **Actions** dropdown and then **Delete configuration**. Quick Setup then prompts you to **Remove all OUs and Regions** which might take some time to complete. Deleting a configuration also deletes all related associations. This two-step deletion process removes all deployed resources from all accounts and Regions and then deletes the configuration.

## Configuration compliance
<a name="quick-setup-compliance"></a>

You can view whether your instances are compliant with the associations created by your configurations in either Explorer or Compliance, which are both tools in AWS Systems Manager. To learn more about compliance, see [Learn details about Compliance](compliance-about.md). To learn more about viewing compliance in Explorer, see [AWS Systems Manager Explorer](Explorer.md).

# Using the Quick Setup API to manage configurations and deployments
<a name="quick-setup-api"></a>

You can use the API provided by Quick Setup to create and manage configurations and deployments using the AWS CLI or your preferred SDK. You can also use CloudFormation to create a configuration manager resource that deploys configurations. Using the API, you create configuration managers that deploy configuration *definitions*. Configuration definitions contain all of the necessary information to deploy a particular configuration type. For more information about the Quick Setup API, see the [Quick Setup API Reference](https://docs.aws.amazon.com/quick-setup/latest/APIReference/).

The following examples demonstrate how to create configuration managers using the AWS CLI and CloudFormation.

------
#### [ AWS CLI ]

```
aws ssm-quicksetup create-configuration-manager \
--name configuration manager name \
--description Description of your configuration manager
--configuration-definitions JSON string containing configuration defintion
```

The following is an example JSON string containing a configuration definition for patch policy.

```
'{"Type":"AWSQuickSetupType-PatchPolicy","LocalDeploymentAdministrationRoleArn":"arn:aws:iam::123456789012:role/AWS-QuickSetup-StackSet-Local-AdministrationRole","LocalDeploymentExecutionRoleName":"AWS-QuickSetup-StackSet-Local-ExecutionRole","Parameters":{"ConfigurationOptionsInstallNextInterval":"true","ConfigurationOptionsInstallValue":"cron(0 2 ? * SAT#1 *)","ConfigurationOptionsPatchOperation":"ScanAndInstall","ConfigurationOptionsScanNextInterval":"false","ConfigurationOptionsScanValue":"cron(0 1 * * ? *)","HasDeletedBaseline":"false","IsPolicyAttachAllowed":"true","OutputBucketRegion":"","OutputLogEnableS3":"false","OutputS3BucketName":"","OutputS3KeyPrefix":"","PatchBaselineRegion":"us-east-1","PatchBaselineUseDefault":"custom","PatchPolicyName":"dev-patch-policy","RateControlConcurrency":"5","RateControlErrorThreshold":"0%","RebootOption":"RebootIfNeeded","ResourceGroupName":"","SelectedPatchBaselines":"{\"ALMA_LINUX\":{\"value\":\"arn:aws:ssm:us-east-1:123456789012:patchbaseline/pb-0cb0c4966f86b059b\",\"label\":\"AWS-AlmaLinuxDefaultPatchBaseline\",\"description\":\"Default Patch Baseline for Alma Linux Provided by AWS.\",\"disabled\":false},\"AMAZON_LINUX_2\":{\"value\":\"arn:aws:ssm:us-east-1:123456789012:patchbaseline/pb-0be8c61cde3be63f3\",\"label\":\"AWS-AmazonLinux2DefaultPatchBaseline\",\"description\":\"Baseline containing all Security and Bugfix updates approved for Amazon Linux 2 instances\",\"disabled\":false},\"AMAZON_LINUX_2023\":{\"value\":\"arn:aws:ssm:us-east-1:123456789012:patchbaseline/pb-05c9c9bf778d4c4d0\",\"label\":\"AWS-AmazonLinux2023DefaultPatchBaseline\",\"description\":\"Default Patch Baseline for Amazon Linux 2023 Provided by AWS.\",\"disabled\":false},\"DEBIAN\":{\"value\":\"arn:aws:ssm:us-east-1:123456789012:patchbaseline/pb-09a5f8eb62bde80b1\",\"label\":\"AWS-DebianDefaultPatchBaseline\",\"description\":\"Default Patch Baseline for Debian Provided by AWS.\",\"disabled\":false},\"MACOS\":{\"value\":\"arn:aws:ssm:us-east-1:123456789012:patchbaseline/pb-0ee4f94581368c0d4\",\"label\":\"AWS-MacOSDefaultPatchBaseline\",\"description\":\"Default Patch Baseline for MacOS Provided by AWS.\",\"disabled\":false},\"ORACLE_LINUX\":{\"value\":\"arn:aws:ssm:us-east-1:123456789012:patchbaseline/pb-06bff38e95fe85c02\",\"label\":\"AWS-OracleLinuxDefaultPatchBaseline\",\"description\":\"Default Patch Baseline for Oracle Linux Server Provided by AWS.\",\"disabled\":false},\"REDHAT_ENTERPRISE_LINUX\":{\"value\":\"arn:aws:ssm:us-east-1:123456789012:patchbaseline/pb-0cbb3a633de00f07c\",\"label\":\"AWS-RedHatDefaultPatchBaseline\",\"description\":\"Default Patch Baseline for Redhat Enterprise Linux Provided by AWS.\",\"disabled\":false},\"ROCKY_LINUX\":{\"value\":\"arn:aws:ssm:us-east-1:123456789012:patchbaseline/pb-03ec98bc512aa3ac0\",\"label\":\"AWS-RockyLinuxDefaultPatchBaseline\",\"description\":\"Default Patch Baseline for Rocky Linux Provided by AWS.\",\"disabled\":false},\"UBUNTU\":{\"value\":\"pb-06e3563bd35503f2b\",\"label\":\"custom-UbuntuServer-Blog-Baseline\",\"description\":\"Default Patch Baseline for Ubuntu Provided by AWS.\",\"disabled\":false},\"WINDOWS\":{\"value\":\"pb-016889927b2bb8542\",\"label\":\"custom-WindowsServer-Blog-Baseline\",\"disabled\":false}}","TargetInstances":"","TargetOrganizationalUnits":"ou-9utf-example","TargetRegions":"us-east-1,us-east-2","TargetTagKey":"Patch","TargetTagValue":"true","TargetType":"Tags"}}' \
```

------
#### [ CloudFormation ]

```
AWSTemplateFormatVersion: '2010-09-09'
Resources:
SSMQuickSetupTestConfigurationManager:
Type: "AWS::SSMQuickSetup::ConfigurationManager"
Properties:
    Name: "MyQuickSetup"
    Description: "Test configuration manager"
    ConfigurationDefinitions:
    - Type: "AWSQuickSetupType-CFGRecording"
      Parameters:
        TargetAccounts:
            Ref: AWS::AccountId
        TargetRegions:
            Ref: AWS::Region
        LocalDeploymentAdministrationRoleArn: !Sub "arn:aws:iam::${AWS::AccountId}:role/AWS-QuickSetup-StackSet-ContractTest-AdministrationRole"
        LocalDeploymentExecutionRoleName: "AWS-QuickSetup-StackSet-ContractTest-ExecutionRole"
    Tags:
        foo1: "bar1"
```

------

# Supported Quick Setup configuration types
<a name="quick-setup-config-types"></a>

**Supported configuration types**  
Quick Setup walks you through configuring operational best practices for a number of Systems Manager and other AWS services, and automatically deploying those configurations. The Quick Setup dashboard displays a real-time view of your configuration deployment status. 

You can use Quick Setup in an individual AWS account or across multiple AWS accounts and Regions by integrating with AWS Organizations. Using Quick Setup across multiple accounts helps to ensure that your organization maintains consistent configurations.

Quick Setup provides support for the following configuration types.
+ [Set up Amazon EC2 host management using Quick Setup](quick-setup-host-management.md)
+ [Set up the Default Host Management Configuration for an organization using Quick Setup](quick-setup-default-host-management-configuration.md)
+ [Create an AWS Config configuration recorder using Quick Setup](quick-setup-config.md)
+ [Deploy AWS Config conformance pack using Quick Setup](quick-setup-cpack.md)
+ [Configure patching for instances in an organization using a Quick Setup patch policy](quick-setup-patch-manager.md)
+ [Change Manager organization setup](change-manager-organization-setup.md)
+ [Set up DevOps Guru using Quick Setup](quick-setup-devops.md)
+ [Deploy Distributor packages using Quick Setup](quick-setup-distributor.md)
+ [Stop and start EC2 instances automatically on a schedule using Quick Setup](quick-setup-scheduler.md)
+ [OpsCenter organization setup](OpsCenter-quick-setup-cross-account.md)
+ [Configure AWS Resource Explorer using Quick Setup](Resource-explorer-quick-setup.md)

# Set up Amazon EC2 host management using Quick Setup
<a name="quick-setup-host-management"></a>

Use Quick Setup, a tool in AWS Systems Manager, to quickly configure required security roles and commonly used Systems Manager tools on your Amazon Elastic Compute Cloud (Amazon EC2) instances. You can use Quick Setup in an individual account or across multiple accounts and AWS Regions by integrating with AWS Organizations. These tools help you manage and monitor the health of your instances while providing the minimum required permissions to get started. 

If you're unfamiliar with Systems Manager services and features, we recommend that you review the *AWS Systems Manager User Guide* before creating a configuration with Quick Setup. For more information about Systems Manager, see [What is AWS Systems Manager?](what-is-systems-manager.md).

**Important**  
Quick Setup might not be the right tool to use for EC2 management if either of the following applies to you:  
You’re trying to create an EC2 instance for the first time to try out AWS capabilities.
You’re still new to EC2 instance management.
Instead, we recommend that you explore the following content:   
[Getting Started with Amazon EC2](https://aws.amazon.com/ec2/getting-started)
[Launch an instance using the new launch instance wizard](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-launch-instance-wizard.html) in the *Amazon EC2 User Guide*
[Tutorial: Get started with Amazon EC2 Linux instances](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/EC2_GetStarted.html) in the *Amazon EC2 User Guide*
If you’re already familiar with EC2 instance management and want to streamline configuration and management for multiple EC2 instances, use Quick Setup. Whether your organization has dozens, thousands, or millions of EC2 instances, use the following Quick Setup procedure to configure multiple options for them, all at once.

**Note**  
This configuration type lets you set multiple options for an entire organization defined in AWS Organizations, only some organizational accounts and Regions, or a single account. One of these options is to check for and apply updates to SSM Agent every two weeks. If you are an organization administrator, you can also choose to update *all* EC2 instances in your organization with agent updates every two weeks using the Default Host Management Configuration type. For information, see [Set up the Default Host Management Configuration for an organization using Quick Setup](quick-setup-default-host-management-configuration.md).

## Configuring host management options for EC2 instances
<a name="host-management-configuration"></a>

To set up host management, perform the following tasks in the AWS Systems Manager Quick Setup console.

**To open the Host Management configuration page**

1. Open the AWS Systems Manager console at [https://console.aws.amazon.com/systems-manager/](https://console.aws.amazon.com/systems-manager/).

1. In the navigation pane, choose **Quick Setup**.

1. On the **Host Management** card, choose **Create**.
**Tip**  
If you already have one or more configurations in your account, first choose the **Library** tab or the **Create** button in the **Configurations** section to view the cards.

**To configure Systems Manager host management options**
+ To configure Systems Manager functionality, in the **Configuration options** section, choose the options in the **Systems Manager** group that you want to enable for your configuration:

     
**Update Systems Manager (SSM) Agent every two weeks**  
Enables Systems Manager to check every two weeks for a new version of the agent. If there is a new version, then Systems Manager automatically updates the agent on your managed node to the latest released version. Quick Setup doesn't install the agent on instances where it's not already present. For information about which AMIs have SSM Agent preinstalled, see [Find AMIs with the SSM Agent preinstalled](ami-preinstalled-agent.md).  
We encourage you to choose this option to ensure that your nodes are always running the most up-to-date version of SSM Agent. For more information about SSM Agent, including information about how to manually install the agent, see [Working with SSM Agent](ssm-agent.md).  
**Collect inventory from your instances every 30 minutes**  
Enables Quick Setup to configure collection of the following types of metadata:  
  + **AWS components** – EC2 driver, agents, versions, and more.
  + **Applications** – Application names, publishers, versions, and more.
  + **Node details** – System name, operating system (OS) name, OS version, last boot, DNS, domain, work group, OS architecture, and more.
  + **Network configuration** – IP address, MAC address, DNS, gateway, subnet mask, and more. 
  + **Services** – Name, display name, status, dependent services, service type, start type, and more (Windows Server nodes only).
  + **Windows roles** – Name, display name, path, feature type, installed state, and more (Windows Server nodes only).
  + **Windows updates** – Hotfix ID, installed by, installed date, and more (Windows Server nodes only).
For more information about Inventory, a tool in AWS Systems Manager, see [AWS Systems Manager Inventory](systems-manager-inventory.md).  
The **Inventory collection** option can take up to 10 minutes to complete, even if you only selected a few nodes.  
**Scan instances for missing patches daily**  
Enables Patch Manager, a tool in Systems Manager, to scan your nodes daily and generate a report in the **Compliance** page. The report shows how many nodes are patch-compliant according to the *default patch baseline*. The report includes a list of each node and its compliance status.   
For information about patching operations and patch baselines, see [AWS Systems Manager Patch Manager](patch-manager.md).   
For information about patch compliance, see the Systems Manager [Compliance](https://console.aws.amazon.com/systems-manager/compliance) page.  
For information about patching managed nodes in multiple accounts and Regions in one configuration, see [Patch policy configurations in Quick Setup](patch-manager-policies.md) and [Configure patching for instances in an organization using a Quick Setup patch policy](quick-setup-patch-manager.md).  
Systems Manager supports several methods for scanning managed nodes for patch compliance. If you implement more than one of these methods at a time, the patch compliance information you see is always the result of the most recent scan. Results from previous scans are overwritten. If the scanning methods use different patch baselines, with different approval rules, the patch compliance information can change unexpectedly. For more information, see [Identifying the execution that created patch compliance data](patch-manager-compliance-data-overwrites.md).

**To configure Amazon CloudWatch host management options**
+ To configure CloudWatch functionality, in the **Configuration options** section, choose the options in the **Amazon CloudWatch** group that you want to enable for your configuration:

     
**Install and configure the CloudWatch agent**  
Installs the basic configuration of the unified CloudWatch agent on your Amazon EC2 instances. The agent collects metrics and log files from your instances for Amazon CloudWatch. This information is consolidated so you can quickly determine the health of your instances. For more information about the CloudWatch agent basic configuration, see [CloudWatch agent predefined metric sets](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/create-cloudwatch-agent-configuration-file-wizard.html#cloudwatch-agent-preset-metrics). There might be added cost. For more information, see [Amazon CloudWatch pricing](https://aws.amazon.com/cloudwatch/pricing/).  
**Update the CloudWatch agent once every 30 days**  
Enables Systems Manager to check every 30 days for a new version of the CloudWatch agent. If there is a new version, Systems Manager updates the agent on your instance. We encourage you to choose this option to ensure that your instances are always running the most up-to-date version of the CloudWatch agent.

**To configure Amazon EC2 Launch Agent host management options**
+ To configure Amazon EC2 Launch Agent functionality, in the **Configuration options** section, choose the options in the ** Amazon EC2 Launch Agent** group that you want to enable for your configuration:

     
**Update the EC2 launch agent once every 30 days**  
Enables Systems Manager to check every 30 days for a new version of the launch agent installed on your instance. If a new version is available, Systems Manager updates the agent on your instance. We encourage you to choose this option to ensure that your instances are always running the most up-to-date version of the applicable launch agent. For Amazon EC2 Windows instances, this option supports EC2Launch, EC2Launch v2, and EC2Config. For Amazon EC2 Linux instances, this option supports `cloud-init`. For Amazon EC2 Mac instances, this option supports `ec2-macos-init`. Quick Setup doesn't support updating launch agents that are installed on operating systems not supported by the launch agent, or on AL2023.  
For more information about these initialization agents see the following topics:  
  +  [Configure a Windows instance using EC2Launch v2](https://docs.aws.amazon.com/AWSEC2/latest/WindowsGuide/ec2launch-v2.html) 
  +  [Configure a Windows instance using EC2Launch](https://docs.aws.amazon.com/AWSEC2/latest/WindowsGuide/ec2launch.html) 
  +  [Configure a Windows instance using the EC2Config service](https://docs.aws.amazon.com/AWSEC2/latest/WindowsGuide/ec2config-service.html) 
  +  [cloud-init Documentation](https://cloudinit.readthedocs.io/en/22.2.2/index.html) 
  +  [ec2-macos-init](https://github.com/aws/ec2-macos-init) 

**To select the EC2 instances to be updated by the host management configuration**
+ In the **Targets** section, choose the method to determine the accounts and Regions where the configuration is to be deployed:
**Note**  
You can't create multiple Quick Setup Host Management configurations that target the same AWS Region.

------
#### [ Entire organization ]

  Your configuration is deployed to all organizational units (OUs) and AWS Regions in your organization.

**Note**  
The **Entire organization** option is only available if you're configuring host management from your organization's management account.

------
#### [ Custom ]

  1. In the **Target OUs** section, select the OUs where you want to deploy this host management configuration.

  1. In the **Target Regions** section, select the Regions where you want to deploy this host management configuration.

------
#### [ Current account ]

  Choose one of the Region options and follow the steps for that option.

   

**Current Region**  
Choose how to target instances in the current Region only:  
  + **All instances** – The host management configuration automatically targets every EC2 in the current Region.
  + **Tag** – Choose **Add** and enter the key and optional value that is added to the instances to be targeted.
  + **Resource group** – For **Resource group**, select an existing resource group that contains the EC2 instances to be targeted.
  + **Manual** – In the **Instances** section, select the check box of each EC2 instance to be targeted.

**Choose Regions**  
Choose how to target instances in the Region you specify by choosing one of the following:  
  + **All instances** – All instances in the Regions you specify are targeted.
  + **Tag** – Choose **Add** and enter the key and optional value that has been added to the instances to be targeted.
In the **Target Regions** section, select the Regions where you want to deploy this host management configuration.

------

**To specify an instance profile option**
+ ***Entire organization** and **Custom** targets only.*

  In the **Instance profile options** section, choose whether you want to add the required IAM policies to the existing instance profiles attached to your instances, or to allow Quick Setup to create the IAM policies and instance profiles with the permissions needed for the configuration you choose.

After specifying all your configuration choices, choose **Create**.

# Set up the Default Host Management Configuration for an organization using Quick Setup
<a name="quick-setup-default-host-management-configuration"></a>

With Quick Setup, a tool in AWS Systems Manager, you can activate Default Host Management Configuration for all accounts and Regions that have been added to your organization in AWS Organizations. This ensures that SSM Agent is kept up to date on all Amazon Elastic Compute Cloud (EC2) instances in the organization, and that they can connect to Systems Manager.

**Before you begin**  
Ensure that the following requirements are met before enabling this setting.
+ The latest version of SSM Agent is already installed on all EC2 instances to be managed in your organization.
+ Your EC2 instances to be managed are using Instance Metadata Service Version 2 (IMDSv2).
+ You are signed in to the management account for your organization, as specified in AWS Organizations, using an AWS Identity and Access Management (IAM) identity (user, role, or group) with administrator permissions.

**Using the default EC2 instance management role**  
Default Host Management Configuration makes use of the `default-ec2-instance-management-role` service setting for Systems Manager. This is a role with permissions that you want made available to all accounts in your organization to allow communication between SSM Agent on the instance and the Systems Manager service in the cloud.

If you have already set this role using the [https://docs.aws.amazon.com/cli/latest/reference/ssm/update-service-setting.html](https://docs.aws.amazon.com/cli/latest/reference/ssm/update-service-setting.html) CLI command, Default Host Management Configuration uses that role. If you have not set this role yet, Quick Setup will create and apply the role for you. 

To check whether this role has already been specified for your organization, use the [https://docs.aws.amazon.com/cli/latest/reference/ssm/get-service-setting.html](https://docs.aws.amazon.com/cli/latest/reference/ssm/get-service-setting.html) command.

## Enable automatic updates of SSM Agent every two weeks
<a name="dhmc-enable-automatic-updates"></a>

Use the following procedure to enable the Default Host Management Configuration option for your entire AWS Organizations organization.

**To enable automatic updates of SSM Agent every two weeks**

1. Open the AWS Systems Manager console at [https://console.aws.amazon.com/systems-manager/](https://console.aws.amazon.com/systems-manager/).

1. In the navigation pane, choose **Quick Setup**.

1. On the **Default Host Management Configuration** card, choose **Create**.
**Tip**  
If you already have one or more configurations in your account, first choose the **Library** tab or the **Create** button in the **Configurations** section to view the cards.

1. In the **Configuration options** section, select **Enable automatic updates of SSM Agent every two weeks**.

1. Choose **Create**

# Create an AWS Config configuration recorder using Quick Setup
<a name="quick-setup-config"></a>

With Quick Setup, a tool in AWS Systems Manager, you can quickly create a configuration recorder powered by AWS Config. Use the configuration recorder to detect changes in your resource configurations and capture the changes as configuration items. If you're unfamiliar with AWS Config, we recommend learning more about the service by reviewing the content in the *AWS Config Developer Guide* before creating a configuration with Quick Setup. For more information about AWS Config, see [What is AWS Config?](https://docs.aws.amazon.com/config/latest/developerguide/WhatIsConfig.html) in the *AWS Config Developer Guide*.

By default, the configuration recorder records all supported resources in the AWS Region where AWS Config is running. You can customize the configuration so that only the resource types you specify are recorded. For more information, see [Selecting which resources AWS Config records](https://docs.aws.amazon.com/config/latest/developerguide/select-resources.html) in the *AWS Config Developer Guide*.

You're charged service usage fees when AWS Config starts recording configurations. For pricing information, see [AWS Config pricing](https://aws.amazon.com/config/pricing/).

**Note**  
If you've already created a configuration recorder, Quick Setup doesn't stop recording or make any changes to resource types that you're already recording. If you choose to record additional resource types using Quick Setup, the service appends them to your existing recorder groups. Deleting the Quick Setup **Config recording** configuration type doesn't stop the configuration recorder. Changes continue to be recorded, and service usage fees apply until you stop the configuration recorder. To learn more about managing the configuration recorder, see [Managing the Configuration Recorder](https://docs.aws.amazon.com/config/latest/developerguide/stop-start-recorder.html) in the *AWS Config Developer Guide*.

To set up AWS Config recording, perform the following tasks in the AWS Systems Manager console.

**To set up AWS Config recording with Quick Setup**

1. Open the AWS Systems Manager console at [https://console.aws.amazon.com/systems-manager/](https://console.aws.amazon.com/systems-manager/).

1. In the navigation pane, choose **Quick Setup**.

1. On the **Config Recording** card, choose **Create**.
**Tip**  
If you already have one or more configurations in your account, first choose the **Library** tab or the **Create** button in the **Configurations** section to view the cards.

1. In the **Configuration options** section, do the following:

   1. For **Choose the AWS resource types to record**, specify whether to record all supported resources or only the resource types you choose.

   1. For **Delivery settings, specify whether to create a new Amazon Simple Storage Service (Amazon S3) bucket, or choose an existing bucket to send configuration snapshots to. **

   1. For **Notification options**, choose the notification option you prefer. AWS Config uses Amazon Simple Notification Service (Amazon SNS) to notify you about important AWS Config events related to your resources. If you choose the **Use existing SNS topics** option, you must provide the AWS account ID and name of the existing Amazon SNS topic in that account you want to use. If you target multiple AWS Regions, the topic names must be identical in each Region.

1. In the **Schedule** section, choose how frequently you want Quick Setup to remediate changes made to resources that differ from your configuration. The **Default** option runs once. If you don't want Quick Setup to remediate changes made to resources that differ from your configuration, choose **Disable remediation** under **Custom**.

1. In the **Targets** section, choose one of the following to identify the accounts and Regions for recording.
**Note**  
If you are working in a single account, options for working with organizations and organizational units (OUs) are not available. You can choose whether to apply this configuration to all AWS Regions in your account or only the Regions you select.
   + **Entire organization** – All accounts and Regions in your organization.
   + **Custom** – Only the OUs and Regions that you specify.
     + In the **Target OUs** section, select the OUs where you want to allow recording. 
     + In the **Target Regions** section, select the Regions where you want to allow recording. 
   + **Current account** – Only the Regions you specify in the account you are currently signed into are targeted. Choose one of the following:
     + **Current Region** – Only managed nodes in the Region selected in the console are targeted. 
     + **Choose Regions** – Choose the individual Regions to apply the recording configuration to.

1. Choose **Create**.

# Deploy AWS Config conformance pack using Quick Setup
<a name="quick-setup-cpack"></a>

A conformance pack is a collection of AWS Config rules and remediation actions. With Quick Setup, you can deploy a conformance pack as a single entity in an account and an AWS Region or across an organization in AWS Organizations. This helps you manage configuration compliance of your AWS resources at scale, from policy definition to auditing and aggregated reporting, by using a common framework and packaging model. 

To deploy conformance packs, perform the following tasks in the AWS Systems Manager Quick Setup console.

**Note**  
You must enable AWS Config recording before deploying this configuration. For more information, see [Conformance packs](https://docs.aws.amazon.com/config/latest/developerguide/conformance-packs.html) in the *AWS Config Developer Guide*.

**To deploy conformance packs with Quick Setup**

1. Open the AWS Systems Manager console at [https://console.aws.amazon.com/systems-manager/](https://console.aws.amazon.com/systems-manager/).

1. In the navigation pane, choose **Quick Setup**.

1. On the **Conformance Packs** card, choose **Create**.
**Tip**  
If you already have one or more configurations in your account, first choose the **Library** tab or the **Create** button in the **Configurations** section to view the cards.

1. In the **Choose conformance packs** section, choose the conformance packs you want to deploy.

1. In the **Schedule** section, choose how frequently you want Quick Setup to remediate changes made to resources that differ from your configuration. The **Default** option runs once. If you don't want Quick Setup to remediate changes made to resources that differ from your configuration, choose **Disabled** under **Custom**.

1. In the **Targets** section, choose whether to deploy conformance packs to your entire organization, some AWS Regions, or the account you're currently logged in to.

   If you choose **Entire organization**, continue to step 8.

   If you choose **Custom**, continue to step 7.

1. In the **Target Regions** section, select the check boxes of the Regions you want to deploy conformance packs to.

1. Choose **Create**.

# Configure patching for instances in an organization using a Quick Setup patch policy
<a name="quick-setup-patch-manager"></a>

With Quick Setup, a tool in AWS Systems Manager, you can create patch policies powered by Patch Manager. A patch policy defines the schedule and baseline to use when automatically patching your Amazon Elastic Compute Cloud (Amazon EC2) instances and other managed nodes. Using a single patch policy configuration, you can define patching for all accounts in multiple AWS Regions in your organization, for only the accounts and Regions you choose, or for a single account-Region pair. For more information about patch policies, see [Patch policy configurations in Quick Setup](patch-manager-policies.md).

**Prerequisite**  
To define a patch policy for a node using Quick Setup, the node must be a *managed node*. For more information about managing your nodes, see [Setting up Systems Manager unified console for an organization](systems-manager-setting-up-organizations.md).

**Important**  
**Patch compliance scanning methods** – Systems Manager supports several methods for scanning managed nodes for patch compliance. If you implement more than one of these methods at a time, the patch compliance information you see is always the result of the most recent scan. Results from previous scans are overwritten. If the scanning methods use different patch baselines, with different approval rules, the patch compliance information can change unexpectedly. For more information, see [Identifying the execution that created patch compliance data](patch-manager-compliance-data-overwrites.md).  
**Association compliance status and patch policies** – The patching status for a managed node that's under a Quick Setup patch policy matches the status of the State Manager association execution for that node. If the association execution status is `Compliant`, the patching status for the managed node is also marked `Compliant`. If the association execution status is `Non-Compliant`, the patching status for the managed node is also marked `Non-Compliant`. 

## Supported Regions for patch policy configurations
<a name="patch-policies-supported-regions"></a>

Patch policy configurations in Quick Setup are currently supported in the following Regions:
+ US East (Ohio) (us-east-2)
+ US East (N. Virginia) (us-east-1)
+ US West (N. California) (us-west-1)
+ US West (Oregon) (us-west-2)
+ Asia Pacific (Mumbai) (ap-south-1)
+ Asia Pacific (Seoul) (ap-northeast-2)
+ Asia Pacific (Singapore) (ap-southeast-1)
+ Asia Pacific (Sydney) (ap-southeast-2)
+ Asia Pacific (Tokyo) (ap-northeast-1)
+ Canada (Central) (ca-central-1)
+ Europe (Frankfurt) (eu-central-1)
+ Europe (Ireland) (eu-west-1)
+ Europe (London) (eu-west-2)
+ Europe (Paris) (eu-west-3)
+ Europe (Stockholm) (eu-north-1)
+ South America (São Paulo) (sa-east-1)

## Permissions for the patch policy S3 bucket
<a name="patch-policy-s3-bucket-permissions"></a>

When you create a patch policy, Quick Setup creates an Amazon S3 bucket that contains a file named `baseline_overrides.json`. This file stores information about the patch baselines that you specified for your patch policy.

The S3 bucket is named in the format `aws-quicksetup-patchpolicy-account-id-quick-setup-configuration-id`. 

For example: `aws-quicksetup-patchpolicy-123456789012-abcde`

If you're creating a patch policy for an organization, the bucket is created in your organization's management account. 

There are two use cases when you must provide other AWS resources with permission to access this S3 bucket using AWS Identity and Access Management (IAM) policies:
+ [Case 1: Use your own instance profile or service role with your managed nodes instead of one provided by Quick Setup](#patch-policy-instance-profile-service-role)
+ [Case 2: Use VPC endpoints to connect to Systems Manager](#patch-policy-vpc)

The permissions policy you need in either case is located in the section below, [Policy permissions for Quick Setup S3 buckets](#patch-policy-bucket-permissions).

### Case 1: Use your own instance profile or service role with your managed nodes instead of one provided by Quick Setup
<a name="patch-policy-instance-profile-service-role"></a>

Patch policy configurations include an option to **Add required IAM policies to existing instance profiles attached to your instances**. 

If you don't choose this option but want Quick Setup to patch your managed nodes using this patch policy, you must ensure that the following are implemented:
+ The IAM managed policy `AmazonSSMManagedInstanceCore` must be attached to the [IAM instance profile](setup-instance-permissions.md) or [IAM service role](hybrid-multicloud-service-role.md) that's used to provide Systems Manager permissions to your managed nodes.
+ You must add permissions to access your patch policy bucket as an inline policy to the IAM instance profile or IAM service role. You can provide wildcard access to all `aws-quicksetup-patchpolicy` buckets or only the specific bucket created for your organization or account, as shown in the earlier code samples.
+ You must tag your IAM instance profile or IAM service role with the following key-value pair.

  `Key: QSConfigId-quick-setup-configuration-id, Value: quick-setup-configuration-id`

  *quick-setup-configuration-id* represents the value of the parameter applied to the AWS CloudFormation stack that is used in creating your patch policy configuration. To retrieve this ID, do the following:

  1. Open the CloudFormation console at [https://console.aws.amazon.com/cloudformation](https://console.aws.amazon.com/cloudformation/).

  1. Select the name of the stack that is used to create your patch policy. The name is in a format such as `StackSet-AWS-QuickSetup-PatchPolicy-LA-q4bkg-52cd2f06-d0f9-499e-9818-d887cEXAMPLE`.

  1. Choose the **Parameters** tab.

  1. In the **Parameters** list, in the **Key** column, locate the key **QSConfigurationId**. In the **Value** column for its row, locate the configuration ID, such as `abcde`.

     In this example, for the tag to apply to your instance profile or service role, the key is `QSConfigId-abcde`, and the value is `abcde`.

For information about adding tags to an IAM role, see [Tagging IAM roles](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_tags_roles.html#id_tags_roles_procs-console) and [Managing tags on instance profiles (AWS CLI or AWS API)](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_tags_instance-profiles.html#id_tags_instance-profile_procs-cli-api) in the *IAM User Guide*.

### Case 2: Use VPC endpoints to connect to Systems Manager
<a name="patch-policy-vpc"></a>

If you use VPC endpoints to connect to Systems Manager, your VPC endpoint policy for S3 must allow access to your Quick Setup patch policy S3 bucket.

For information about adding permissions to a VPC endpoint policy for S3, see [Controlling access from VPC endpoints with bucket policies](https://docs.aws.amazon.com/AmazonS3/latest/userguide/example-bucket-policies-vpc-endpoint.html) in the *Amazon S3 User Guide*.

### Policy permissions for Quick Setup S3 buckets
<a name="patch-policy-bucket-permissions"></a>

You can provide wildcard access to all `aws-quicksetup-patchpolicy` buckets or only the specific bucket created for your organization or account. To provide the necessary permissions for the two cases described below, use either format.

------
#### [ All patch policy buckets ]

------
#### [ JSON ]

****  

```
{
  "Version":"2012-10-17",		 	 	 
  "Statement": [
    {
      "Sid": "AccessToAllPatchPolicyRelatedBuckets",
      "Effect": "Allow",
      "Action": "s3:GetObject",
      "Resource": "arn:aws:s3:::aws-quicksetup-patchpolicy-*"
    }
  ]
}
```

------

------
#### [ Specific patch policy bucket ]

------
#### [ JSON ]

****  

```
{
  "Version":"2012-10-17",		 	 	 
  "Statement": [
    {
      "Sid": "AccessToMyPatchPolicyRelatedBucket",
      "Effect": "Allow",
      "Action": "s3:GetObject",
      "Resource": "arn:aws:s3:::aws-quicksetup-patchpolicy-111122223333-quick-setup-configuration-id"
    }
  ]
}
```

------

**Note**  
After the patch policy configuration is created, you can locate the full name of your bucket in the S3 console. For example: `aws-quicksetup-patchpolicy-123456789012-abcde`

------

## Random patch baseline IDs in patch policy operations
<a name="qs-patch-baselines-and-compliance"></a>

Patching operations for patch policies utilize the `BaselineOverride` parameter in the `AWS-RunPatchBaseline` SSM Command document. 

When you use `AWS-RunPatchBaseline` for patching *outside* of a patch policy, you can use `BaselineOverride` to specify a list of patch baselines to use during the operation that are different from the specified defaults. You create this list in a file named `baseline_overrides.json` and manually add it to an Amazon S3 bucket that you own, as explained in [Using the BaselineOverride parameter](patch-manager-baselineoverride-parameter.md).

For patching operations based on patch policies, however, Systems Manager automatically creates an S3 bucket and adds a `baseline_overrides.json` file to it. Then, every time Quick Setup runs a patching operation (using the Run Command tool, the system generates a random ID for each patch baseline. This ID is different for every patch policy patching operation, and the patch baseline it represents is not stored or accessible to you in your account. 

As a result, you will not see the ID of the patch baseline selected in your configuration in patching logs. This applies to both AWS managed patch baselines and custom patch baselines you might have selected. The baseline ID reported in the log is instead that one that was generated for that specific patching operation.

In addition, if you attempt to view details in Patch Manager about a patch baseline that was generated with a random ID, the system reports that the patch baseline doesn't exist. This is expected behavior and can be ignored.

## Creating a patch policy
<a name="create-patch-policy"></a>

To create a patch policy, perform the following tasks in the Systems Manager console.

**To create a patch policy with Quick Setup**

1. Open the AWS Systems Manager console at [https://console.aws.amazon.com/systems-manager/](https://console.aws.amazon.com/systems-manager/).

   If you are setting up patching for an organization, make sure you are signed in to the management account for the organization. You can't set up the policy using the delegated administrator account or a member account.

1. In the navigation pane, choose **Quick Setup**.

1. On the **Patch Manager** card, choose **Create**.
**Tip**  
If you already have one or more configurations in your account, first choose the **Library** tab or the **Create** button in the **Configurations** section to view the cards.

1. For **Configuration name**, enter a name to help identify the patch policy.

1. In the **Scanning and installation** section, under **Patch operation**, choose whether the patch policy will **Scan** the specified targets or **Scan and install** patches on the specified targets.

1. Under **Scanning schedule**, choose **Use recommended defaults** or **Custom scan schedule**. The default scan schedule will scan your targets daily at 1:00 AM UTC.
   + If you choose **Custom scan schedule**, select the **Scanning frequency**.
   + If you choose **Daily**, enter the time, in UTC, that you want to scan your targets. 
   + If you choose **Custom CRON Expression**, enter the schedule as a **CRON expression**. For more information about formatting CRON expressions for Systems Manager, see [Reference: Cron and rate expressions for Systems Manager](reference-cron-and-rate-expressions.md).

     Also, select **Wait to scan targets until first CRON interval**. By default, Patch Manager immediately scans nodes as they become targets.

1. If you chose **Scan and install**, choose the **Installation schedule** to use when installing patches to the specified targets. If you choose **Use recommended defaults**, Patch Manager will install weekly patches at 2:00 AM UTC on Sunday.
   + If you choose **Custom install schedule**, select the **Installation Frequency**.
   + If you choose **Daily**, enter the time, in UTC, that you want to install updates on your targets.
   + If you choose **Custom CRON expression**, enter the schedule as a **CRON expression**. For more information about formatting CRON expressions for Systems Manager, see [Reference: Cron and rate expressions for Systems Manager](reference-cron-and-rate-expressions.md).

     Also, clear **Wait to install updates until first CRON interval** to immediately install updates on nodes as they become targets. By default, Patch Manager waits until the first CRON interval to install updates.
   + Choose **Reboot if needed** to reboot the nodes after patch installation. Rebooting after installation is recommended but can cause availability issues.

1. In the **Patch baseline** section, choose the patch baselines to use when scanning and updating your targets. 

   By default, Patch Manager uses the predefined patch baselines. For more information, see [Predefined baselines](patch-manager-predefined-and-custom-patch-baselines.md#patch-manager-baselines-pre-defined).

   If you choose **Custom patch baseline**, change the selected patch baseline for operating systems that you don't want to use a predefined AWS patch baseline.
**Note**  
If you use VPC endpoints to connect to Systems Manager, make sure your VPC endpoint policy for S3 allows access to this S3 bucket. For more information, see [Permissions for the patch policy S3 bucket](#patch-policy-s3-bucket-permissions). 
**Important**  
If you are using a [patch policy configuration](patch-manager-policies.md) in Quick Setup, updates you make to custom patch baselines are synchronized with Quick Setup once an hour.   
If a custom patch baseline that was referenced in a patch policy is deleted, a banner displays on the Quick Setup **Configuration details** page for your patch policy. The banner informs you that the patch policy references a patch baseline that no longer exists, and that subsequent patching operations will fail. In this case, return to the Quick Setup **Configurations** page, select the Patch Manager configuration , and choose **Actions**, **Edit configuration**. The deleted patch baseline name is highlighted, and you must select a new patch baseline for the affected operating system.

1. (Optional) In the **Patching log storage** section, select **Write output to S3 bucket** to store patching operation logs in an Amazon S3 bucket. 
**Note**  
If you are setting up a patch policy for an organization, the management account for your organization must have at least read-only permissions for this bucket. All organization units included in the policy must have write-access to the bucket. For information about granting bucket access to different accounts, see [Example 2: Bucket owner granting cross-account bucket permissions](https://docs.aws.amazon.com/AmazonS3/latest/userguide/example-walkthroughs-managing-access-example2.html) in the *Amazon Simple Storage Service User Guide*.

1. Choose **Browse S3** to select the bucket that you want to store patch log output in. The management account must have read access to this bucket. All non-management accounts and targets configured in the **Targets** section must have write access to the provided S3 bucket for logging.

1. In the **Targets** section, choose one of the following to identify the accounts and Regions for this patch policy operation.
**Note**  
If you are working in a single account, options for working with organizations and organizational units (OUs) are not available. You can choose whether to apply this configuration to all AWS Regions in your account or only the Regions you select.  
If you previously specified a Home Region for you account and haven't onboarded to the new Quick Setup console experience, you can't exclude that Region from the **Targets** configuration.
   + **Entire organization** – All accounts and Regions in your organization.
   + **Custom** – Only the OUs and Regions that you specify.
     + In the **Target OUs** section, select the OUs where you want to set up the patch policy. 
     + In the **Target Regions** section, select the Regions where you want to apply the patch policy. 
   + **Current account** – Only the Regions you specify in the account you are currently signed into are targeted. Choose one of the following:
     + **Current Region** – Only managed nodes in the Region selected in the console are targeted. 
     + **Choose Regions** – Choose the individual Regions to apply the patch policy to.

1. For **Choose how you want to target instances**, choose one of the following to identify the nodes to patch: 
   + **All managed nodes** – All managed nodes in the selected OUs and Regions.
   + **Specify the resource group** – Choose the name of a resource group from the list to target its associated resources.
**Note**  
Currently, selecting resource groups is supported only for single account configurations. To patch resources in multiple accounts, choose a different targeting option.
   + **Specify a node tag** – Only nodes tagged with the key-value pair that you specify are patched in all accounts and Regions you have targeted. 
   + **Manual** – Choose managed nodes from all specified accounts and Regions manually from a list.
**Note**  
This option currently supports only Amazon EC2 instances. You can add a maximum of 25 instances manually in a patch policy configuration.

1. In the **Rate control** section, do the following:
   + For **Concurrency**, enter a number or percentage of nodes to run the patch policy on at the same time.
   + For **Error threshold**, enter the number or percentage of nodes that can experience an error before the patch policy fails.

1. (Optional) Select the **Add required IAM policies to existing instance profiles attached to your instances** check box.

   This selection applies the IAM policies created by this Quick Setup configuration to nodes that already have an instance profile attached (EC2 instances) or a service role attached (hybrid-activated nodes). We recommend this selection when your managed nodes already have an instance profile or service role attached, but it doesn't contain all the permissions required for working with Systems Manager.

   Your selection here is applied to managed nodes created later in the accounts and Regions that this patch policy configuration applies to.
**Important**  
If you don't select this check box but want Quick Setup to patch your managed nodes using this patch policy, you must do the following:  
Add permissions to your [IAM instance profile](setup-instance-permissions.md) or [IAM service role](hybrid-multicloud-service-role.md) to access the S3 bucket created for your patch policy  
Tag your IAM instance profile or IAM service role with a specific key-value pair.  
For information, see [Case 1: Use your own instance profile or service role with your managed nodes instead of one provided by Quick Setup](#patch-policy-instance-profile-service-role).

1. Choose **Create**.

   To review patching status after the patch policy is created, you can access the configuration from the [https://console.aws.amazon.com/systems-manager/quick-setup](https://console.aws.amazon.com/systems-manager/quick-setup) page.

# Set up DevOps Guru using Quick Setup
<a name="quick-setup-devops"></a>

You can quickly configure DevOps Guru options by using Quick Setup. Amazon DevOps Guru is a machine learning (ML) powered service that makes it easy to improve an application's operational performance and availability. DevOps Guru detects behaviors that are different from normal operating patterns so you can identify operational issues long before they impact your customers. DevOps Guru automatically ingests operational data from your AWS applications and provides a single dashboard to visualize issues in your operational data. You can get started with DevOps Guru to improve application availability and reliability with no manual setup or machine learning expertise.

Configuring DevOps Guru with Quick Setup is available in the following AWS Regions:
+ US East (N. Virginia)
+ US East (Ohio)
+ US West (Oregon)
+ Europe (Frankfurt)
+ Europe (Ireland)
+ Europe (Stockholm)
+ Asia Pacific (Singapore)
+ Asia Pacific (Sydney)
+ Asia Pacific (Tokyo)

For pricing information, see [Amazon DevOps Guru pricing](https://aws.amazon.com/devops-guru/pricing/).

To set up DevOps Guru, perform the following tasks in the AWS Systems Manager Quick Setup console.

**To set up DevOps Guru with Quick Setup**

1. Open the AWS Systems Manager console at [https://console.aws.amazon.com/systems-manager/](https://console.aws.amazon.com/systems-manager/).

1. In the navigation pane, choose **Quick Setup**.

1. On the **DevOps Guru** card, choose **Create**.
**Tip**  
If you already have one or more configurations in your account, first choose the **Library** tab or the **Create** button in the **Configurations** section to view the cards.

1. In the **Configuration options** section, choose the AWS resource types you want to analyze and your notification preferences.

   If you don't select the **Analyze all AWS resources in all the accounts in my organization** option, you can choose AWS resources to analyze later in the DevOps Guru console. DevOps Guru analyzes different AWS resource types (such as Amazon Simple Storage Service (Amazon S3) buckets and Amazon Elastic Compute Cloud (Amazon EC2) instances), which are categorized into two pricing groups. You pay for the AWS resource hours analyzed, for each active resource. A resource is only active if it produces metrics, events, or log entries within an hour. The rate you're charged for a specific AWS resource type depends on the price group.

   If you select the **Enable SNS notifications** option, an Amazon Simple Notification Service (Amazon SNS) topic is created in each AWS account in the organizational units (OUs) you target with your configuration. DevOps Guru uses the topic to notify you about important DevOps Guru events, such as the creation of a new insight. If you don't enable this option, you can add a topic later in the DevOps Guru console.

   If you select the **Enable AWS Systems Manager OpsItems** option, operational work items (OpsItems) will be created for related Amazon EventBridge events and Amazon CloudWatch alarms.

1. In the **Schedule** section, choose how frequently you want Quick Setup to remediate changes made to resources that differ from your configuration. The **Default** option runs once. If you don't want Quick Setup to remediate changes made to resources that differ from your configuration, choose **Disabled** under **Custom**.

1. In the **Targets** section, choose whether to allow DevOps Guru to analyze resources in some of your organizational units (OUs), or the account you're currently logged in to.

   If you choose **Custom**, continue to step 8.

   If you choose **Current account**, continue to step 9.

1. In the **Target OUs** and **Target Regions** sections, select the check boxes of the OUs and Regions where you want to use DevOps Guru.

1. Choose the Regions where you want to use DevOps Guru in the current account.

1. Choose **Create**.

# Deploy Distributor packages using Quick Setup
<a name="quick-setup-distributor"></a>

Distributor is a tool in AWS Systems Manager. A Distributor package is a collection of installable software or assets that can be deployed as a single entity. With Quick Setup, you can deploy a Distributor package in an AWS account and an AWS Region or across an organization in AWS Organizations. Currently, only the EC2Launch v2 agent, Amazon Elastic File System (Amazon EFS) utilities package and Amazon CloudWatch agent can be deployed with Quick Setup. For more information about Distributor, see [AWS Systems Manager Distributor](distributor.md).

To deploy Distributor packages, perform the following tasks in the AWS Systems Manager Quick Setup console.

**To deploy Distributor packages with Quick Setup**

1. Open the AWS Systems Manager console at [https://console.aws.amazon.com/systems-manager/](https://console.aws.amazon.com/systems-manager/).

1. In the navigation pane, choose **Quick Setup**.

1. On the **Distributor** card, choose **Create**.
**Tip**  
If you already have one or more configurations in your account, first choose the **Library** tab or the **Create** button in the **Configurations** section to view the cards.

1. In the **Configuration options** section, choose the package you want to deploy.

1. In the **Targets** section, choose whether to deploy the package to your entire organization, some of your organizational units (OUs), or the account you're currently logged in to.

   If you choose **Entire organization**, continue to step 8.

   If you choose **Custom**, continue to step 7.

1. In the **Target OUs** section, select the check boxes of the OUs and Regions you want to deploy the package to.

1. Choose **Create**.

# Stop and start EC2 instances automatically on a schedule using Quick Setup
<a name="quick-setup-scheduler"></a>

With Quick Setup, a tool in AWS Systems Manager, you can configure Resource Scheduler to automate the starting and stopping of Amazon Elastic Compute Cloud (Amazon EC2) instances.

This Quick Setup configuration helps you reduce operational costs by starting and stopping instances according to the schedule that you specify. This tool helps you avoid incurring unnecessary costs for running instances when they’re not needed. 

For example, you currently might leave your instances running constantly, even though they’re only used 10 hours a day, 5 days a week. Instead, you can schedule your instances to stop every day after business hours. As a result, there would be 70 percent savings for those instances because the running time is reduced from 168 hours to 50 hours. There is no cost to use Quick Setup. However, costs can be incurred by the resources you set up and the usage limits with no fees for the services used to set up your configuration.

Using Resource Scheduler, you can choose to automatically stop and start instances across multiple AWS Regions and AWS accounts according to a schedule you define. The Quick Setup configuration targets Amazon EC2 instances using the tag key and value that you specify. Only the instances with a tag matching the value that you specify in your configuration are stopped or started by Resource Scheduler. Note that if the Amazon EBS volumes attached to the instance are encrypted, you must add the required permissions for the AWS KMS key to the IAM role for Resource Scheduler to start the instance.

**Maximum instances per configuration**  
An individual configuration supports scheduling up to 5,000 instances per Region. If your case requires more than 5,000 instances to be scheduled in a given Region, you must create multiple configurations. Tag your instances accordingly so each configuration is managing up to 5,000 instances. When creating multiple Resource Scheduler Quick Setup configurations, you must specify different tag key values. For example, one configuration can use the tag key `Environment` with the value `Production`, while another uses `Environment` and `Development`.

**Scheduling behaviors**  
The following points describe certain behaviors of schedule configurations:
+ Resource Scheduler starts the tagged instances only if they are in the `Stopped` state. Similarly, instances are only stopped if they are in the `running` state. Resource Scheduler operates on an event driven model and only starts or stops instances at the times that you specify. For example, you create a schedule that starts instances at 9 AM. Resource Scheduler starts all instances associated with the tag you specify that are in the `Stopped` state at 9 AM. If the instances are manually stopped at a later time, Resource Scheduler will not start them again to maintain the `Running` state. Similarly, if an instance is started manually after it was stopped according to your schedule, Resource Scheduler will not stop the instance again.
+ If you create a schedule with a start time that is later in a 24-hour day than the stop time, Resource Scheduler assumes your instances are to run overnight. For example, you create a schedule that starts instances at 9 PM, and stops instances at 7 AM. Resource Scheduler starts all instances associated with the tag you specify that are in the `Stopped` state at 9 PM, and stops them at 7 AM the following day. For overnight schedules, the start time applies to the days you select for your schedule. However, the stop time applies to the following day in your schedule.
+ When you create a schedule configuration, the current state of your instances might be changed to match the requirements of the schedule.

  For example, say that today is a Wednesday, and you specify a schedule for your managed instances to start at 9 AM and stop at 5 PM on Tuesdays and Thursdays *only*. Because your current time is outside of the prescribed hours for the instances to be running, they will be stopped after the configuration is created. The instances won't run again until the next prescribed hour, 9 AM on Thursday. 

  If your instances are currently in a `Stopped` state, and you specify a schedule in which they would be running at the current time, Resource Scheduler starts them after the configuration is created.

If you delete your configuration, instances are no longer stopped and started according to the previously defined schedule. In rare cases, instances might not successfully stop or start due to API operation failures.

To set up scheduling for Amazon EC2 instances, perform the following tasks in the AWS Systems Manager Quick Setup console.

**To set up instance scheduling with Quick Setup**

1. Open the AWS Systems Manager console at [https://console.aws.amazon.com/systems-manager/](https://console.aws.amazon.com/systems-manager/).

1. In the navigation pane, choose **Quick Setup**.

1. On the **Resource Scheduler** card, choose **Create**.
**Tip**  
If you already have one or more configurations in your account, first choose the **Library** tab or the **Create** button in the **Configurations** section to view the cards.

1. In the **Instance tag** section, specify the tag key and value applied to the instances you want to associate with your schedule.

1. In the **Schedule options** section, specify the time zone, days, and times you want to start and stop your instances.

1. In the **Targets** section, choose whether to set scheduling for a **Custom** group of organizational units (OUs), or the **Current account** you're signed in to:
   + **Custom** – In the **Target OUs** section, select the OUs where you want to set up scheduling. Next, in the **Target Regions** section, select the Regions where you want to set up scheduling.
   + **Current account** – Select **Current Region** or **Choose Regions**. If you selected **Choose Regions**, choose the **Target Regions** where you want to set up scheduling.

1. Verify the schedule information in the **Summary** section.

1. Choose **Create**.

# Configure AWS Resource Explorer using Quick Setup
<a name="Resource-explorer-quick-setup"></a>

With Quick Setup, a tool in AWS Systems Manager, you can quickly configure AWS Resource Explorer to search and discover resources in your AWS account or across an entire AWS organization. You can search for your resources using metadata like names, tags, and IDs. AWS Resource Explorer provides fast responses to your search queries by using *indexes*. Resource Explorer creates and maintains indexes using a variety of data sources to gather information about resources in your AWS account. 

Quick Setup for Resource Explorer automates the index configuration process. For more information about AWS Resource Explorer, see [ What is AWS Resource Explorer?](https://docs.aws.amazon.com/resource-explorer/latest/userguide/welcome.html) in the AWS Resource Explorer User Guide.

During Quick Setup, Resource Explorer does the following: 
+ Creates an index in every AWS Region in your AWS account.
+ Updates the index in the Region you specify to be the aggregator index for the account.
+ Creates a default view in the aggregator index Region. This view has no filters so it returns all resources found in the index.

**Minimum permissions**

To perform the steps in the following procedure, you must have the following permissions:
+ **Action**: `resource-explorer-2:*` – **Resource**: no specific resource (`*`)
+ **Action**: `iam:CreateServiceLinkedRole` – **Resource**: no specific resource (`*`)

**To configure Resource Explorer**

1. Open the AWS Systems Manager console at [https://console.aws.amazon.com/systems-manager/](https://console.aws.amazon.com/systems-manager/).

1. In the navigation pane, choose **Quick Setup**.

1. On the **Resource Explorer** card, choose **Create**.

1. In the **Aggregator Index Region** section, choose which Region you want to contain the **aggregator index**. You should select the Region that is appropriate for the geographic location for your users.

1. (Optional) Select the **Replace existing aggregator indexes in Regions other than the one selected above** check box. 

1. In the **Targets** section, choose the target **organization** or specific **Organizational Units (OUs)** containing the resources you want to discover. 

1. In the **Regions** section, choose which **Regions** to include in the configuration. 

1. Review the configuration summary, and then choose **Create**. 

On the **Resource Explorer** page, you can monitor the configuration status.

# Troubleshooting Quick Setup results
<a name="quick-setup-results-troubleshooting"></a>

Use the following information to help you troubleshoot problems with Quick Setup, a tool in AWS Systems Manager. This topic includes specific tasks to resolve issues based on the type of Quick Setup issue.

**Issue: Failed deployment**  
A deployment fails if the CloudFormation stack set failed during creation. Use the following steps to investigate a deployment failure.

1. Navigate to the [AWS CloudFormation console](https://console.aws.amazon.com/cloudformation). 

1. Choose the stack created by your Quick Setup configuration. The **Stack name** includes `QuickSetup` followed by the type of configuration you chose, such as `SSMHostMgmt`. 
**Note**  
CloudFormation sometimes deletes failed stack deployments. If the stack isn't available in the **Stacks** table, choose **Deleted** from the filter list.

1. View the **Status** and **Status reason**. For more information about stack statuses, see [Stack status codes](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/cfn-console-view-stack-data-resources.html#cfn-console-view-stack-data-resources-status-codes) in the *AWS CloudFormation User Guide*. 

1. To understand the exact step that failed, view the **Events** tab and review each event's **Status**. 

1. Review [Troubleshooting](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/troubleshooting.html) in the *AWS CloudFormation User Guide*.

1. If you are unable to resolve the deployment failure using the CloudFormation troubleshooting steps, delete the configuration and reconfigure it.

**Issue: Failed association**  
The **Configuration details** table on the **Configuration details** page of your configuration shows a **Configuration status** of **Failed** if any of the associations failed during set up. Use the following steps to troubleshoot a failed association.

1. In the **Configuration details** table, choose the failed configuration and then choose **View Details**.

1. Copy the **Association name**.

1. Navigate to **State Manager** and paste the association name into the search field. 

1. Choose the association and choose the **Execution history** tab.

1. Under **Execution ID**, choose the association execution that failed.

1. The **Association execution targets** page lists all of the nodes where the association ran. Choose the **Output** button for an execution that failed to run.

1. In the **Output** page, choose **Step - Output** to view the error message for that step in the command execution. Each step can display a different error message. Review the error messages for all steps to help troubleshoot the issue.
If viewing the step output doesn't solve the problem, then you can try to recreate the association. To recreate the association, first delete the failing association in State Manager. After deleting the association, edit the configuration and choose the option you deleted and choose **Update**.  
To investigate **Failed** associations for an **Organization** configuration, you must sign in to the account with the failed association and use the following failed association procedure, previously described. The **Association ID** isn't a hyperlink to the target account when viewing results from the management account.

**Issue: Drift status**  
When viewing a configuration's details page, you can view the drift status of each deployment. Configuration drift occurs whenever a user makes any change to a service or feature that conflicts with the selections made through Quick Setup. If an association has changed after the initial configuration, the table displays a warning icon that indicates the number of items that have drifted. You can determine what caused the drift by hovering over the icon. 
When an association is deleted in State Manager, the related deployments display a drift warning. To fix this, edit the configuration and choose the option that was removed when the association was deleted. Choose **Update** and wait for the deployment to complete.