How To Create AWS SSM Automation Workflow
Hello Everyone
Welcome to CloudAffaire and this is Debjeet.
In the last blog post, we have discussed how to execute a command using AWS SSM Run Command.
https://cloudaffaire.com/how-to-execute-a-command-using-aws-ssm-run-command/
In this blog post, we will discuss how to create AWS SSM Automation.
What Is AWS System Manager (SSM) Automation:
Systems Manager Automation simplifies common maintenance and deployment tasks of EC2 instances and other AWS resources. Using SSM Automation, you can automate common maintenance and deployment tasks. You can use Automation to create and update Amazon Machine Images, apply driver and agent updates, reset passwords on Windows Server instance, reset SSH keys on Linux instances, and apply OS patches or application updates.
Systems Manager Automation Features:
- Target: Automation supports the target parameter which enables you to quickly define which resources in your fleet can run 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 EC2 tags with the Targets parameter.
- Rate Control: 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.
- Triggers: Automations can be initiated by several different triggers, such as Amazon EventBridge, State Manager associations, or maintenance windows. By using triggers, you can run automations as a result of a specific event or on a scheduled basis.
- Security: Automations can be run using the current authenticated user or an IAM service role or by using delegated administration.
- Multiple AWS Region And Accounts: You can run AWS Systems Manager automations across multiple AWS Regions and AWS accounts or AWS Organizational Units (OUs) from an Automation management account.
- Automation Documents: A Systems Manager Automation document defines the actions that Systems Manager performs on your managed instances and other AWS resources when an automation execution runs. A document 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.
Systems Manager Automation Actions:
Systems Manager Automation runs steps defined in Automation documents. 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 Automation document. Below is the list of all actions possible through SSM Automation Document.
- aws:approve – Pause an execution for manual approval
- aws:assertAwsResourceProperty – Assert an AWS resource state or event state
- aws:branch – Run conditional automation steps
- aws:changeInstanceState – Change or assert instance state
- aws:copyImage – Copy or encrypt an Amazon Machine Image
- aws:createImage – Create an Amazon Machine Image
- aws:createStack – Create an AWS CloudFormation stack
- aws:createTags – Create tags for AWS resources
- aws:deleteImage – Delete an Amazon Machine Image
- aws:deleteStack – Delete an AWS CloudFormation stack
- aws:executeAutomation – Run another automation execution
- aws:executeAwsApi – Call and run AWS API actions
- aws:executeScript – Run a script
- aws:executeStateMachine – Run an AWS Step Functions state machine
- aws:invokeLambdaFunction – Invoke an AWS Lambda function
- aws:pause – Pause an automation execution
- aws:runCommand – Run a command on a managed instance
- aws:runInstances – Launch an EC2 instance
- aws:sleep – Delay an automation execution
- aws:waitForAwsResourceProperty – Wait on an AWS resource property
How To Create AWS SSM Automation Workflow:
Requirements:
AWS CLI installed and configured. You can follow the below blog post to install and configure AWS CLI.
https://cloudaffaire.com/how-to-install-aws-cli/
https://cloudaffaire.com/how-to-configure-aws-cli/
Step 1: Create an EC2 SSM Managed Instance.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 |
############################################### ## How To Create AWS SSM Automation Workflow ## ############################################### ## -------------------------------------- ## Create An AWS EC2 SSM Managed Instance ## -------------------------------------- ## Create a directory for this demo mkdir ssmdemo && cd ssmdemo ## Create a VPC AWS_VPC_ID=$(aws ec2 create-vpc \ --cidr-block 10.0.0.0/16 \ --query 'Vpc.{VpcId:VpcId}' \ --output text) ## Enable DNS hostname for your VPC aws ec2 modify-vpc-attribute \ --vpc-id $AWS_VPC_ID \ --enable-dns-hostnames "{\"Value\":true}" ## Create a public subnet AWS_SUBNET_PUBLIC_ID=$(aws ec2 create-subnet \ --vpc-id $AWS_VPC_ID --cidr-block 10.0.1.0/24 \ --availability-zone ap-south-1a --query 'Subnet.{SubnetId:SubnetId}' \ --output text) ## Enable Auto-assign Public IP on Public Subnet aws ec2 modify-subnet-attribute \ --subnet-id $AWS_SUBNET_PUBLIC_ID \ --map-public-ip-on-launch ## Create an Internet Gateway AWS_INTERNET_GATEWAY_ID=$(aws ec2 create-internet-gateway \ --query 'InternetGateway.{InternetGatewayId:InternetGatewayId}' \ --output text) ## Attach Internet gateway to your VPC aws ec2 attach-internet-gateway \ --vpc-id $AWS_VPC_ID \ --internet-gateway-id $AWS_INTERNET_GATEWAY_ID ## Create a route table AWS_CUSTOM_ROUTE_TABLE_ID=$(aws ec2 create-route-table \ --vpc-id $AWS_VPC_ID \ --query 'RouteTable.{RouteTableId:RouteTableId}' \ --output text ) ## Create route to Internet Gateway aws ec2 create-route \ --route-table-id $AWS_CUSTOM_ROUTE_TABLE_ID \ --destination-cidr-block 0.0.0.0/0 \ --gateway-id $AWS_INTERNET_GATEWAY_ID ## Associate the public subnet with route table AWS_ROUTE_TABLE_ASSOID=$(aws ec2 associate-route-table \ --subnet-id $AWS_SUBNET_PUBLIC_ID \ --route-table-id $AWS_CUSTOM_ROUTE_TABLE_ID \ --output text) ## Create a security group aws ec2 create-security-group \ --vpc-id $AWS_VPC_ID \ --group-name myvpc-security-group \ --description 'My VPC non default security group' ## Get security group ID's AWS_DEFAULT_SECURITY_GROUP_ID=$(aws ec2 describe-security-groups \ --filters "Name=vpc-id,Values=$AWS_VPC_ID" \ --query 'SecurityGroups[?GroupName == `default`].GroupId' \ --output text) && AWS_CUSTOM_SECURITY_GROUP_ID=$(aws ec2 describe-security-groups \ --filters "Name=vpc-id,Values=$AWS_VPC_ID" \ --query 'SecurityGroups[?GroupName == `myvpc-security-group`].GroupId' \ --output text) ## Create security group ingress rules aws ec2 authorize-security-group-ingress \ --group-id $AWS_CUSTOM_SECURITY_GROUP_ID \ --ip-permissions '[{"IpProtocol": "tcp", "FromPort": 22, "ToPort": 22, "IpRanges": [{"CidrIp": "0.0.0.0/0", "Description": "Allow SSH"}]}]' && aws ec2 authorize-security-group-ingress \ --group-id $AWS_CUSTOM_SECURITY_GROUP_ID \ --ip-permissions '[{"IpProtocol": "tcp", "FromPort": 80, "ToPort": 80, "IpRanges": [{"CidrIp": "0.0.0.0/0", "Description": "Allow HTTP"}]}]' ## Get Amazon Linux 2 latest AMI ID AWS_AMI_ID=$(aws ec2 describe-images \ --owners 'amazon' \ --filters 'Name=name,Values=amzn2-ami-hvm-2.0.????????-x86_64-gp2' 'Name=state,Values=available' \ --query 'sort_by(Images, &CreationDate)[-1].[ImageId]' \ --output 'text') ## Create a key-pair aws ec2 create-key-pair \ --key-name myvpc-keypair \ --query 'KeyMaterial' \ --output text > myvpc-keypair.pem ## Create user data for a LAMP stack cat < #!/bin/bash sudo yum update -y sudo systemctl enable amazon-ssm-agent sudo systemctl start amazon-ssm-agent sudo systemctl status amazon-ssm-agent EOF ## Create an EC2 instance AWS_EC2_INSTANCE_ID=$(aws ec2 run-instances \ --image-id $AWS_AMI_ID \ --instance-type t2.micro \ --key-name myvpc-keypair \ --monitoring "Enabled=false" \ --security-group-ids $AWS_CUSTOM_SECURITY_GROUP_ID \ --subnet-id $AWS_SUBNET_PUBLIC_ID \ --user-data file://myuserdata.txt \ --private-ip-address 10.0.1.10 \ --query 'Instances[0].InstanceId' \ --output text) ## Create an Instance profile for SSM aws iam create-instance-profile \ --instance-profile-name "AmazonSSMInstanceProfileForInstances" ## Create a trust relation json file cat < { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Service": "ec2.amazonaws.com" }, "Action": "sts:AssumeRole" } ] } EOF ## Create an IAM role for SSM aws iam create-role \ --role-name "AmazonSSMRoleForInstances" \ --assume-role-policy-document file://trust_policy.json ## Attach the required policy for SSM aws iam attach-role-policy \ --role-name "AmazonSSMRoleForInstances" \ --policy-arn "arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore" ## Add the role to the instance profile aws iam add-role-to-instance-profile \ --instance-profile-name "AmazonSSMInstanceProfileForInstances" \ --role-name "AmazonSSMRoleForInstances" ## Attach the Instance Profile to the EC2 instance aws ec2 associate-iam-instance-profile \ --instance-id "$AWS_EC2_INSTANCE_ID" \ --iam-instance-profile "Name=AmazonSSMInstanceProfileForInstances" ## Add a tag to the ec2 instance aws ec2 create-tags \ --resources $AWS_EC2_INSTANCE_ID \ --tags "Key=Name,Value=MYAPP" |
Step 2: Create a new SSM document of type “Automation” to create an AMI from an EC2 Instance.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
## ------------------------------------ ## Create A SSM Document For Automation ## ------------------------------------ ## Create a document content file cat < --- schemaVersion: '0.3' description: "Create AMI Using AWS SSM Automation" parameters: InstanceId: type: String description: "(Required) AMI Source EC2 instance ID" mainSteps: - action: aws:createImage name: createMyImage maxAttempts: 3 onFailure: Abort inputs: InstanceId: "{{ InstanceId }}" ImageName: MYAPP AMI NoReboot: true ImageDescription: MYAPP AMI Created Through SSM Automation EOF ## Create a custom SSM document aws ssm create-document \ --content file://documentContent.json \ --name "my-custom-ssm-automation-doc" \ --document-type "Automation" \ --document-format "YAML" \ --tags "Key=Name,Value=MYAPP" |
Step 3: Execute the Automation to create an AMI.
1 2 3 4 5 6 7 8 9 10 |
## ---------------- ## Start Automation ## ---------------- ## Manually start the automation execution AUTOMATION_EXECUTION_ID=$(aws ssm start-automation-execution \ --document-name "my-custom-ssm-automation-doc" \ --parameters "InstanceId=i-01b8d4839b0c89e9d" \ --query 'AutomationExecutionId' \ --output text) |
Step 4: Get details for the AWS SSM Automation.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
## -------------------------- ## Get Deatils For Automation ## -------------------------- ## Get detailed information about a particular Automation execution aws ssm get-automation-execution \ --automation-execution-id $AUTOMATION_EXECUTION_ID ## Provides details about all active and terminated Automation executions. aws ssm describe-automation-executions \ --filters Key=ExecutionId,Values=$AUTOMATION_EXECUTION_ID ## Information about all active and terminated step executions in an Automation workflow. aws ssm describe-automation-step-executions \ --automation-execution-id $AUTOMATION_EXECUTION_ID ## Get the AMI details aws ec2 describe-images \ --region ap-south-1 \ --filters "Name=name,Values=MYAPP AMI" |
Step 5: Cleanup.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 |
## ------- ## Cleanup ## ------- ## Delete the AMI AMI_ID=$(aws ec2 describe-images \ --region ap-south-1 \ --filters "Name=name,Values=AMI Created on2020-11-09_10.31.51" \ --query 'Images[0].{ImageId:ImageId}' \ --output text) && aws ec2 deregister-image \ --image-id $AMI_ID ## Delete the ebs volume snapshot AWS_EBS_VOLUME_ID=$(aws ec2 describe-volumes \ --filters Name=attachment.instance-id,Values=$AWS_EC2_INSTANCE_ID \ --query 'Volumes[0].{VolumeId:VolumeId}' \ --output text) && AWS_SNAPSHOT_ID=$(aws ec2 describe-snapshots \ --filters Name=volume-id,Values=$AWS_EBS_VOLUME_ID \ --query "Snapshots[*].[SnapshotId]" \ --output text) && aws ec2 delete-snapshot \ --snapshot-id $AWS_SNAPSHOT_ID ## Delete the SSM document aws ssm delete-document \ --name "my-custom-ssm-automation-doc" ## Terminate the ec2 instance aws ec2 terminate-instances \ --instance-ids $AWS_EC2_INSTANCE_ID && rm -f myuserdata.txt ## wait for some time sleep 30 ## Delete key pair aws ec2 delete-key-pair \ --key-name myvpc-keypair && rm -f myvpc-keypair.pem ## Delete custom security group aws ec2 delete-security-group \ --group-id $AWS_CUSTOM_SECURITY_GROUP_ID ## Delete internet gateway aws ec2 detach-internet-gateway \ --internet-gateway-id $AWS_INTERNET_GATEWAY_ID \ --vpc-id $AWS_VPC_ID && aws ec2 delete-internet-gateway \ --internet-gateway-id $AWS_INTERNET_GATEWAY_ID ## Delete the custom route table aws ec2 disassociate-route-table \ --association-id $AWS_ROUTE_TABLE_ASSOID && aws ec2 delete-route-table \ --route-table-id $AWS_CUSTOM_ROUTE_TABLE_ID ## Delete the public subnet aws ec2 delete-subnet \ --subnet-id $AWS_SUBNET_PUBLIC_ID ## Delete the vpc aws ec2 delete-vpc \ --vpc-id $AWS_VPC_ID ## Remove the IAM role from Instance Profile aws iam remove-role-from-instance-profile \ --instance-profile-name "AmazonSSMInstanceProfileForInstances" \ --role-name "AmazonSSMRoleForInstances" ## Dettach policy from the role aws iam detach-role-policy \ --role-name "AmazonSSMRoleForInstances" \ --policy-arn "arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore" ## Delete the IAM role aws iam delete-role \ --role-name "AmazonSSMRoleForInstances" ## Delete the IAM Instance Profile aws iam delete-instance-profile \ --instance-profile-name "AmazonSSMInstanceProfileForInstances" ## Delete the directory created for this demo cd .. && rm -rf ssmdemo |
Hope you have enjoyed this blog post, to get more details on AWS SSM, please refer below AWS documentation
https://docs.aws.amazon.com/systems-manager/index.html