How do I use AWSUtility::CloudFormation::CommandRunner to run a command before or after a resource in my CloudFormation stack?

3 minute read
0

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 you run AWS Command Line Interface (AWS CLI) commands, then see Troubleshooting errors for the AWS CLI. Also, make sure that you're using the most recent AWS CLI version.

Register AWSUtility::CloudFormation::CommandRunner

If you didn't register the AWSUtility::CloudFormation::CommandRunner resource, then run the following commands to register it:

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

The register.sh script runs the register-type AWS CLI command and uses awsutility-cloudformation-commandrunner.zip to register the resource type in your default AWS Region. To check the default Region, run the aws configure get region command. For more information about what actions the register.sh script performs, see User installation steps on the AWS GitHub website.

Define the resource in your CloudFormation template

To run a command before or after a resource in your CloudFormation stack, define the AWSUtility::CloudFormation::CommandRunner resource in your CloudFormation template.

Example template:

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

You must include the --region option in your AWS CLI commands. Then, write the command's output to a reserved file that's called /command-output.txt.

The Role property must be the name of an AWS Identity and Access Management (IAM) instance profile that has an associated IAM role. The IAM role must have a trust relationship with the Amazon Elastic Compute Cloud (Amazon EC2) service, ec2.amazonaws.com. To run your command, the AWSUtility::CloudFormation::CommandRunner resource, assumes the property Role property. If you specify the LogGroup property, then LogGroup writes the logs from your command's execution to the Amazon CloudWatch log group.

For more information about how to use the AWSUtility::CloudFormation::CommandRunner resource in your template, see README.md and docs/README.md on the GitHub website.

Use Fn::GetAtt to reference the output of the command.

Example template snippet:

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.

Example template:

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 the resource's definition.

Example template:

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 that aws s3 ls returned. To get the bucket name, sed -n 1p sends the response to cut -d " " -f3. Then, cut -d " " -f3 chooses the third element in the array that's created after it splits the line that's delimited by a space.

Related information

Running bash commands in AWS CloudFormation templates

AWS OFFICIAL
AWS OFFICIALUpdated 4 months ago