話題の記事

AWS Systems Manager から直接 AWS API をたたけるようになりました!

AWS Systems Manager から AWS API を呼び出すことができるようになりました。CloudFront のキャッシュクリア(Invalidation)を例に、実際に試してみます。
2018.08.29

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

本日(現地時間の 8/28)、AWS Systems Manager に AWS API を直接呼び出す機能が追加されました。控えめに言って 革命です

何が出来るようになった?

  • YAML を書くだけで、AWS CLI から出来ること はたいていのことが AWS Systems Manager のマネジメントコンソールから実行可能になった
  • もちろん従来通り、実行前に承認を待ったり、権限をその YAML (ドキュメント)に AssumeRole させることも可能

オペ業務的にいえば、AWS CLI を順に実行するだけのようなシェルスクリプトは ほぼ全てこれに置き換えることが可能 と言えば良いでしょうか。多分過言ですが気持ち的にはそのような勢いです。

もちろんこれまででも、AWS Systems Manager から AWS Lambda 関数や Step Functions を起動することはできましたから、Lambda を介すことで AWS API を叩くことは出来ました。Run Command を使って AWS CLI を叩くことも可能です。ただしこれからは、Lambda 関数をコーディングすることも、Run Command 用の EC2 や書かれたコードを管理したりメンテナンスしたりする必要もありません。

YAML を書けばいいだけです1

例 : CloudFront キャッシュクリアする Automation ドキュメントを作る

試しに、CloudFront の特定ディストリビューションを Invalidation (所謂キャッシュクリア)してみましょう。まずこのような YAML を用意しました。

---
description: CloudFront Invalidation
schemaVersion: "0.3"
assumeRole: "{{ AutomationAssumeRole }}"
parameters:
  DistributionId:
    type: String
    description: (Required) CloudFront Distribution Id to invalidate cache contents
  Path:
    type: String
    description: (Required) Information about the objects that you want to invalidate.
    default: "/*"
  AutomationAssumeRole:
    type: String
    description: (Optional) The ARN of the role that allows Automation to perform the actions on your behalf.
    default: ""
mainSteps:
  - name: InvalidateCFDistribution
    action: aws:executeAwsApi
    inputs:
      Service: cloudfront
      Api: CreateInvalidation
      DistributionId: "{{DistributionId}}"
      InvalidationBatch:
        CallerReference: "{{global:DATE_TIME}}"
        Paths:
          Items:
            - "{{Path}}"
          Quantity: 1
    isEnd: true

18行目から下が、新しい Action である aws:executeAwsApi を使って CloudFront の CreateInvalidation API を叩いているところです。

