1

I have a CloudFormation template that create a set of SSM commands to manage my Linux EC2 instances. This commands must have access to my AWS account number to do some tasks.

On my CloudFormation template, I did :

AWSTemplateFormatVersion: '2010-09-09'
Description: Sample SSM commands

MyCommand1:
  Type: AWS::SSM::Document
  Properties: 
    DocumentType: Command
      Content: 
        schemaVersion: "2.2"
        parameters: {}
        mainSteps: 
          - action: aws:runShellScript 
            name : command1
            inputs: 
              runCommand:
                - echo "this command run on the selected EC2 instance" && echo "You are running this on account {{global:ACCOUNT_ID}}"

Outputs:
    Command1ID:
        Description: MyCommand1
        Value: !Ref  MyCommand1

This template install the function, and I can run it from the SSM web console.

But the {{global:ACCOUNT_ID}} is not valued to my account number. It is valued to the string "{{global:ACCOUNT_ID}}". So I presume this is not the good syntax to use global var from an SSM command.

So, after reading the doc here https://docs.aws.amazon.com/systems-manager/latest/userguide/walkthrough-cli.html I tried to test this via the CLI only (to quickly test other syntax) :

$> sh_command_id=$(aws ssm send-command --instance-ids "i-0cb0c0ea8ef7339f1" --document-name "AWS-RunShellScript" --parameters commands='echo You are running this on account {{global:ACCOUNT_ID}}' --output text --query "Command.CommandId")

but the command failed with a parsing error Error parsing parameter '--parameters': Expected: ',', received: '}' for input

What is the correct syntax to use the {{global:*}} things in SSM "runCommand" action ?

JayMore
  • 642
  • 6
  • 20

2 Answers2

2

You can achieve this by using the Fn::Sub function:

- !Sub 'echo "this command run on the selected EC2 instance" && echo "You are running this on account ${AWS::AccountId}"'
Titulum
  • 9,928
  • 11
  • 41
  • 79
  • 1
    Great answer ! To complete the answer from Yogesh_D : it is not possible to use {{..}} inside an SSM command, but your trick here is to substitue the account_id at CloudFormation level, before SSM. – JayMore Jan 07 '20 at 12:58
  • Learned something new today! @JayMore Def use this instead of what I mentioned :) – Yogesh_D Jan 07 '20 at 13:27
-1

The built in variable for ACCOUNT_ID is not going to be available to you. Using SSM you are running a command on an instance and this command doesn't understand the ACCOUNT_ID. Based on the cloud formation template I am assuming you are running this on a *ix based system.

One way to do is this use this in your actual command:

ACCOUNT_ID=`curl -s http://169.254.169.254/latest/dynamic/instance-identity/document | grep accountId| awk '{print $3}'|sed 's/"//g'|sed 's/,//g'` && echo "this command run on the selected EC2 instance" && echo "You are running this on account ${ACCOUNT_ID}"

This uses the ec2 instance metadata to figure out the Account ID.

Yogesh_D
  • 17,656
  • 10
  • 41
  • 55
  • Thank for your answer, it solve the problem at the run level. Improvement : if you are using a standard AmazonLinux, you can use : `curl -s http://169.254.169.254/latest/dynamic/instance-identity/document | jq -r .accountId` instead of awk | sed . – JayMore Jan 07 '20 at 13:00
  • yes, you can use jq, however did not want to assume you have ```jq``` installed on your ec2 instance and hence stuck to using awk and sed. – Yogesh_D Jan 07 '20 at 13:24