amazon-web-servicesamazon-ec2automationyamlaws-ssm

YAML script to tag stopped EC2 instances using automation document in Systems Manager


I am trying to create an automation document in AWS for a maintenance task- which will add a tag to all the stopped EC2 instances in a region.

This is the yaml I'm working with:

schemaVersion: '0.3'
description: Automation to add tags to stopped instances.

parameters:
  - name: Region
    type: String
    description: The AWS region to run the automation in.
    default: us-east-1

  - name: TagKey
    type: String
    description: The key of the tag to be added to the instances.
    default: Status

  - name: TagValue
    type: String
    description: The value of the tag to be added to the instances.
    default: Stopped

mainSteps:
  - action: 'aws:runCommand'
    name: 'FindStoppedInstances'
    inputs:
      DocumentName: 'AWS-RunShellScript'
      Parameters:
        commands:
          - |
            # Get the list of stopped EC2 instance IDs
            instance_ids=$(aws ec2 describe-instances \
              --filters "Name=instance-state-name,Values=stopped" \
              --query "Reservations[*].Instances[*].InstanceId" \
              --output text)
            
            echo "$instance_ids"
        executionTimeout: ['3600']
    outputs:
      - Name: 'instance_ids'
        Selector: '$.Payload'
        Type: 'StringList'

  - action: 'aws:runCommand'
    name: 'TagStoppedInstances'
    inputs:
      DocumentName: 'AWS-RunShellScript'
      Parameters:
        commands:
          - |
            # Loop through each stopped instance and tag it
            for instance_id in {{ instance_ids }}; do
              echo "Adding tag to instance $instance_id"
              aws ec2 create-tags --resources $instance_id --tags Key={{ TagKey }},Value={{ TagValue }}
            done
        executionTimeout: ['3600']

frankly, I have not used YAML before and took help from chatgpt. I don't want to use lambda for this task. This document is giving an error - (parameters) Parameter definition does not match any following types, String, StringList, Boolean, Integer, StringMap, MapList, AWS::EC2::Instance::Id, AWS::IAM::Role::Arn, AWS::S3::Bucket::Name, List<AWS::EC2::Instance::Id>, List<AWS::IAM::Role::Arn>, List<AWS::S3::Bucket::Name>

Can someone please help me on how to correct this script? After putting the tags, I want to start those EC2s. Once my patching task is complete (for which I am using run command), I want to shut down the EC2s which have this tag again and remove this tag.


Solution

  • There are couple of issues with the script. Update the parameter section to have keys not list:

    parameters:
      Region:
        type: String
        description: The AWS region to run the automation in.
        default: us-east-1
    
      TagKey:
        type: String
        description: The key of the tag to be added to the instances.
        default: Status
    
      TagValue:
        type: String
        description: The value of the tag to be added to the instances.
        default: Stopped
    

    Then update the script in action TagStoppedInstances to reference the previous action:

      - action: 'aws:runCommand'
        name: 'TagStoppedInstances'
        inputs:
          DocumentName: 'AWS-RunShellScript'
          Parameters:
            commands:
              - |
                # Loop through each stopped instance and tag it
                for instance_id in {{ FindStoppedInstances.instance_ids }}; do
                  echo "Adding tag to instance $instance_id"
                  aws ec2 create-tags --resources $instance_id --tags Key={{ TagKey }},Value={{ TagValue }}
                done
            executionTimeout: ['3600']
    

    Instead of running scripts that call AWS CLI I would suggest using actions that run AWS API. A sample of similar workflow can be found on AWS Systems Manager User Guide