ぴよ丸水産

週末ファゴッティストによる技術ブログ

【AWS】Systems Manager 自作オートメーションドキュメント その2

はじめに

AWSのSystems Managerで、(以下SSM)
オートメーションドキュメントを自作したので、
やりたいこと別に紹介します!

前前回導入編を書いて、前回「その1」を書いて、
その続編的な何かです。

blue-38.hatenablog.com

blue-38.hatenablog.com

目次

■値を取得して別のステップで使いたい

ステップ1のレスポンスで帰ってきた値を変数に格納しておけば、
そのあとのステップで、
ステップ名.変数名みたいな感じで使用できます。

例えば、
対象EC2インスタンスのNameタグの値を取得してみます。

  - name: getNameTag
    action: 'aws:executeAwsApi'
    inputs:
      Service: ec2
      Api: DescribeTags
      Filters:
        - Name: resource-id
          Values:
            - '{{ InstanceId }}'
        - Name: key
          Values:
            - Name
    outputs:
      - Name: InstanceName
        Selector: 'Tags[0].Value'
        Type: String

上記のように取得すれば、後のステップで、
{{ getNameTag.InstanceName }}のように使えます。

ポイント

  • action: 'aws:executeAwsApi'で`APIを実行
    • DescribeXXXを使うことが多いかな
    • 期待するレスポンスを得るために、Filters:を使う
  • outputs:で格納する変数をName:に定義&格納する値へのパスをSelector:に記述
  • 使う時は、前述のとおり、{{ ステップ名.変数名 }}

■RDSのDBインスタンスを操作したい

メンテナンスウィンドウのターゲットに、
RDSのDBインスタンスを設定して、
オートメーションドキュメントで操作を自動化してみます。

まず、メンテナンスウィンドウでの
ターゲットの設定は、
Choose a resource group
リソースタイプがAWS::RDS::DBInstanceのリソースグループを指定するイメージです。
※EC2インスタンス以外のターゲットを指定する方法がこれしかない気がします。
※あれば知りたい

上記のようなメンテナンスウィンドウから
呼び出されるオートメーションドキュメントを書こうとしたときの注意点です。

parameters:
  DBInstanceId:
    type: String
    description: (Required) The DBInstance's ID.

たとえば、上記のように入力パラメータを定義し、
メンテナンスウィンドウでのタスク登録で、

f:id:blue-38:20200211212714p:plain
メンテナンスウィンドウ-タスク登録画面

こんな風に、{{ TARGET_ID }}を指定すると、
オートメーション実行時に、 DBInstanceIdに実際に入力される値は、
arn:aws:rds:ap-northeast-1:000000000000:db:piyomaru-dbのように、
ARNの値が入ってきます。

RDSを操作するようなAPIを使う場合って、
DB識別子が必須パラメータが多いので、
1ステップ目で、
ARNからDB識別子を取得するようにしてます。

mainSteps:
  - name: GetDBInstanceIdentifier
    action: 'aws:executeAwsApi'
    inputs:
      Service: rds
      Api: DescribeDBInstances
      Filters:
        - Name: db-instance-id
          Values:
            - '{{ DBInstanceId }}'
    outputs:
      - Name: DBInstanceIdentifier
        Selector: 'DBInstances[0].DBInstanceIdentifier'

■値を取得して別のステップで使いたい
おさらいですが、
取得したDB識別子は、この後のステップで、
GetDBInstanceIdentifier.DBInstanceIdentifierとして使えます。

動かし始めたとき、
DB識別子が入ってくれると勝手に勘違いしていたので、
紛らわしい命名になっていますが、
DBInstanceIdDBarnとかにすると分かりやすいかもですね。

続きの処理の例です。
スナップショット作成してみました。

  - name: CreateRDSSnapshot
    action: 'aws:executeAwsApi'
    inputs:
      Service: rds
      Api: CreateDBSnapshot
      DBInstanceIdentifier: '{{ GetDBInstanceIdentifier.DBInstanceIdentifier }}'
      DBSnapshotIdentifier: '{{ global:DATE }}-{{ GetDBInstanceIdentifier.DBInstanceIdentifier }}'

■分岐したい

スクリプトみたいに、
あまり器用なことはできませんが、
分岐の記法はあります。

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

ちょっと書いてみました。
対象のEC2インスタンスが特定のEC2インスタンスだった場合、
echo "Hello World"してね!そうじゃない場合は、眠りましょう!
というオートメーションドキュメントです。

description: Exec runCommand to specified Instance.
schemaVersion: '0.3'
parameters:
  InstanceId:
    type: String
    description: (Required) The ID of the Amazon EC2 instance.
mainSteps:
  - name: Jadgment Instance
    action: 'aws:branch'
    inputs:
      Choices:
        - NextStep: runCommand
          Variable: '{{ InstanceId }}'
          StringEquals: i-026828bd5e33fba70
      Default: Sleep
  - name: runCommand
    action: 'aws:runCommand'
    inputs:
      DocumentName: AWS-RunShellScript
      InstanceIds:
        - i-0000aaaa0000bbbb
      Parameters:
        commands:
          - 'echo "Hello World"'
    isEnd: true
  - name: Sleep
    action: 'aws:sleep'
    inputs:
      Duration: PT5S

ポイント

  • action:aws:branchを指定する
  • NextStep:に分岐先のステップ名を定義
    • 複数分岐条件があれば、複数定義できる
  • どの条件にも合致しない場合の分岐先はDefault:に定義
  • 分岐先で処理を終了する場合にはisEndを定義
    • 定義しておかないと、止まらずに上から下にそのまま流れてしまう

おわりに

「その2」はちょっと応用バージョンみたいなネタをまとめてみました。
ただ、あんまりアクロバットなことをするなら
Lambdaの方が適していると思います。
自作オートメーションドキュメントの実例はあまりネットに落ちてない気がするので、
誰かの役に立てば幸いです。