CloudFormation で EC2 インスタンスの EBS ルートボリュームにタグを付与する方法

2024.02.01

こんにちは、アノテーションの浅野です。

CloudFormation でルートボリュームにタグ付けしようとすると、EC2 インスタンスリソースのブロックデバイスマッピングプロパティにはボリュームにタグを付与するプロパティがありません。 そこで、CloudFormation の機能を用いたルートボリュームのタグ付け方法についてまとめてみましたので、皆さんにもシェアしたいと思います。

CloudFormation でルートボリュームにタグを付与する方法

CloudFormation でルートボリュームにタグを付与する方法は、次の 3 つの方法になります。

  1. UserData のスクリプトでタグを付与する方法
  2. AWS::EC2::LaunchTemplate の TagSpecification でルートボリュームにタグを付与する方法
  3. AWS::EC2::Instance の PropagateTagsToVolumeOnCreation を利用してタグ伝播でタグを付与する方法

順番にそれぞれの方法を確認していきましょう。

1. UserData のスクリプトでタグを付与する方法

AWS::EC2::Instance リソースの UserData プロパティを介して、ルートボリュームにタグを付ける方法です。 UserData を用いる方法については、既に詳細を解説した弊社ブログエントリがありますので、説明は割愛します。

なお、この方法は EC2 インスタンス作成後にタグを付与するので、ボリューム作成と同時にタグを設定をする要件がある場合は、残念ながら適しません。

2. AWS::EC2::LaunchTemplate の TagSpecification でルートボリュームにタグを付与する方法

AWS::EC2::LaunchTemplate リソースの TagSpecification プロパティを使用する方法です。
例えば、テンプレートは以下のように記述します。

AWSTemplateFormatVersion: '2010-09-09'
Resources:
  myLaunchTemplate:
    Type: AWS::EC2::LaunchTemplate
    Properties: 
      LaunchTemplateName: !Sub ${AWS::StackName}-launch-template
      LaunchTemplateData: 
        BlockDeviceMappings: 
          - Ebs:
              VolumeSize: 8
              VolumeType: gp3
              DeleteOnTermination: true
              Encrypted: true
            DeviceName: /dev/xvda
        TagSpecifications:
          - ResourceType: volume
            Tags:
            - Key: Name
              Value: hoge
        CreditSpecification: 
          CpuCredits: Unlimited
        Monitoring: 
          Enabled: true
        ImageId: ami-04d5cc9b88example
        InstanceType: t2.micro
        KeyName: !Ref KeyName
        SecurityGroupIds: 
          - sg-7c2270198example
          - sg-903004f88example

インスタンス作成と同時にルートボリュームへのタグ付けが行われました。

※ なお、タグを更新する場合は、EC2 インスタンスの置換が行われるので注意してください。

3. AWS::EC2::Instance の PropagateTagsToVolumeOnCreation を利用してタグ伝播でタグを付与する方法

AWS::EC2::Instance リソースの PropagateTagsToVolumeOnCreation プロパティを true に設定してインスタンスにタグを記述すると、インスタンス起動時にそれらのタグがインスタンスにアタッチされたすべてのボリュームに付与されます。

PropagateTagsToVolumeOnCreation Indicates whether to assign the tags from the instance to all of the volumes attached to the instance at launch. If you specify true and you assign tags to the instance, those tags are automatically assigned to all of the volumes that you attach to the instance at launch. If you specify false, those tags are not assigned to the attached volumes.

Required: No Type: Boolean

Update requires: No interruption

出典: AWS::EC2::Instance - AWS CloudFormation

テンプレート記述例は以下のようになります。

  MyEC2Instance: 
    Type: AWS::EC2::Instance
    Properties: 
      ImageId: ami-04d5cc9b88example
      KeyName: !Ref KeyName
      BlockDeviceMappings: 
      - DeviceName: /dev/xvda
        Ebs: 
          VolumeType: gp3
          DeleteOnTermination: true
          VolumeSize: 8
      PropagateTagsToVolumeOnCreation: true
      Tags:
        - Key: Name
          Value: hoge
        - Key: Environment
          Value: Dev

スタックをデプロイしたところ、EC2 インスタンスに設定したタグがルートボリュームにも付与されていることがわかります。

ec2_instance.json

{
    "Tags": [
        {
            "Key": "Environment",
            "ResourceId": "i-xxxxxxxxxxxxxxxxx",
            "ResourceType": "instance",
            "Value": "Dev"
        },
        {
            "Key": "Name",
            "ResourceId": "i-xxxxxxxxxxxxxxxxx",
            "ResourceType": "instance",
            "Value": "hoge"
        },
        {
            "Key": "aws:cloudformation:logical-id",
            "ResourceId": "i-xxxxxxxxxxxxxxxxx",
            "ResourceType": "instance",
            "Value": "EC2Instance"
        }
        (中略)
    ]
}

ebs_root_volume.json

[
    [
        {
            "Key": "Environment",
            "Value": "Dev"
        },
        {
            "Key": "Name",
            "Value": "hoge"
        }
    ]
]

ちなみに、この方法はドキュメントに記載の通り、インスタンスの起動時にタグ伝播する仕様のため、AWS::EC2::Instance の Tags プロパティを編集してタグの付け替えを行っても、EC2 インスタンスのタグは付け替えが反映されますが、ルートボリュームのタグには変更が反映されません。

最後に

今回のエントリでは、CloudFormation の機能を用いて EC2 インスタンスの EBS ルートボリュームにタグを付与する方法をまとめてみました。
現状 CloudFormation で提供されている方法の場合、ボリュームのタグを編集するときは、EC2 インスタンスの置き換えが行われたり、ルートボリューム単体のタグ編集ができなかったりと若干不便な感じがしますね。AWS::EC2::Instance BlockDeviceMapping でタグを指定することができれば、例えば、インスタンスのスタックに Retain DeletionPolicy を追加し、タグを変更してからインポートオペレーションを実施する等の方法が使えるので、インスタンスの置換を回避しつつ、ルートボリューム単体へカスタムしたタグを付与する、のようなことが実現できる気がします。

何はともあれ、この記事が少しでも誰かのお役に立てれば幸いです。

アノテーションの浅野でした。

参考情報

AWS resource and property types reference - AWS CloudFormation

アノテーション株式会社について

アノテーション株式会社はクラスメソッドグループのオペレーション専門特化企業です。サポート・運用・開発保守・情シス・バックオフィスの専門チームが、最新 IT テクノロジー、高い技術力、蓄積されたノウハウをフル活用し、お客様の課題解決を行っています。当社は様々な職種でメンバーを募集しています。「オペレーション・エクセレンス」と「らしく働く、らしく生きる」を共に実現するカルチャー・しくみ・働き方にご興味がある方は、アノテーション株式会社 採用サイトをぜひご覧ください。