Automation、AWS Lambda、Parameter Store を使用してゴールデン AMI を更新する - AWS Systems Manager

Automation、AWS Lambda、Parameter Store を使用してゴールデン AMI を更新する

次の例では、Amazon Elastic Compute Cloud (Amazon EC2) AMIs から構築するのではなく、組織が独自の AMIs を維持し、定期的にパッチを適用するモデルを使用しています。

次の手順は、最新または最後の AMI であると既にみなされている AMI にオペレーティングシステム (OS) のパッチを自動的に適用する方法を示しています。この例では、パラメータ SourceAmiId のデフォルト値は、latestAmi という AWS Systems Manager Parameter Store のパラメータによって定義されます。latestAmi の値は、オートメーションの終了時に呼び出される AWS Lambda 関数によって更新されます。このオートメーションプロセスの結果として、パッチ適用が常に最新の AMI に適用されるため、AMIs のパッチ適用に費やされる時間と労力が最小限に抑えられます。Parameter Store とオートメーションは、AWS Systems Manager の機能です。

開始する前に

Automation ロール、およびオプションで、Automation 用の Amazon EventBridge を設定します。詳細については、「オートメーションの設定」を参照してください。

タスク 1: Systems Manager Parameter Store でパラメータを作成する

Parameter Store で以下の情報を使用する文字列パラメータを作成します。

  • Name (名前)latestAmi]: 。

  • : AMI ID。例: ami-188d6e0e

Parameter Store の文字列パラメータの作成方法については、「Systems Manager での Parameter Store パラメータの作成」を参照してください。

タスク 2: 用の IAM ロールを作成するAWS Lambda

の IAM サービスロールを作成するために、次の手順を使用しますAWS Lambda これらのポリシーは、Lambda に Lambda 関数および Systems Manager を使用して、latestAmi パラメータの値を更新する権限を与えます。

