CloudFormation에서 생성한 인스턴스의 루트 볼륨에 태그를 어떻게 지정해야 하나요?

8분 분량
0

AWS CloudFormation을 통해 생성된 Amazon Elastic Compute Cloud (Amazon EC2) 인스턴스의 루트 볼륨에 태그를 지정하고 싶어요.

간단한 설명

EC2 인스턴스 리소스의 태그 속성은 CloudFormation을 통해 생성된 볼륨으로 확장되지 않습니다. 태그 지정은 인스턴스에 대한 사용자의 제어를 제한할 수 있습니다. 태그 지정은 특정 리소스의 비용을 관리하고 AWS ID와 Access Management (IAM) 정책을 제한하는 데 도움이 됩니다. 또한 태그 지정을 통해 사용자는 다른 리소스에 대해 유사한 제어 권한을 행사할 수 있습니다.

CloudFormation을 통한 부트스트랩을 사용하면 인스턴스의 Amazon Elastic Block Store (Amazon EBS) 루트 볼륨에 태그를 지정할 수 있습니다. 부트스트랩은 AWS: :EC2: :인스턴스 리소스의 ** UserData ** 속성을 통해 만듭니다. 부트스트랩을 수행하려면, 인스턴스를 생성한 후 AWS Command Line Interface (AWS CLI) 명령 또는 표준 Windows PowerShell 명령을 사용하십시오.

참고: AWS CLI 명령을 실행할 때 오류가 발생하면 최신 AWS CLI 버전을 사용하고 있는지 확인하세요.

해결 방법

CloudFormation 템플릿으로 인스턴스 생성

1.CloudFormation 콘솔을 엽니다.

2.    **Create Stack(스택 생성)**을 선택한 후 디자인 템플릿을 선택합니다.

3.    코드 편집기의 파라미터 탭에서 템플릿을 선택합니다.

4.템플릿 언어 ** ** 선택란에서 ** ** YAML을 선택합니다.

5.다음 JSON 또는 YAML 템플릿 중 하나를 복사한 다음 복사한 템플릿을 코드 편집기에 붙여 넣습니다.

JSON 템플릿:

{
  "AWSTemplateFormatVersion": "2010-09-09",
  "Description": "AWS CloudFormation Sample Template Tagging Root Volumes of EC2 Instances: This template shows you how to automatically tag the root volume of the EC2 instances that are created through the AWS CloudFormation template. This is done through the UserData property of the AWS::EC2::Instance resource. **WARNING** This template creates two Amazon EC2 instances and an IAM role. You will be billed for the AWS resources used if you create a stack from this template.",
  "Parameters": {
    "KeyName": {
      "Type": "AWS::EC2::KeyPair::KeyName",
      "Description": "Name of an existing EC2 KeyPair to enable SSH access to the ECS instances."
    },
    "InstanceType": {
      "Description": "EC2 instance type",
      "Type": "String",
      "Default": "t2.micro",
      "AllowedValues": [
        "t2.micro",
        "t2.small",
        "t2.medium",
        "t2.large",
        "m3.medium",
        "m3.large",
        "m3.xlarge",
        "m3.2xlarge",
        "m4.large",
        "m4.xlarge",
        "m4.2xlarge",
        "m4.4xlarge",
        "m4.10xlarge",
        "c4.large",
        "c4.xlarge",
        "c4.2xlarge",
        "c4.4xlarge",
        "c4.8xlarge",
        "c3.large",
        "c3.xlarge",
        "c3.2xlarge",
        "c3.4xlarge",
        "c3.8xlarge",
        "r3.large",
        "r3.xlarge",
        "r3.2xlarge",
        "r3.4xlarge",
        "r3.8xlarge",
        "i2.xlarge",
        "i2.2xlarge",
        "i2.4xlarge",
        "i2.8xlarge"
      ],
      "ConstraintDescription": "Please choose a valid instance type."
    },
    "InstanceAZ": {
      "Description": "EC2 AZ.",
      "Type": "AWS::EC2::AvailabilityZone::Name",
      "ConstraintDescription": "Must be the name of an Availability Zone."
    },
    "WindowsAMIID": {
      "Description": "The Latest Windows 2016 AMI taken from the public Systems Manager Parameter Store",
      "Type": "AWS::SSM::Parameter::Value<String>",
      "Default": "/aws/service/ami-windows-latest/Windows_Server-2016-English-Full-Base"
    },
    "LinuxAMIID": {
      "Description": "The Latest Amazon Linux 2 AMI taken from the public Systems Manager Parameter Store",
      "Type": "AWS::SSM::Parameter::Value<String>",
      "Default": "/aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2"
    }
  },
  "Resources": {
    "WindowsInstance": {
      "Type": "AWS::EC2::Instance",
      "Properties": {
        "ImageId": {
          "Ref": "WindowsAMIID"
        },
        "InstanceType": {
          "Ref": "InstanceType"
        },
        "AvailabilityZone": {
          "Ref": "InstanceAZ"
        },
        "IamInstanceProfile": {
          "Ref": "InstanceProfile"
        },
        "KeyName": {
          "Ref": "KeyName"
        },
        "UserData": {
          "Fn::Base64": {
            "Fn::Join": [
              "",
              [
                "<powershell>\n",
                "try {\n",
                "$AWS_AVAIL_ZONE=(Invoke-WebRequest -Uri 'http://169.254.169.254/latest/meta-data/placement/availability-zone' -UseBasicParsing).Content\n ",
                "$AWS_REGION=$AWS_AVAIL_ZONE.Substring(0,$AWS_AVAIL_ZONE.length-1)\n ",
                "$AWS_INSTANCE_ID=(Invoke-WebRequest -Uri 'http://169.254.169.254/latest/meta-data/instance-id' -UseBasicParsing).Content\n ",
                "$ROOT_VOLUME_IDS=((Get-EC2Instance -Region $AWS_REGION -InstanceId $AWS_INSTANCE_ID).Instances.BlockDeviceMappings | where-object DeviceName -match '/dev/sda1').Ebs.VolumeId\n ",
                "$tag = New-Object Amazon.EC2.Model.Tag\n ",
                "$tag.key = \"MyRootTag\"\n ",
                "$tag.value = \"MyRootVolumesValue\"\n ",
                "New-EC2Tag -Resource $ROOT_VOLUME_IDS -Region $AWS_REGION -Tag $tag\n",
                "}\n",
                "catch {\n",
                "Write-Output $PSItem\n",
                "}\n",
                "</powershell>\n"
              ]
            ]
          }
        },
        "Tags": [
          {
            "Key": "Name",
            "Value": {
              "Ref": "AWS::StackName"
            }
          }
        ],
        "BlockDeviceMappings": [
          {
            "DeviceName": "/dev/sdm",
            "Ebs": {
              "VolumeType": "io1",
              "Iops": "200",
              "DeleteOnTermination": "true",
              "VolumeSize": "10"
            }
          }
        ]
      }
    },
    "LinuxInstance": {
      "Type": "AWS::EC2::Instance",
      "Properties": {
        "ImageId": {
          "Ref": "LinuxAMIID"
        },
        "InstanceType": {
          "Ref": "InstanceType"
        },
        "AvailabilityZone": {
          "Ref": "InstanceAZ"
        },
        "IamInstanceProfile": {
          "Ref": "InstanceProfile"
        },
        "KeyName": {
          "Ref": "KeyName"
        },
        "UserData": {
          "Fn::Base64": {
            "Fn::Join": [
              "",
              [
                "#!/bin/sh\n",
                "AWS_AVAIL_ZONE=$(curl http://169.254.169.254/latest/meta-data/placement/availability-zone)\n",
                "AWS_REGION=${AWS_AVAIL_ZONE::-1}\n",
                "AWS_INSTANCE_ID=$(curl http://169.254.169.254/latest/meta-data/instance-id)\n",
                "ROOT_VOLUME_IDS=$(aws ec2 describe-instances --region $AWS_REGION --instance-id $AWS_INSTANCE_ID --output text --query Reservations[0].Instances[0].BlockDeviceMappings[0].Ebs.VolumeId)\n",
                "aws ec2 create-tags --resources $ROOT_VOLUME_IDS --region $AWS_REGION --tags Key=MyRootTag,Value=MyRootVolumesValue\n"
              ]
            ]
          }
        },
        "Tags": [
          {
            "Key": "Name",
            "Value": {
              "Ref": "AWS::StackName"
            }
          }
        ],
        "BlockDeviceMappings": [
          {
            "DeviceName": "/dev/sdm",
            "Ebs": {
              "VolumeType": "io1",
              "Iops": "200",
              "DeleteOnTermination": "true",
              "VolumeSize": "10"
            }
          }
        ]
      }
    },
    "InstanceRole": {
      "Type": "AWS::IAM::Role",
      "Properties": {
        "AssumeRolePolicyDocument": {
          "Version": "2012-10-17",
          "Statement": [
            {
              "Effect": "Allow",
              "Principal": {
                "Service": [
                  "ec2.amazonaws.com"
                ]
              },
              "Action": [
                "sts:AssumeRole"
              ]
            }
          ]
        },
        "Path": "/",
        "Policies": [
          {
            "PolicyName": "taginstancepolicy",
            "PolicyDocument": {
              "Version": "2012-10-17",
              "Statement": [
                {
                  "Effect": "Allow",
                  "Action": [
                    "ec2:Describe*"
                  ],
                  "Resource": "*"
                },
                {
                  "Effect": "Allow",
                  "Action": [
                    "ec2:CreateTags"
                  ],
                  "Resource": [
                    {
                      "Fn::Sub": "arn:aws:ec2:${AWS::Region}:${AWS::AccountId}:volume/*"
                    },
                    {
                      "Fn::Sub": "arn:aws:ec2:${AWS::Region}:${AWS::AccountId}:instance/*"
                    }
                  ]
                }
              ]
            }
          }
        ]
      }
    },
    "InstanceProfile": {
      "Type": "AWS::IAM::InstanceProfile",
      "Properties": {
        "Path": "/",
        "Roles": [
          {
            "Ref": "InstanceRole"
          }
        ]
      }
    }
  }
}

