今回の内容はAutomationにとりあえず触れてみて理解を深めることを目的としています。AWS CLIを使っている人にとっては、アクションがいくつかあること、変数、形の3つが追加的な情報になるかと思います。今回はAutomationでインスタンスの単純な再起動と、それに付随する操作について述べます。

ドキュメント作成

まずはドキュメントを作成します。
Systems Managerを開き、「オートメーションの実行」→「ドキュメントの作成」へと進み、エディタを選択します。
エディタ

参考:https://docs.aws.amazon.com/ja_jp/systems-manager/latest/userguide/documents-using.html#create-ssm-console

作成するドキュメントの内容は以下の通りです。以降はこのドキュメントがそれぞれどういうステップ・変数になっているかをご紹介します。

description: Stop and Start EC2 Instance
schemaVersion: '0.3'
assumeRole: '{{AutomationAssumeRole}}'
parameters:
  AutomationAssumeRole:
    type: String
    description: (Optional) The ARN of the role that allows Automation to perform the actions on your behalf.
    default: ''
  TargetInstance:
    type: String
    description: (Required) The target instance id
    default: null
mainSteps:
  - name: StopInstances
    action: 'aws:changeInstanceState'
    inputs:
      InstanceIds:
        - '{{TargetInstance}}'
      DesiredState: stopped
  - name: pauseThis
    action: 'aws:pause'
    inputs: {}
  - name: RunInstances
    action: 'aws:changeInstanceState'
    inputs:
      InstanceIds:
        - '{{TargetInstance}}'
      DesiredState: running
  - name: CheckInstanceStatus
    action: 'aws:executeAwsApi'
    maxAttempts: 10
    timeoutSeconds: 600
    inputs:
      Service: EC2
      Api: DescribeInstanceStatus
      InstanceIds:
        - '{{TargetInstance}}'
      Filters:
        - Name: instance-status.reachability
          Values:
            - passed
  - name: CheckSystemStatus
    action: 'aws:executeAwsApi'
    maxAttempts: 10
    timeoutSeconds: 600
    inputs:
      Service: EC2
      Api: DescribeInstanceStatus
      InstanceIds:
        - '{{TargetInstance}}'
      Filters:
        - Name: system-status.reachability
          Values:
            - passed

これはAutomation実行時にインスタンスを指定し、それをストップ/スタートさせるというものです。途中pauseThisというステップがあるように一旦停止し、再度実行させることで続きのステップが可能となります。EC2が1台のみの環境のメンテナンス対応では、このように単純なストップ・スタートを実行していることと思います。

ステータスチェックのAutomationのStepをAWS CLIと対比する

しかし、この他にちゃんと起動しているかチェックもしているはずです。具体的にはコンソールでインスタンスのステータスチェックが2/2で合格していることを確認すると思います。上記で紹介しているコードのうちの29行目以降がそれに当たります。以下抜粋します。

  - name: CheckInstanceStatus
    action: 'aws:executeAwsApi'
    maxAttempts: 10
    timeoutSeconds: 600
    inputs:
      Service: EC2
      Api: DescribeInstanceStatus
      InstanceIds:
        - '{{TargetInstance}}'
      Filters:
        - Name: instance-status.reachability
          Values:
            - passed
  - name: CheckSystemStatus
    action: 'aws:executeAwsApi'
    maxAttempts: 10
    timeoutSeconds: 600
    inputs:
      Service: EC2
      Api: DescribeInstanceStatus
      InstanceIds:
        - '{{TargetInstance}}'
      Filters:
        - Name: system-status.reachability
          Values:
            - passed

これはAPIを呼び出し実行しているものです。コンソールであれCLIであれ、AWSの様々なサービスはAPI経由でやりとりをしているので、これはCLIコマンドで表すことができます。