Lambda の IAM サービスロールを作成するには
  1. AWS Management Console にサインインして、IAM コンソール (https://console.aws.amazon.com/iam/) を開きます。

  2. ナビゲーションペインで、[Policies] を選択し、次に [Create policy] を選択します。

  3. [JSON] タブを選択します。

  4. デフォルトのコンテンツを次のポリシーに置き換えます。各リソースプレースホルダーの例をユーザー自身の情報に置き換えます。

    { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": "logs:CreateLogGroup", "Resource": "arn:aws:logs:region:123456789012:*" }, { "Effect": "Allow", "Action": [ "logs:CreateLogStream", "logs:PutLogEvents" ], "Resource": [ "arn:aws:logs:region:123456789012:log-group:/aws/lambda/function name:*" ] } ] }
  5. [Next: Tags] (次へ: タグ) を選択します。

  6. (オプション) 1 つ以上のタグキーと値のペアを追加して、このポリシーのアクセスを整理、追跡、または制御します。

  7. [次へ: レビュー] を選択します。

  8. [Review policy (ポリシーの確認)] ページで、[Name (名前)] にインラインポリシーの名前を入力します (amiLambda など)。

  9. [Create policy] を選択します。

  10. ステップ 2 と 3 を繰り返します。

  11. 次のポリシーを貼り付けます。各リソースプレースホルダーの例をユーザー自身の情報に置き換えます。

    { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": "ssm:PutParameter", "Resource": "arn:aws:ssm:region:123456789012:parameter/latestAmi" }, { "Effect": "Allow", "Action": "ssm:DescribeParameters", "Resource": "*" } ] }
  12. [Next: Tags] (次へ: タグ) を選択します。

  13. (オプション) 1 つ以上のタグキーと値のペアを追加して、このポリシーのアクセスを整理、追跡、または制御します。

  14. [次へ: レビュー] を選択します。

  15. [Review policy (ポリシーの確認)] ページで、[Name (名前)] にインラインポリシーの名前を入力します (amiParameter など)。

  16. [Create policy] を選択します。

  17. ナビゲーションペインで [Roles] を選択し、続いて [Create role] を選択します。

  18. [ユースケース] のすぐ下で、[Lambda][次へ] の順に選択します。

  19. [アクセス許可の追加] ページで [検索] フィールドを使用し、前に作成した 2 つのポリシーを見つけます。

  20. ポリシーの横にあるチェックボックスをオンにして、[次へ] を選択します。

  21. [ロール名] に、新しいロールの名前を入力 (lambda-ssm-role など) するか、希望する別の名前を入力します。

    注記

    多くのエンティティによりロールが参照されるため、作成後にロール名を変更することはできません。

  22. (オプション) 1 つ以上のタグキーと値のペアを追加して、このロールのアクセスを整理、追跡、制御し、[ロールの作成] を選択します。

タスク 3: AWS Lambda 関数を作成する

latestAmi パラメータの値を自動的に更新する Lambda 関数を作成するには、次の手順を使用します。

Lambda 関数を作成するには
  1. AWS Management Console にサインインして AWS Lambda コンソール (https://console.aws.amazon.com/lambda/) を開きます。

  2. [Create function] を選択します。

  3. [Create function] ページで、[Author from scratch] を選択します。

  4. [関数名] に「Automation-UpdateSsmParam」と入力します。

  5. ランタイム] では、Python 3.8] を選択します。

  6. [アーキテクチャ] で、関数の実行に使用する Lambda のコンピュータープロセッサーのタイプ、[x86_64] または [arm64] を選択します。

  7. [アクセス許可] セクションで、[デフォルトの実行ロールの変更] を展開します。

  8. [Use an existing role (既存のロールの使用)] を選択し、タスク 2 で作成した Lambda のサービスロールを選択します。

  9. [Create function] を選択します。

  10. [コードソース] 領域の [lambda_function] タブで、フィールドにあらかじめ入力されているコードを削除し、次のコードサンプルを貼り付けます。

    from __future__ import print_function import json import boto3 print('Loading function') #Updates an SSM parameter #Expects parameterName, parameterValue def lambda_handler(event, context): print("Received event: " + json.dumps(event, indent=2)) # get SSM client client = boto3.client('ssm') #confirm parameter exists before updating it response = client.describe_parameters( Filters=[ { 'Key': 'Name', 'Values': [ event['parameterName'] ] }, ] ) if not response['Parameters']: print('No such parameter') return 'SSM parameter not found.' #if parameter has a Description field, update it PLUS the Value if 'Description' in response['Parameters'][0]: description = response['Parameters'][0]['Description'] response = client.put_parameter( Name=event['parameterName'], Value=event['parameterValue'], Description=description, Type='String', Overwrite=True ) #otherwise just update Value else: response = client.put_parameter( Name=event['parameterName'], Value=event['parameterValue'], Type='String', Overwrite=True ) responseString = 'Updated parameter %s with value %s.' % (event['parameterName'], event['parameterValue']) return responseString
  11. [ファイル]、[保存] の順に選択します。

  12. Lambda 関数をテストするには、[テスト] メニューで、[テストイベントの設定] を選択します。

  13. [Event name] で、MyTestEvent など、テストイベントの名前を入力します。

  14. 既存のテキストを次の JSON に置き換えます。[AMI ID] をユーザー自身の情報に置き換え、latestAmi パラメータ値を設定します。

    { "parameterName":"latestAmi", "parameterValue":"AMI ID" }
  15. [Save] を選択します。

  16. [テスト (Test)] を選択して関数をテストします。[実行結果] タブに、更新に関するその他の詳細とともに、ステータスが [成功] として報告されます。

タスク 4: ランブックを作成し、AMI にパッチを適用する

以下の手順を使用して、[latestAmi] パラメータに指定した AMI にパッチを適用したランブックを作成して実行します。オートメーションが完了すると、latestAmi の値は、新しくパッチ適用された AMI の ID で更新されます。以降のオートメーションは、以前の実行で作成された AMI を使用します。

ランブックを作成して実行するには
  1. AWS Systems Manager コンソール (https://console.aws.amazon.com/systems-manager/) を開きます。

  2. ナビゲーションペインで、[ドキュメント] を選択します。

  3. [ドキュメントの作成][オートメーション] を選択します。

  4. [名前]UpdateMyLatestWindowsAmi と入力します。

  5. [Editor (エディタ)] タブを選択し、次に [Edit (編集)] を選択します。

  6. プロンプトが表示されたら、[OK] を選択します。

  7. [ドキュメントエディタ] フィールドで、デフォルトのコンテンツを、次の YAML サンプルランブックコンテンツに置き換えます。

    --- description: Systems Manager Automation Demo - Patch AMI and Update ASG schemaVersion: '0.3' assumeRole: '{{ AutomationAssumeRole }}' parameters: AutomationAssumeRole: type: String description: '(Required) The ARN of the role that allows Automation to perform the actions on your behalf. If no role is specified, Systems Manager Automation uses your IAM permissions to execute this document.' default: '' SourceAMI: type: String description: The ID of the AMI you want to patch. default: '{{ ssm:latestAmi }}' SubnetId: type: String description: The ID of the subnet where the instance from the SourceAMI parameter is launched. SecurityGroupIds: type: StringList description: The IDs of the security groups to associate with the instance that's launched from the SourceAMI parameter. NewAMI: type: String description: The name of of newly patched AMI. default: 'patchedAMI-{{global:DATE_TIME}}' InstanceProfile: type: String description: The name of the IAM instance profile you want the source instance to use. SnapshotId: type: String description: (Optional) The snapshot ID to use to retrieve a patch baseline snapshot. default: '' RebootOption: type: String description: '(Optional) Reboot behavior after a patch Install operation. If you choose NoReboot and patches are installed, the instance is marked as non-compliant until a subsequent reboot and scan.' allowedValues: - NoReboot - RebootIfNeeded default: RebootIfNeeded Operation: type: String description: (Optional) The update or configuration to perform on the instance. The system checks if patches specified in the patch baseline are installed on the instance. The install operation installs patches missing from the baseline. allowedValues: - Install - Scan default: Install mainSteps: - name: startInstances action: 'aws:runInstances' timeoutSeconds: 1200 maxAttempts: 1 onFailure: Abort inputs: ImageId: '{{ SourceAMI }}' InstanceType: m5.large MinInstanceCount: 1 MaxInstanceCount: 1 IamInstanceProfileName: '{{ InstanceProfile }}' SubnetId: '{{ SubnetId }}' SecurityGroupIds: '{{ SecurityGroupIds }}' - name: verifyInstanceManaged action: 'aws:waitForAwsResourceProperty' timeoutSeconds: 600 inputs: Service: ssm Api: DescribeInstanceInformation InstanceInformationFilterList: - key: InstanceIds valueSet: - '{{ startInstances.InstanceIds }}' PropertySelector: '$.InstanceInformationList[0].PingStatus' DesiredValues: - Online onFailure: 'step:terminateInstance' - name: installPatches action: 'aws:runCommand' timeoutSeconds: 7200 onFailure: Abort inputs: DocumentName: AWS-RunPatchBaseline Parameters: SnapshotId: '{{SnapshotId}}' RebootOption: '{{RebootOption}}' Operation: '{{Operation}}' InstanceIds: - '{{ startInstances.InstanceIds }}' - name: stopInstance action: 'aws:changeInstanceState' maxAttempts: 1 onFailure: Continue inputs: InstanceIds: - '{{ startInstances.InstanceIds }}' DesiredState: stopped - name: createImage action: 'aws:createImage' maxAttempts: 1 onFailure: Continue inputs: InstanceId: '{{ startInstances.InstanceIds }}' ImageName: '{{ NewAMI }}' NoReboot: false ImageDescription: Patched AMI created by Automation - name: terminateInstance action: 'aws:changeInstanceState' maxAttempts: 1 onFailure: Continue inputs: InstanceIds: - '{{ startInstances.InstanceIds }}' DesiredState: terminated - name: updateSsmParam action: aws:invokeLambdaFunction timeoutSeconds: 1200 maxAttempts: 1 onFailure: Abort inputs: FunctionName: Automation-UpdateSsmParam Payload: '{"parameterName":"latestAmi", "parameterValue":"{{createImage.ImageId}}"}' outputs: - createImage.ImageId
  8. [Create automation (オートメーションを作成)] を選択します。

  9. ナビゲーションペインで、[オートメーション]、[オートメーションの実行] の順に選択します。

  10. [Choose document] (ドキュメントを選択) ページで、[Owned by me] (自分が所有) タブを選択します。

  11. UpdateMyLatestWindowsAmi ランブックを検索し、UpdateMyLatestWindowsAmi カードのボタンを選択します。

  12. [Next] を選択します。

  13. [ Simple execution (シンプルな実行)] を選択します。

  14. 入力パラメータの値を指定します。

  15. [実行] を選択します。

  16. 実行の完了後に、ナビゲーションペインで [Parameter Store] を選択し、latestAmi の新しい値がオートメーションから返された値と一致することを確認します。新しい AMI ID が、Amazon EC2 コンソールの [AMIs] セクションに表示される Automation の出力と一致することを確認することもできます。