YAML 템플릿:

AWSTemplateFormatVersion: 2010-09-09
Description: >-
  AWS CloudFormation Sample Template Tagging Root Volumes of EC2 Instances: This
  template shows you how to automatically tag the root volume of the EC2
  instances that are created through the AWS CloudFormation template. This is
  done through the UserData property of the AWS::EC2::Instance resource.
  **WARNING** This template creates two Amazon EC2 instances and an IAM role.
  You will be billed for the AWS resources used if you create a stack from this
  template.
Parameters:
  KeyName:
    Type: 'AWS::EC2::KeyPair::KeyName'
    Description: Name of an existing EC2 KeyPair to enable SSH access to the ECS instances.
  InstanceType:
    Description: EC2 instance type
    Type: String
    Default: t2.micro
    AllowedValues:
      - t2.micro
      - t2.small
      - t2.medium
      - t2.large
      - m3.medium
      - m3.large
      - m3.xlarge
      - m3.2xlarge
      - m4.large
      - m4.xlarge
      - m4.2xlarge
      - m4.4xlarge
      - m4.10xlarge
      - c4.large
      - c4.xlarge
      - c4.2xlarge
      - c4.4xlarge
      - c4.8xlarge
      - c3.large
      - c3.xlarge
      - c3.2xlarge
      - c3.4xlarge
      - c3.8xlarge
      - r3.large
      - r3.xlarge
      - r3.2xlarge
      - r3.4xlarge
      - r3.8xlarge
      - i2.xlarge
      - i2.2xlarge
      - i2.4xlarge
      - i2.8xlarge
    ConstraintDescription: Please choose a valid instance type.
  InstanceAZ:
    Description: EC2 AZ.
    Type: 'AWS::EC2::AvailabilityZone::Name'
    ConstraintDescription: Must be the name of an Availability Zone.
  WindowsAMIID:
    Description: >-
      The Latest Windows 2016 AMI taken from the public Systems Manager
      Parameter Store
    Type: 'AWS::SSM::Parameter::Value<String>'
    Default: /aws/service/ami-windows-latest/Windows_Server-2016-English-Full-Base
  LinuxAMIID:
    Description: >-
      The Latest Amazon Linux 2 AMI taken from the public Systems Manager
      Parameter Store
    Type: 'AWS::SSM::Parameter::Value<String>'
    Default: /aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2
