How do I use AWSUtility::CloudFormation::CommandRunner to run a command before or after a resource in my AWS CloudFormation stack?
Last updated: 2021-02-02
I want to use AWSUtility::CloudFormation::CommandRunner to run a command before or after a resource in my AWS CloudFormation stack.
Resolution
Note: If you receive errors when running AWS Command Line Interface (AWS CLI) commands, make sure that you’re using the most recent AWS CLI version.
To run a command before or after a resource in your AWS CloudFormation stack, define the AWSUtility::CloudFormation::CommandRunner resource in your AWS CloudFormation template.
For example:
Resources:
CommandRunner:
Type: AWSUtility::CloudFormation::CommandRunner
Properties:
Command: 'aws ssm get-parameter --name BucketName --region us-east-1 --query Parameter.Value --output text > /command-output.txt'
Role: EC2-Role
LogGroup: my-cloudwatch-log-group
Important: If you haven't already registered the AWSUtility::CloudFormation::CommandRunner resource, then run the following commands.
git clone https://github.com/aws-cloudformation/aws-cloudformation-resource-providers-awsutilities-commandrunner.git
cd aws-cloudformation-resource-providers-awsutilities-commandrunner
curl -LO https://github.com/aws-cloudformation/aws-cloudformation-resource-providers-awsutilities-commandrunner/releases/latest/download/awsutility-cloudformation-commandrunner.zip
./scripts/register.sh --set-default
Important: The property Role requires a trust relationship with the Amazon Elastic Compute Cloud (Amazon EC2) service (ec2.amazonaws.com). The property Role is assumed by the AWSUtility::CloudFormation::CommandRunner resource to run your command. The optional property LogGroup, if specified, writes the logs from your command's execution to the Amazon CloudWatch log group. For more information on using the AWSUtility::CloudFormation::CommandRunner resource in your template, see README.md and docs/README.md from the aws-cloudformation-resource-providers-awsutilities-commandrunner repository on the AWS GitHub site.
You must include the --region option in your AWS CLI commands, and then write the command's output to a reserved file called /command-output.txt, as in the preceding code example.
You can reference the output of the command using Fn::GetAtt. For example:
S3Bucket:
Type: AWS::S3::Bucket
Properties:
BucketName: !GetAtt CommandRunner.Output
To run the command after a resource with the logical name Instance, specify DependsOn: Instance in the AWSUtility::CloudFormation::CommandRunner resource's definition. For example:
Resources:
CommandRunner:
DependsOn: Instance
Type: AWSUtility::CloudFormation::CommandRunner
Properties:
Command: aws s3 ls | sed -n 1p | cut -d " " -f3 > /command-output.txt
LogGroup: my-cloudwatch-log-group
Role: EC2-Role
Instance:
Type: AWS::EC2::Instance
Properties:
Image: ami-abcd1234
To run the command before a resource, set DependsOn to the logical name of the AWSUtility::CloudFormation::CommandRunner resource in that resource's definition. For example:
Resources:
CommandRunner:
Type: AWSUtility::CloudFormation::CommandRunner
Properties:
Command: aws s3 ls | sed -n 1p | cut -d " " -f3 > /command-output.txt
LogGroup: my-cloudwatch-log-group
Role: EC2-Role
Instance:
DependsOn: CommandRunner
Type: AWS::EC2::Instance
Properties:
Image: ami-abcd1234
Note: In the preceding examples, sed -n 1p prints only the first line from the response returned by aws s3 ls. To get the bucket name, sed -n 1p pipes the response to cut -d " " -f3, which chooses the third element in the array created after splitting the line delimited by a space.
Related information
Did this article help?
Do you need billing or technical support?