SSM Automationを使用してAMIを作成する(単発/定期)

SSM Automationを使用してAMIを作成する(単発/定期)

SSM Automationを使用してAMIを作成する(単発/定期)

AMIを作成する方法はいくつかあります。

例えばマネージメントコンソールから作成する方法が、以下のページで紹介されています。

https://docs.aws.amazon.com/ja_jp/toolkit-for-visual-studio/latest/user-guide/tkv-create-ami-from-instance.html

AWS CLIを使用しても作成することができます。

https://docs.aws.amazon.com/cli/latest/reference/ec2/create-image.html

今回はSSM オートメーションランブック AWS-CreateImageを使用して、AMIを作成することを考えます。

https://docs.aws.amazon.com/ja_jp/systems-manager-automation-runbooks/latest/userguide/automation-aws-createimage.html

具体的には以下の2つを実施します。

  • SSMオートメーションランブックの関連付けを作成して、単発でイメージを作成する。
  • メンテナンスウィンドウを設定して、定期的にメー時を作成する。

構築する環境

Diagram of creating AMI using SSM Automation (one-time/scheduled)

1つのプライベートサブネット内に2つのEC2インスタンスを作成します。
インスタンスは最新のAmazon Linux 2とします。

両インスタンスにSSMオートメーションランブック AWS-CreateImageを実行して、イメージを取得します。
一方のインスタンスはSSM関連付けを作成して、単発でランブックを実行します。
もう一方のインスタンスはメンテナンスウィンドウを作成して、定期的(15分に1回)にランブックを実行します。

CloudFormationテンプレートファイル

上記の構成をCloudFormationで構築します。
以下のURLにCloudFormationテンプレートを配置しています。

https://github.com/awstut-an-r/awstut-fa/tree/main/118

テンプレートファイルのポイント解説

SSM Automation用IAMロール

Resources:
  CreateImageRole:
    Type: AWS::IAM::Role
    DeletionPolicy: Delete
    Properties:
      AssumeRolePolicyDocument:
        Version: 2012-10-17
        Statement:
          - Effect: Allow
            Action: sts:AssumeRole
            Principal:
              Service:
                - ssm.amazonaws.com
      Policies:
        - PolicyName: CreateImagePolicy
          PolicyDocument:
            Version: 2012-10-17
            Statement:
              - Effect: Allow
                Action:
                  - ec2:CreateImage
                  - ec2:DescribeInstances
                Resource:
                  - "*"
Code language: YAML (yaml)

AWS-CreateImageを使用してAMIを作成するためには、SSMにAMIを作成する権限を与える必要があります。
SSMをプリンシパルとするIAMロールを作成します。
IAMロールに付与する権限は、以下のページを参考にしました。

https://docs.aws.amazon.com/ja_jp/systems-manager-automation-runbooks/latest/userguide/automation-aws-createimage.html

SSM関連付け

Resources:
  CreateImageAssociation:
    Type: AWS::SSM::Association
    Properties:
      AssociationName: !Sub "${Prefix}-createimage-association"
      AutomationTargetParameterName: InstanceId
      Name: AWS-CreateImage
      Parameters:
        AutomationAssumeRole:
          - !Ref CreateImageRoleArn
        InstanceId:
          - "{{RESOURCE_ID}}"
      Targets:
        - Key: !Sub "tag:${TagKey}"
          Values:
            - !Ref TagValue1
      WaitForSuccessTimeoutSeconds: !Ref WaitForSuccessTimeoutSeconds
Code language: YAML (yaml)

Targetsプロパティで関連付けの対象を指定します。
今回は以下のタグが設定されているインスタンスを、関連付けの対象とします。

  • タグのキー:CreateImage
  • タグの値:Group1

ParametersプロパティでAWS-CreateImageを実行する際のパラメータを指定します。
AutomationAssumeRoleに先述のIAMロールを指定します。
InstanceIdには「{{RESOURCE_ID}}」を指定します。
これは疑似パラメータと呼ばれるもので、この記法を使用することによって、各インスタンスのIDを参照することができます。

https://docs.aws.amazon.com/ja_jp/systems-manager/latest/userguide/mw-cli-register-tasks-parameters.html

AutomationTargetParameterNameプロパティで、疑似パラメータを使用して、オートメーションが分岐するパラメータを指定します。
今回は「InstanceId」に疑似パラメータを指定しましたので、これを指定します。

メンテナンスウィンドウ

