AWS CloudFormation が作成したインスタンスからルートボリュームにタグを付ける方法を教えてください。

最終更新日: 2020 年 1 月 16 日

AWS CloudFormation を通じて作成された Amazon Elastic Compute Cloud (Amazon EC2) インスタンスのルートボリュームにタグを付ける事を考えています。

簡単な説明

Amazon EC2 インスタンスリソースのタグプロパティは、AWS CloudFormation を通じて作成されたボリュームには拡張されません。 タグ付けでは、インスタンスに対するコントロールを制限できます。これにより、特定のリソースのコスト管理や AWS Identity and Access Management (IAM) ポリシーの制限ができ、他のリソースに対しても同様のコントロールを行うことができます。

インスタンスの Amazon Elastic Block Store (Amazon EBS) ルートボリュームへのタグ付けは、AWS CloudFormation を使用したブートストラップにより行えます。 ブートストラップ方法は、AWS::EC2::Instance リソースの UserData プロパティを介して行われます。ブートストラップを実行するには、インスタンスを作成した後に AWS Command Line Interface (AWS CLI) の commands または標準の PowerShell コマンドを使用します。

解決方法

AWS CloudFormation テンプレートを使用してインスタンスを作成します

1.    [AWS CloudFormation コンソール] を開きます。

2.    [スタックの作成] を選択してから、[デザインテンプレート] クリックします。

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 how to automatically tag the root volume of the EC2 instances which are created through the 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 availabity 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",
                "$AWS_AVAIL_ZONE=(curl http://169.254.169.254/latest/meta-data/placement/availability-zone).Content\n ",
                "$AWS_REGION=$AWS_AVAIL_ZONE.Substring(0,$AWS_AVAIL_ZONE.length-1)\n ",
                "$AWS_INSTANCE_ID=(curl http://169.254.169.254/latest/meta-data/instance-id).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",
                "</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*",
                    "ec2:CreateTags"
                  ],
                  "Resource": "*"
                }
              ]
            }
          }
        ]
      }
    },
    "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 how to automatically tag the root volume of the EC2 instances which are
 created through the 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 availabity 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:
 #Tagging the root volume for the EC2 instances with the Windows OS
 #The commented out powershell commands are to utilize if the AMI has the AWS CLI installed and you prefer that approach.
 WindowsInstance:
  Type: 'AWS::EC2::Instance'
  Properties:
   ImageId: !Ref WindowsAMIID
   InstanceType: !Ref InstanceType
   AvailabilityZone: !Ref InstanceAZ
   IamInstanceProfile: !Ref InstanceProfile
   KeyName: !Ref KeyName
   UserData: 
    Fn::Base64: |
     <powershell>
      $AWS_AVAIL_ZONE=(curl http://169.254.169.254/latest/meta-data/placement/availability-zone).Content
      $AWS_REGION=$AWS_AVAIL_ZONE.Substring(0,$AWS_AVAIL_ZONE.length-1)
      $AWS_INSTANCE_ID=(curl http://169.254.169.254/latest/meta-data/instance-id).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
     </powershell>
    #<powershell>
    #$AWS_AVAIL_ZONE=(curl http://169.254.169.254/latest/meta-data/placement/availability-zone).Content
    #$AWS_REGION=$AWS_AVAIL_ZONE.Substring(0,$AWS_AVAIL_ZONE.length-1)
    #$AWS_INSTANCE_ID=(curl http://169.254.169.254/latest/meta-data/instance-id).Content
    #$ROOT_VOLUME_IDS =(aws ec2 describe-instances --region eu-west-1 --instance-id $AWS_INSTANCE_ID --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
    #</powershell>
   Tags:
    - Key: Name
     Value: !Ref 'AWS::StackName'
   BlockDeviceMappings:
    - DeviceName: /dev/sdm
     Ebs:
      VolumeType: io1
      Iops: '200'
      DeleteOnTermination: 'true'
      VolumeSize: '10'
 #Tagging the root volume for EC2 instances with an Unix OS with the AWS CLI installed.
 LinuxInstance:
  Type: 'AWS::EC2::Instance'
  Properties:
   ImageId: !Ref LinuxAMIID
   InstanceType: !Ref InstanceType
   AvailabilityZone: !Ref InstanceAZ
   IamInstanceProfile: !Ref InstanceProfile
   KeyName: !Ref KeyName
   UserData: 
    Fn::Base64: |
     #!/bin/sh
     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
   Tags:
    - Key: Name
     Value: !Ref 'AWS::StackName'
   BlockDeviceMappings:
    - DeviceName: /dev/sdm
     Ebs:
      VolumeType: io1
      Iops: '200'
      DeleteOnTermination: 'true'
      VolumeSize: '10'
 #AMI role given to the instances, the instances need the describe and create tags to complete the UserData
 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*'
         - 'ec2:CreateTags'
        Resource: '*'
 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>
            $AWS_AVAIL_ZONE=(curl http://169.254.169.254/latest/meta-data/placement/availability-zone).Content
            $AWS_REGION=$AWS_AVAIL_ZONE.Substring(0,$AWS_AVAIL_ZONE.length-1)
            $AWS_INSTANCE_ID=(curl http://169.254.169.254/latest/meta-data/instance-id).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
          </powershell>

注: UserData に対し AWS CLI コマンドを使用するには、EC2 インスタンスの Amazon マシンイメージ (AMI) 内に AWS CLI をインストールする必要があります。AWS CLI は、デフォルトですべての Amazon Linux AMI にインストールされています。加えて、EC2 インスタンスにインスタンスプロファイルをアタッチする必要もあります。インスタンスプロファイルには、ec2:DescribeInstances および ec2:CreateTags API を呼び出すアクセス許可が含まれています。

7.    [スタック] の作成アイコンを選択します。

8.    [スタック名] には、スタックの名前を入力します。

9.    [パラメータ] セクションに、インスタンスタイプ、EC2 キーペア、AMI など、ご使用の環境からの要件に応じ適切な情報を入力します。

10.    [次へ] を選択します。

11.    [オプション] セクションで、スタックに適切な情報を入力してから、[次へ] を選択します。

12.    AWS CloudFormation スタックで IAM リソースを作成できるようにするには、[AWS CloudFormation が IAM リソースを作成する可能性があることを了承します] のチェックボックスをオンにします。

13.    [作成] を選択します。

インスタンスのルートボリュームにタグを付ける

1.    Amazon EC2 コンソールを開きます。

2.    ナビゲーションペインの [Elastic Block Store] セクションで、[ボリューム] を選択します。

3.    [Filter] フィールドで、AWS CloudFormation スタックに設定したタグを入力して、ボリュームにタグが付けられていることを確認します。


この記事はお役に立ちましたか?

改善できることはありますか?


さらにサポートが必要な場合