その上の部分で、下記をパラメータとして入力できるようにしました。

  • DistributionId : 所謂ディストリビューションID
  • Path : Invalidation するパス(デフォルト値は「全て (/*)」)

Assume Role の ARN を指定できるようにするのは、ドキュメントの作法のようなものなので、あまり気にしなくても良いです(今回は使いません)。

こちらの内容でドキュメントを作成し、実行してみます。大きな手順は下記記事と変わらないので、あわせてご参照下さい。

AWS Systems Manager で EC2 のバックアップを取得(ドキュメント作成・手動実行篇)

ドキュメントの作成

AWS Systems Manager のコンソール画面から「ドキュメント」をクリックし、右上の「Create document」をクリックします。

ドキュメントの作成画面になるので、

  • 名前 : 何でも良いのですが、ここでは CM-CloudFrontInvalidation としました
  • ドキュメントタイプ : 今回は自動実行で使用するので「オートメーションドキュメント」を選択します
  • コンテンツ : まず YAML を選択し、下のフォームに上の YAML をコピペします

設定できたら右下の「ドキュメントの作成」をクリックして下さい。これで作成されます。

ちなみに何か間違えた! と思ったら、さっきのドキュメントの画面から検索して削除すれば ok です。

実行

それでは試してみます。今回は下記の CloudFront ディストリビューションを対象に実行してみます。

左の「オートメーション」をクリックし、右上の「オートメーションの実行」をクリックします。

開いた画面で、いま作成したドキュメント CM-CloudFrontInvalidation をクリックします。ドキュメント名や所有者などで検索すると見つけやすいでしょう。

ドキュメントを選択すると、いろいろと入力フォームが現れますが、「実行モード」と「ターゲットとレート制御」は今回触らなくて良いです。

入力パラメーターのところで、対象となるディストリビューションのIDとパスを入力します。

入力に問題がなければ、右下の「オートメーションの実行」をクリックして下さい。実行画面に切り替わり、CreateInvalidation APIがコールされます。

問題がなければ、ステータスは「成功」になるでしょう。

CloudFront のコンソールを確認してみると、見事 Invalidation が動いていました。簡単ですね!

もちろんこのドキュメントは再利用できますし、適切な Assume Role 設定で権限設計をしたり、他のステップを組み合わせて一連の流れとすることも可能です。

YAML の解説

今回の要である YAML のうち、aws:executeAwsApi の部分について解説します。この部分は AWS API の構造やエレメントをそのまま持ってきた感じです。

mainSteps:
  - name: InvalidateCFDistribution
    action: aws:executeAwsApi
    inputs:
      Service: cloudfront
      Api: CreateInvalidation
      DistributionId: "{{DistributionId}}"
      InvalidationBatch:
        CallerReference: "{{global:DATE_TIME}}"
        Paths:
          Items:
            - "{{Path}}"
          Quantity: 1

CreateInvalidation の API ドキュメントと見比べてみましょう。

POST /2018-06-18/distribution/DistributionId/invalidation HTTP/1.1
<?xml version="1.0" encoding="UTF-8"?>
<InvalidationBatch xmlns="http://cloudfront.amazonaws.com/doc/2018-06-18/">
   <CallerReference>string</CallerReference>
   <Paths>
      <Items>
         <Path>string</Path>
      </Items>
      <Quantity>integer</Quantity>
   </Paths>
</InvalidationBatch>

まず Service のところに API のサービス名である cloudfront を、Api には API 名 CreateInvalidation をそのまま書きます。

続いて DistributionId なのですが、実は最初は書き方がわからなかったため適当に試したところ、下記のエラーから記述方法がわかりました。

Missing required parameter in input: "DistributionId"
Missing required parameter in input: "InvalidationBatch"

また InvalidationBatchPaths の書き方についても、同様にいろいろ試してみているうちに「 'str'じゃなくて 'dict'で書け 」「'dict'じゃなくて 'list'で書け」と言われたため、そのまま YAML の書き方を修正しました。

Invalid type for parameter InvalidationBatch,
value: <CallerReference>2018-08-29_07.56.26</CallerReference><Paths><Items><Path>/*</Path></Items><Quantity>integer</Quantity></Paths>, 
type: <class 'str'>,
valid types: <class 'dict'>
Invalid type for parameter InvalidationBatch.Paths.Items, 
value: {'Path': '/*'}, 
type: <class 'dict'>, 
valid types: <class 'list'>, <class 'tuple'>

現状はこうやってトライアンドエラーするしかないのですが、既に膨大な量のある AWS API を全て文書(ドキュメント)に起こすことは実質不可能ですし、ご覧のとおり素直に実装されているため、新しい API を使ってドキュメントを書くことも難しくないかと思います。

※08/29 追記

AWS Solutions Architect の大村様 よりフォローを頂きました。例えば今回の例の `Paths` の場合、下記のドキュメントをたどっていくことで、InvalidationBatch や Paths のデータ型がわかるとのことでした。情報ありがとうございました!

また CallerReference については、API ドキュメントによると「一意の文字列」を記入とあるので、AWS Systems Manager の組み込み変数 global:DATE_TIME をつかってタイムスタンプを指定しています。

まとめ

AWS Systems Manager は、様々な運用業務を適切に権限分離し、自動化・定形化できる部分はして、運用担当者が運用に集中できるよう考えて作られたサービスです。とはいえこれまでは、使える場面も正直限られていたと思いますが、今回の機能追加で活躍可能な場がぐんと広がったと思います。

AWS Systems Manager といえば Run Command しか使ったことがない、という方も多いかと思いますが、AWS の運用は自動化定形化して楽してなんぼなので、是非使いこなしてみて下さい!

注釈


  1. もちろん JSON でもいいです