SSM Automationを使用してAMIを作成する(単発/定期)
AMIを作成する方法はいくつかあります。
例えばマネージメントコンソールから作成する方法が、以下のページで紹介されています。
AWS CLIを使用しても作成することができます。
https://docs.aws.amazon.com/cli/latest/reference/ec2/create-image.html
今回はSSM オートメーションランブック AWS-CreateImageを使用して、AMIを作成することを考えます。
具体的には以下の2つを実施します。
- SSMオートメーションランブックの関連付けを作成して、単発でイメージを作成する。
- メンテナンスウィンドウを設定して、定期的にメー時を作成する。
構築する環境
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ロールに付与する権限は、以下のページを参考にしました。
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を参照することができます。
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つのリソース(メンテナンスウィンドウ、ターゲット、タスク)を定義します。
詳細につきましては、以下のページをご確認ください。
メンテナンスウィンドウ本体のポイントはScheduleプロパティです。
rate式を使用して、15分に1回実行するように指定します。
ターゲットのポイントはTargetsプロパティです。
メンテナンスウィンドウの対象となるインスタンスを指定します。
インスタンスの指定はタグ情報に基づいて行うことができます。
今回は以下のタグが設定されているインスタンスを、関連付けの対象とします。
- タグのキー:CreateImage
- タグの値:Group2
ポイントはタスクのTaskInvocationParametersプロパティです。
先述の関連付けと同様に設定します。
具体的には、イメージ作成用のIAMロールと、インスタンスIDを疑似リソースを指定します。
環境構築
CloudFormationを使用して、本環境を構築し、実際の挙動を確認します。
CloudFormationスタックを作成し、スタック内のリソースを確認する
CloudFormationスタックを作成します。
スタックの作成および各スタックの確認方法については、以下のページをご確認ください。
各スタックのリソースを確認した結果、今回作成された主要リソースの情報は以下の通りです。
- インスタンス1:i-0bdf9464a3d6c1f90
- インスタンス2:i-03ccfb5347cd623d5
- インスタンス1とのSSM関連付け:657587dd-a930-4ac8-8d38-49effcab7dc5
- インスタンス2用のメンテナンスウィンドウ:fa-118-MaintenanceWindow
動作確認
準備が整いましたので、AWS Management Consoleから各リソースを確認します。
SSM関連付け
SSM関連付けを確認します。
SSM AutomationランブックAWS-CreateImageに関する関連付けが作成されていることがわかります。
この関連付けのターゲットを見ると、タグ名CreateImageの値が「Group1」であるインスタンスが対象であることがわかります。
つまりインスタンス1がこの関連付けのターゲットとなります。
ランブックの実行ログを確認します。
ランブックが正常に実行されて、AMI(ami-0f36d15af67832dfa)が作成されたことが読み取れます。
実行時の各ステップの詳細なログを確認することもできます。
確かにインスタンス1を対象として、アクション(aws:createImage)が実行されて、AMIが作成されたことが確認できます。
作成されたAMIを確認します。
確かにインスタンス1からAMIが作成されています。
このようにSSM関連付けを作成して、EC2インスタンスに対して、SSM AutomationランブックAWS-CreateImageを実行することによって、単発でAMIを作成することができました。
メンテナンスウィンドウ
メンテナンスウィンドウを確認します。
15分に1回、処理を実行するメンテナンスウィンドウが作成されていることがわかります。
メンテナンスウィンドウのタスクを見ると、ランブックAWS-CreateImageを実行する内容であることが読み取れます。
メンテナンスウインドウのターゲットを見ると、タグ名CreateImageの値が「Group2」であるインスタンスが対象であることがわかります。
つまりインスタンス2がターゲットになります。
メンテナンスウィンドウの実行ログを確認します。
2回ランブックが実行されたことが読み取れます。
確かに実行間隔は15分に1回です。
2つの実行履歴を確認します。
確かに各実行時にインスタンス2からAMIが作成されていることがわかります。
最後に作成されたAMIを確認します。
インスタンス1から作成されたAMIに加えて、インスタンス2から作成された2つのAMIも確認できます。
このようにメンテナンスウィンドウを作成して、EC2インスタンスに対して、SSM AutomationランブックAWS-CreateImageを実行することによって、定期的にAMIを作成することができました。
まとめ
SSM関連付け、またはメンテナンスウィンドウを作成することによって、SSM AutomationランブックAWS-CreateImageを実行することで、EC2インスタンスからAMIを単発/定期的にAMIを作成する方法を確認しました。