$ aws ec2 describe-instance-status --instance-ids i-xxxxxxxxxxxxxxxx --filters Name=instance-status.reachability,Values=passed
{
    "InstanceStatuses": [
        {
            "AvailabilityZone": "ap-northeast-1a",
            "InstanceId": "i-xxxxxxxxxxxxxxxx",
            "InstanceState": {
                "Code": 16,
                "Name": "running"
            },
            "InstanceStatus": {
                "Details": [
                    {
                        "Name": "reachability",
                        "Status": "passed"
                    }
                ],
                "Status": "ok"
            },
            "SystemStatus": {
                "Details": [
                    {
                        "Name": "reachability",
                        "Status": "passed"
                    }
                ],
                "Status": "ok"
            }
        }
    ]
}
$
$ aws ec2 describe-instance-status --instance-ids i-xxxxxxxxxxxxxxxx --filters Name=system-status.reachability,Values=passed
{
    "InstanceStatuses": [
        {
            "AvailabilityZone": "ap-northeast-1a",
            "InstanceId": "i-xxxxxxxxxxxxxxxx",
            "InstanceState": {
                "Code": 16,
                "Name": "running"
            },
            "InstanceStatus": {
                "Details": [
                    {
                        "Name": "reachability",
                        "Status": "passed"
                    }
                ],
                "Status": "ok"
            },
            "SystemStatus": {
                "Details": [
                    {
                        "Name": "reachability",
                        "Status": "passed"
                    }
                ],
                "Status": "ok"
            }
        }
    ]
}
$ 

もしCLIでpassedになっていない、つまりはステータスチェックが2/2になっていない場合は次のように出力されます。

$ aws ec2 describe-instance-status --instance-ids i-xxxxxxxxxxxxxxxx --filters Name=instance-status.reachability,Values=passed
{
    "InstanceStatuses": []
}
$ aws ec2 describe-instance-status --instance-ids i-xxxxxxxxxxxxxxxx --filters Name=system-status.reachability,Values=passed
{
    "InstanceStatuses": []
}
$

ほしい値である「passed」という記載がなく、上記のようにインスタンスの詳細が出てきません。この時はコマンドが間違っているか、インスタンスが意図する正しい状態になっているかをチェックすることになります。

このようにAPIを利用する場合(つまりアクションのaws:executeAwsApiを利用する場合)、コマンドはCLIに近いものになっています。
最終的にはAPIドキュメントのレファレンスを参照することになりますが、その前にAWS CLI Command Referenceを参考にコマンドを叩いてみてイメージをつかんでからそれをAutomationに置き換えると理解・作業がしやすいのではと思っています。(Automationでは「Api: DescribeInstanceStatus」ですが、CLIでは「describe-instance-status」といったように、近いけれども微妙に表記の仕方が違うことがありますので、CLIでイメージをつかんだ後にAPIドキュメントでより正確な表記に修正する必要があります。)

構成がALBにEC2に2台紐付いている冗長構成であれば、ターゲットグループへのデタッチ・アタッチなどの作業もあるかと思います。同様のものも上記CLIでイメージをつかみつつAutomationに組み込むということも可能です。

アクションのリファレンスを参考にどのアクションで実行するのか、APIを使う場合はCLIならどのようなコマンドをAutomationに合わせて記述していくのか、ということを意識していくことになります。

変数と形

次に変数と形についてです。
上記のドキュメントでは「TargetInstance」という変数を事前に指定し、それをそれぞれのステップのinstanceidsという形で入れてスタート・ストップさせています。

  TargetInstance:
    type: String
    description: (Required) The target instance id
    default: null

ここでは文字列を扱うことから「type: String」としていますが、「type: Integer」とすることで数字が扱えます。

例えばAMIを取得してそれを元にEC2をもう一台起動させたいというケースがあったとします。その場合はAutomation実行時に変数が事前指定できません。代わりに「output」を用いることでその変数の指定を引き継ぐことができます。(参照)今回は単純なステップの紹介にとどめたいと思いますので、ここでは省きます。

最後に形についてです。前出の変数と内容と近いのですが、Instance-status-checkのCLIの中ではintegerやstringなど種類に応じて入力するようになっています。(参照)JSONの構造もFiltersではやや込み入っています。これをAutomationに合わせた形にしていく必要があります。