Resources:
  MaintenanceWindow:
    Type: AWS::SSM::MaintenanceWindow
    Properties:
      AllowUnassociatedTargets: true
      Cutoff: 1
      Description: My-First-Maintenance-Window
      Duration: 2
      Name: !Sub "${Prefix}-MaintenanceWindow"
      Schedule: rate(15 minutes)
      ScheduleTimezone: Asia/Tokyo

  MaintenanceWindowTarget:
    Type: AWS::SSM::MaintenanceWindowTarget
    Properties:
      Name: !Sub "${Prefix}-MaintenanceWindowTarget"
      ResourceType: INSTANCE
      Targets:
        - Key: !Sub "tag:${TagKey}"
          Values:
            - !Ref TagValue2
      WindowId: !Ref MaintenanceWindow

  MaintenanceWindowTask:
    Type: AWS::SSM::MaintenanceWindowTask
    Properties:
      MaxConcurrency: 1
      MaxErrors: 1
      Name: !Sub "${Prefix}-MaintenanceWindowTask"
      Priority: 10
      Targets:
        - Key: WindowTargetIds
          Values:
            - !Ref MaintenanceWindowTarget
      TaskArn: AWS-CreateImage
      TaskInvocationParameters:
        MaintenanceWindowAutomationParameters:
          Parameters:
            AutomationAssumeRole:
              - !Ref CreateImageRoleArn
            InstanceId:
              - "{{RESOURCE_ID}}"
      TaskType: AUTOMATION
      WindowId: !Ref MaintenanceWindow
Code language: YAML (yaml)

メンテナンスウィンドウを設定するために、3つのリソース(メンテナンスウィンドウ、ターゲット、タスク)を定義します。
詳細につきましては、以下のページをご確認ください。

https://awstut.com/2023/02/05/set-up-maintenance-window-to-schedule-ssm-patch-manager

メンテナンスウィンドウ本体のポイントはScheduleプロパティです。
rate式を使用して、15分に1回実行するように指定します。

ターゲットのポイントはTargetsプロパティです。
メンテナンスウィンドウの対象となるインスタンスを指定します。
インスタンスの指定はタグ情報に基づいて行うことができます。
今回は以下のタグが設定されているインスタンスを、関連付けの対象とします。

  • タグのキー:CreateImage
  • タグの値:Group2

ポイントはタスクのTaskInvocationParametersプロパティです。
先述の関連付けと同様に設定します。
具体的には、イメージ作成用のIAMロールと、インスタンスIDを疑似リソースを指定します。

環境構築

CloudFormationを使用して、本環境を構築し、実際の挙動を確認します。

CloudFormationスタックを作成し、スタック内のリソースを確認する

CloudFormationスタックを作成します。
スタックの作成および各スタックの確認方法については、以下のページをご確認ください。

https://awstut.com/2021/12/02/cloudformation-nested-stacks

各スタックのリソースを確認した結果、今回作成された主要リソースの情報は以下の通りです。

  • インスタンス1:i-0bdf9464a3d6c1f90
  • インスタンス2:i-03ccfb5347cd623d5
  • インスタンス1とのSSM関連付け:657587dd-a930-4ac8-8d38-49effcab7dc5
  • インスタンス2用のメンテナンスウィンドウ:fa-118-MaintenanceWindow

動作確認

準備が整いましたので、AWS Management Consoleから各リソースを確認します。

SSM関連付け

SSM関連付けを確認します。

Detail of SSM 1.
Detail of SSM 2.

SSM AutomationランブックAWS-CreateImageに関する関連付けが作成されていることがわかります。

この関連付けのターゲットを見ると、タグ名CreateImageの値が「Group1」であるインスタンスが対象であることがわかります。
つまりインスタンス1がこの関連付けのターゲットとなります。

ランブックの実行ログを確認します。

Detail of SSM 3.

ランブックが正常に実行されて、AMI(ami-0f36d15af67832dfa)が作成されたことが読み取れます。

実行時の各ステップの詳細なログを確認することもできます。

Detail of SSM 4.

確かにインスタンス1を対象として、アクション(aws:createImage)が実行されて、AMIが作成されたことが確認できます。

作成されたAMIを確認します。

Detail of AMI 1.

確かにインスタンス1からAMIが作成されています。

このようにSSM関連付けを作成して、EC2インスタンスに対して、SSM AutomationランブックAWS-CreateImageを実行することによって、単発でAMIを作成することができました。

メンテナンスウィンドウ

メンテナンスウィンドウを確認します。

Detail of SSM 5.
Detail of SSM 6.
Detail of SSM 7.

15分に1回、処理を実行するメンテナンスウィンドウが作成されていることがわかります。

メンテナンスウィンドウのタスクを見ると、ランブックAWS-CreateImageを実行する内容であることが読み取れます。

メンテナンスウインドウのターゲットを見ると、タグ名CreateImageの値が「Group2」であるインスタンスが対象であることがわかります。
つまりインスタンス2がターゲットになります。

メンテナンスウィンドウの実行ログを確認します。

Detail of SSM 8.

2回ランブックが実行されたことが読み取れます。
確かに実行間隔は15分に1回です。

2つの実行履歴を確認します。

Detail of SSM 9.
Detail of SSM 10.

確かに各実行時にインスタンス2からAMIが作成されていることがわかります。

最後に作成されたAMIを確認します。

Detail of AMI 2.

インスタンス1から作成されたAMIに加えて、インスタンス2から作成された2つのAMIも確認できます。

このようにメンテナンスウィンドウを作成して、EC2インスタンスに対して、SSM AutomationランブックAWS-CreateImageを実行することによって、定期的にAMIを作成することができました。

まとめ

SSM関連付け、またはメンテナンスウィンドウを作成することによって、SSM AutomationランブックAWS-CreateImageを実行することで、EC2インスタンスからAMIを単発/定期的にAMIを作成する方法を確認しました。