Resources:
  WindowsInstance:
    Type: 'AWS::EC2::Instance'
    Properties:
      ImageId: !Ref WindowsAMIID
      InstanceType: !Ref InstanceType
      AvailabilityZone: !Ref InstanceAZ
      IamInstanceProfile: !Ref InstanceProfile
      KeyName: !Ref KeyName
      UserData: !Base64
        'Fn::Join':
          - ''
          - - |
              <powershell>
            - |
              try {
            - >-
              $AWS_AVAIL_ZONE=(Invoke-WebRequest -Uri
              'http://169.254.169.254/latest/meta-data/placement/availability-zone'
              -UseBasicParsing).Content

            - |-
              $AWS_REGION=$AWS_AVAIL_ZONE.Substring(0,$AWS_AVAIL_ZONE.length-1)

            - >-
              $AWS_INSTANCE_ID=(Invoke-WebRequest -Uri
              'http://169.254.169.254/latest/meta-data/instance-id'
              -UseBasicParsing).Content

            - >-
              $ROOT_VOLUME_IDS=((Get-EC2Instance -Region $AWS_REGION -InstanceId
              $AWS_INSTANCE_ID).Instances.BlockDeviceMappings | where-object
              DeviceName -match '/dev/sda1').Ebs.VolumeId

            - |-
              $tag = New-Object Amazon.EC2.Model.Tag

            - |-
              $tag.key = "MyRootTag"

            - |-
              $tag.value = "MyRootVolumesValue"

            - >
              New-EC2Tag -Resource $ROOT_VOLUME_IDS -Region $AWS_REGION -Tag
              $tag
            - |
              }
            - |
              catch {
            - |
              Write-Output $PSItem
            - |
              }
            - |
              </powershell>
      Tags:
        - Key: Name
          Value: !Ref 'AWS::StackName'
      BlockDeviceMappings:
        - DeviceName: /dev/sdm
          Ebs:
            VolumeType: io1
            Iops: '200'
            DeleteOnTermination: 'true'
            VolumeSize: '10'
  LinuxInstance:
    Type: 'AWS::EC2::Instance'
    Properties:
      ImageId: !Ref LinuxAMIID
      InstanceType: !Ref InstanceType
      AvailabilityZone: !Ref InstanceAZ
      IamInstanceProfile: !Ref InstanceProfile
      KeyName: !Ref KeyName
      UserData: !Base64
        'Fn::Join':
          - ''
          - - |
              #!/bin/sh
            - >
              AWS_AVAIL_ZONE=$(curl
              http://169.254.169.254/latest/meta-data/placement/availability-zone)
            - |
              AWS_REGION=${AWS_AVAIL_ZONE::-1}
            - >
              AWS_INSTANCE_ID=$(curl
              http://169.254.169.254/latest/meta-data/instance-id)
            - >
              ROOT_VOLUME_IDS=$(aws ec2 describe-instances --region $AWS_REGION
              --instance-id $AWS_INSTANCE_ID --output text --query
              Reservations[0].Instances[0].BlockDeviceMappings[0].Ebs.VolumeId)
            - >
              aws ec2 create-tags --resources $ROOT_VOLUME_IDS --region
              $AWS_REGION --tags Key=MyRootTag,Value=MyRootVolumesValue
      Tags:
        - Key: Name
          Value: !Ref 'AWS::StackName'
      BlockDeviceMappings:
        - DeviceName: /dev/sdm
          Ebs:
            VolumeType: io1
            Iops: '200'
            DeleteOnTermination: 'true'
            VolumeSize: '10'
  InstanceRole:
    Type: 'AWS::IAM::Role'
    Properties:
      AssumeRolePolicyDocument:
        Version: 2012-10-17
        Statement:
          - Effect: Allow
            Principal:
              Service:
                - ec2.amazonaws.com
            Action:
              - 'sts:AssumeRole'
      Path: /
      Policies:
        - PolicyName: taginstancepolicy
          PolicyDocument:
            Version: 2012-10-17
            Statement:
              - Effect: Allow
                Action:
                  - 'ec2:Describe*'
                Resource: '*'
              - Effect: Allow
                Action:
                  - 'ec2:CreateTags'
                Resource:
                  - !Sub 'arn:aws:ec2:${AWS::Region}:${AWS::AccountId}:volume/*'
                  - !Sub 'arn:aws:ec2:${AWS::Region}:${AWS::AccountId}:instance/*'
  InstanceProfile:
    Type: 'AWS::IAM::InstanceProfile'
    Properties:
      Path: /
      Roles:
        - !Ref InstanceRole

6.템플릿의 ** UserData ** 섹션에서 Linux 인스턴스의 요구 사항에 ** 맞게 --tags Key=Name,Value=newAMI를 ** 업데이트합니다. Windows 인스턴스의 경우 ** $tag.key="MyRootTag”와 $tag.value="MyRootVolumesValue"를 업데이트하십시오. ** ** ** 다음과 같은 Linux와 Windows용 ** UserData ** 섹션 예를 참조하십시오.

Linux 예제:

#Linux UserData
  UserData:
     Fn::Base64: !Sub |
      #!/bin/bash
      AWS_AVAIL_ZONE=$(curl http://169.254.169.254/latest/meta-data/placement/availability-zone)
      AWS_REGION="`echo \"$AWS_AVAIL_ZONE\" | sed 's/[a-z]$//'`"
      AWS_INSTANCE_ID=$(curl http://169.254.169.254/latest/meta-data/instance-id)
      ROOT_VOLUME_IDS=$(aws ec2 describe-instances --region $AWS_REGION --instance-id $AWS_INSTANCE_ID --output text --query Reservations[0].Instances[0].BlockDeviceMappings[0].Ebs.VolumeId)
      aws ec2 create-tags --resources $ROOT_VOLUME_IDS --region $AWS_REGION --tags Key=MyRootTag,Value=MyRootVolumesValue

Windows 예제:

#Windows UserData with standard Powershell commands (no AWS CLI installed)
    UserData:
    Fn::Base64: !Sub |
      <powershell>
      try {  
      $AWS_AVAIL_ZONE=(Invoke-WebRequest -Uri 'http://169.254.169.254/latest/meta-data/placement/availability-zone' -UseBasicParsing).Content
      $AWS_REGION=$AWS_AVAIL_ZONE.Substring(0,$AWS_AVAIL_ZONE.length-1)
      $AWS_INSTANCE_ID=(Invoke-WebRequest -Uri 'http://169.254.169.254/latest/meta-data/instance-id' -UseBasicParsing).Content
      $ROOT_VOLUME_IDS=((Get-EC2Instance -Region $AWS_REGION -InstanceId $AWS_INSTANCE_ID).Instances.BlockDeviceMappings | where-object DeviceName -match '/dev/sda1').Ebs.VolumeId
      $tag = New-Object Amazon.EC2.Model.Tag
      $tag.key = "MyRootTag"
      $tag.value = "MyRootVolumesValue"
      New-EC2Tag -Resource $ROOT_VOLUME_IDS -Region $AWS_REGION -Tag $tag
      }
      catch {
      Write-Output $PSItem
      }
      </powershell>

**중요:****UserData에 ** 서 AWS CLI 명령을 사용하려면 EC2 인스턴스의 Amazon Machine Image (AMI) ](https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-install.html) 내에 [ AWS CLI를 설치해야 합니다. AWS CLI는 기본적으로 모든 Amazon Linux AMI에 설치됩니다. 또한 EC2 인스턴스에 인스턴스 프로필을 붙여야 합니다. 인스턴스 프로필에는 AWS 지역 및 계정 내의 EC2 볼륨 **과 ** 인스턴스에서만 ec2:DescribeInstances와 ** ec2:CreateTags ** API를 호출할 수 있는 권한이 포함되어 있습니다.

7.** Create stack(스택 생성) ** 아이콘을 선택합니다.

8.    Stack 이름란에는 사용자 스택의 이름을 입력합니다.

9.**Parameters ** 섹션에서는 사용자의 인스턴스 유형, EC2 키 쌍 및 AMI를 포함하여 환경의 요구 사항에 따르는 적절한 정보를 입력합니다.

  1. **Next(다음)**를 선택합니다.

11.Options ** 섹션에서는 사용자 스택에 대한 적절한 정보를 입력한 후 ** Next(다음)를 선택합니다.

12.CloudFormation 스택에서 IAM 리소스를 생성하려면 ** “I acknowledge that AWS CloudFormation might create IAM resources” (AWS CloudFormation이 IAM 리소스를 생성할 수 있음을 확인했습니다) 확인란을 선택합니다. **

13.Create(생성)를 선택합니다.

인스턴스의 루트 볼륨에 태그 지정

  1. Amazon EC2 콘솔을 엽니다.

2.탐색 창의 ** Elastic Block Store ** 섹션에서 ** 볼륨을 선택합니다**.

3.**Filter ** 필드에 CloudFormation 스택에 설정한 태그를 입력하여 볼륨에 태그가 지정되었는지 확인합니다.


AWS 공식
AWS 공식업데이트됨 3년 전
댓글 없음

관련 콘텐츠