この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
はじめに
以下のような 承認/作成フローを Systems Manager(SSM) オートメーションを使って実現してみます。
大まかな流れは以下のとおり
- 開発者は CFnスタック作成に必要なパラメータを入力して、SSMオートメーションを実行する
- SSMオートメーションは
管理者の承認
ステップに入る - 管理者は SSMオートメーションの内容を確認して、承認する
- SSMオートメーションは
CFnスタック作成
ステップに入る - SSMオートメーションは入力パラメータを元に CFnスタックを作成する
前提知識
SSMドキュメント
多くの人が知っているとおり、 AWS Systems Manager(SSM) でできることはとても多いです。 例えば 「EC2インスタンスに対して特定のコマンドを実行する」Run Command や 「一連のAWSアクションを自動化する」Automation などがあります。
これら SSM 各種機能で実施する定型アクションは AWS Systems Manager(SSM) ドキュメント の構文に従って書かれています。
SSMドキュメントの主な特徴は以下の通り
- YAML もしくは JSONで記述
- 異なるバージョンの作成や比較が可能
- アカウント間の共有が可能
- タイプ が存在して、タイプに合わせた スキーマバージョンを指定する必要がある
- 例えば Run Command の SSMドキュメントは
Command
タイプ。 スキーマバージョンは1.2, 2.0, 2.2
が使用できる - 例えば Automation の SSMドキュメントは
Automation
タイプ。 スキーマバージョンは0.3
を使用する必要がある
- 例えば Run Command の SSMドキュメントは
SSMドキュメントはマネジメントコンソールの AWS Systems Manager > Documents から参照できます。 SSMドキュメントは自身で作成することも可能ですが、 AWSで提供されている SSMドキュメントも豊富にあります。
SSMオートメーション
Systems Manager(SSM) オートメーション は EC2インスタンスや他AWSリソースに関連する 一連の運用作業を自動化するための機能です。
前述の SSMドキュメント(スキーマタイプ Automation
)を活用しています。
Automation で使われる SSMドキュメントは ランブック(runbook) と呼ばれます。
「承認プロセスを含んだ EC2インスタンスの起動/停止フロー」や 「承認プロセスを含んだ CFnスタック作成フロー」などがユースケースです。
もし AWS Config の修復機能を触ったことがある方は、 SSMオートメーションに馴染みがあるかもしれません。 Configルールの「修復アクション」の実態は SSMオートメーションです。
参考: 【AWS Config】EC2インスタンスに特定アプリケーションがインストールされているかチェックして通知する | DevelopersIO
構築
今回の検証で作る必要のあるリソースは以下の 4つです。
- SSMドキュメント: 「承認→CFnスタック作成」フローを記述するために必要です
- SNSトピック: 「承認」ステップで管理者に SNSトピック経由でメール通知を行います
- CFnテンプレート: 「CFnスタック作成」ステップで使うテンプレートです
- IAMロール: SSMオートメーションの実行ロールです
手間の掛からない順番に説明します。
SNSトピック
適宜作成して、管理者へメールが通知されるようにサブスクリプション設定を済ませます。
CFnテンプレート
今回は バケット名/Projectタグをパラメータとした S3バケットを作成するシンプルなテンプレートを使います。
AWSTemplateFormatVersion: '2010-09-09'
Parameters:
BucketName:
Type: String
ProjectName:
Type: String
Resources:
S3Bucket:
Type: AWS::S3::Bucket
Properties:
BucketName: !Ref BucketName
Tags:
- Key: Project
Value: !Ref ProjectName
これを S3バケットに格納しておきます。
IAMロール
SSMオートメーションの実行ロールです。以下を行う権限を付与します。
- SNSトピックに送信(Publish)する
- 後述する
aws:approve
アクションで必要な権限です
- 後述する
- CFnスタックを作成する
- 後述する
aws:createStack
アクションで必要な権限です
- 後述する
- S3バケットを作成する
- 同じく
aws:createStack
アクションで必要な権限ですが、 CFnテンプレートで作るリソースに依ります
- 同じく
今回は以下のように CFnテンプレートを使って作成しました。
AWSTemplateFormatVersion: '2010-09-09'
Parameters:
RoleName:
Type: String
Default: ssm-automation-role-for-creating-stack
Resources:
IamRole:
Type: AWS::IAM::Role
Properties:
RoleName: !Ref RoleName
Description: "role for ssm automation: create stack"
AssumeRolePolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: "Allow"
Principal:
Service: "ssm.amazonaws.com"
Action: "sts:AssumeRole"
Policies:
- PolicyName: policy-for-ssm-automation
PolicyDocument:
Version: "2012-10-17"
Statement:
# SNSトピックに送信(Publish)する
- Sid: approval
Effect: "Allow"
Action: "sns:Publish"
Resource: "*"
# CFnスタックを作成する
- Sid: createStack
Effect: "Allow"
Action:
- "sqs:*"
- "cloudformation:CreateStack"
- "cloudformation:DescribeStacks"
- "s3:GetObject"
Resource: "*"
# S3バケットを作成する
- Sid: createBucket
Effect: "Allow"
Action:
- "s3:CreateBucket"
- "s3:PutBucketTagging"
Resource: "*"
SSMドキュメント
以下のような SSMドキュメントを作成しました。 ハイライト部分を適宜書き換えてください。
schemaVersion: "0.3"
description: "create a new S3 bucket with approval"
assumeRole: "{{AssumeRole}}"
parameters:
AssumeRole:
description: "(Required) Automation Role."
type: String
default: "(先程作ったIAMロールのARN)"
allowedValues:
- "(先程作ったIAMロールのARN)"
SnsTopic:
description: "(Required) The SNS topic ARN used to send pending approval notification."
type: String
default: "(先程作ったSNSトピックのARN)"
allowedValues:
- "(先程作ったSNSトピックのARN)"
TemplateURL:
description: "(Required) CFn TemplateURL"
type: String
default: "(先程作ったCFnテンプレートの格納先 URL)"
allowedValues:
- "(先程作ったCFnテンプレートの格納先 URL)"
StackName:
description: "(Required) CFn StackName"
type: String
BucketName:
description: "(Required) Parameter: BucketName"
type: String
ProjectName:
description: "(Required) Parameter: ProjectName"
type: String
mainSteps:
- name: "approve"
action: "aws:approve"
onFailure: Abort
inputs:
NotificationArn: "{{SnsTopic}}"
Message: "Approval required to createStack: {{StackName}} (BucketName: {{BucketName}}, ProjectName: {{ProjectName}})"
MinRequiredApprovals: 1
Approvers:
- "(管理者のIAMロールARN)"
- name: "createStack"
action: "aws:createStack"
onFailure: Abort
inputs:
StackName: "{{StackName}}"
TemplateURL: "{{TemplateURL}}"
Parameters:
- ParameterKey: BucketName
ParameterValue: "{{BucketName}}"
- ParameterKey: ProjectName
ParameterValue: "{{ProjectName}}"
これを登録していきます。
マネコンの SSMドキュメント のページに行き、 オートメーションを作成する
を選択します。
名前を適当に記入(例えば CreateNewS3BucketWithApproval
) して、
ドキュメントエディタに貼り付けてオートメーションを作成します。
SSMドキュメント詳細
作成した SSMドキュメントの内容解説です。
「SSMドキュメントの構文や SSMオートメーションで使用可能なアクションを知りたい人」向けです。 必要ない場合は次章 "検証(利用の流れ)" をご覧ください。
全体構成
schemaVersion: "0.3"
description: "create a new S3 bucket with approval"
assumeRole: "{{AssumeRole}}"
parameters:
AssumeRole:
description: "(Required) Automation Role."
type: String
default: "(先程作ったIAMロールのARN)"
allowedValues:
- "(先程作ったIAMロールのARN)"
(略)
mainSteps:
- name: "approve"
action: "aws:approve"
(略)
- name: "createStack"
action: "aws:createStack"
(略)
大枠部分の構文は以下ドキュメントを読めば分かります。
schemaVersion は使用するスキーマバージョンです。
Automation
ドキュメントは 0.3
を指定する必要があります。
description はドキュメントの説明です。
assumeRole は SSMオートメーションの実行ロールを指定します。
後述のパラメータ AssumeRole
を参照しています。
parameters でパラメータを定義します。おおよそ CFnのパラメータと同じような使い方です。
"{{ParameterName}}"
といった形で他セクションで参照できます。
mainSteps で実行するアクションを連ねていきます。 「承認→作成」フローを書くセクションです。詳細は後述。
mainSteps#1(aws:approve
)
# "approve" ステップ
- name: "approve"
# 実行するアクション
action: "aws:approve"
# 失敗時の行動。Abotr(中止), Continue(続行), step:xxx(別ステップへ遷移)
onFailure: Abort
inputs:
# 通知先SNSトピック
NotificationArn: "{{SnsTopic}}"
# メッセージ
Message: "Approval required to createStack: {{StackName}} (BucketName: {{BucketName}}, ProjectName: {{ProjectName}})"
# 必要な承認の最小数
MinRequiredApprovals: 1
# 承認できるプリンシパルのリスト
Approvers:
- "(管理者のIAMロールARN)"
まず SSMオートメーションで実行可能なアクションのリファレンスは以下リンクから辿れます。
最初のステップでは aws:approve を使います。 指定した承認者から、必要数の承認を得られた場合に次のステップに進めます。
必要に応じて MinRequiredApprovals
(必要な承認の最小数) や
Approvers
(承認できるプリンシパルのリスト)を変更しましょう。
mainSteps#2(aws:createStack
)
# "createStack" ステップ
- name: "createStack"
# 実行するアクション
action: "aws:createStack"
# 失敗時の行動。Abotr(中止), Continue(続行), step:xxx(別ステップへ遷移)
onFailure: Abort
inputs:
# スタック名
StackName: "{{StackName}}"
# テンプレートURL
TemplateURL: "{{TemplateURL}}"
# CFnパラメータ
Parameters:
- ParameterKey: BucketName
ParameterValue: "{{BucketName}}"
- ParameterKey: ProjectName
ParameterValue: "{{ProjectName}}"
このステップでは aws:createStack を使います。 テンプレートを指定して新しい CFnスタックを作成するアクションです。
検証(利用の流れ)
[開発者] オートメーションを実行する
開発者は SSMのマネコンから、作成したドキュメントを選択します。
"オートメーションを実行する" を選択します。
デフォルトの "シンプルな実行" を選択したままで、 以下のようにパラメータを入力します。 AssumeRole, SnsTopic, TemplateURL は固定値にしているので、 開発者はスタック名と CFnパラメータ(作成したバケットの名前とプロジェクト名)を入力します。
内容確認して "実行" します。
[管理者] 承認する
SNS経由で管理者へメール通知されます。以下のような内容です。
Approve のリンクへ移動します。以下のような承認/拒否画面になります。
メッセージからリクエストされた情報(スタック名やパラメータ)を確認し、 承認を選択して "送信" します。
スタック作成を確認
スタック作成が成功する場合は、以下のように全ステップ "成功" となります。
CFnスタック、および スタックリソース(S3バケット)も確認できました。
おわりに
シンプルですが SSMオートメーションを使った CFnスタック展開の承認フローを作ってみました。
最近登場した Systems Manager Change Manager (変更管理のプロセス、承認フロー作成の機能) の 実態は オートメーションです。 Change Manager を触る前に、 今回みたいにオートメーションを軽く触ることでスムーズに理解が進むのではないでしょうか。
参考
- AWS Documents
- AWS Systems Manager ドキュメント - AWS Systems Manager
- AWS Systems Manager オートメーション - AWS Systems Manager
- SSM ドキュメントの構文 - AWS Systems Manager
- Systems Manager オートメーションアクションのリファレンス - AWS Systems Manager
- aws:approve – 手動承認のためにオートメーションを一時停止する - AWS Systems Manager
- aws: createStack – AWS CloudFormation スタックを作成する - AWS Systems Manager
- DevelopersIO