AWS Systems Manager Distributor と Automation を使って、組織配下の EC2 にソフトウェアを配布してみた
はじめに
AWS Systems Manager Distributor は、ソフトウェアや設定用ファイルなどをパッケージとして登録し、Systems Manager 経由でマネージドインスタンスに配布できる機能です。
Run Command や Automation と組み合わせることで、対象インスタンスに一括でインストール処理を実行できます。
Distributor の概要については、以下の AWS Black Belt 資料やドキュメントが分かりやすいです。

今回は、管理アカウントから組織配下の複数メンバーアカウントに存在する EC2 インスタンスへソフトウェアを配布する構成を試しました。
管理アカウントで Distributor のパッケージドキュメントと Automation ランブックを作成し、管理アカウントからメンバーアカウントの EC2 に対して SSM Automation を実行します。
なお、SSM Automation 自体は複数リージョンに対して実行できます。
一方で、Distributor パッケージの作成・共有はリージョン単位で行う必要があり、クロスリージョン共有はできません。
そのため、複数リージョンで同じ構成を使う場合は、リージョンごとに Distributor パッケージを作成・共有したうえで、Automation を実行する必要があります。
今回の構成
まずは、今回の構成を整理します。
設定作業としては、以下を管理アカウント中心に行います。
- 管理アカウントで Distributor のパッケージドキュメントを作成する
- 管理アカウントでパッケージドキュメントをメンバーアカウントへ共有する
- 管理アカウントで Automation ランブックを作成する
- 管理アカウントとメンバーアカウントに、Automation 実行用 IAM ロールを作成する
そのうえで、実際の配布時には以下の流れで動作します。
- 管理アカウントから Automation を実行する
- 指定したメンバーアカウント側で
AWS-SystemsManager-AutomationExecutionRoleを使って child automation が実行される - ランブック内の
aws:runCommandがAWS-ConfigureAWSPackageを呼び出す - メンバーアカウント側の対象 EC2 が、共有済みのパッケージドキュメントを参照してパッケージをインストールする
つまり、実際にメンバーアカウントの EC2 にソフトウェアを入れるのは AWS-ConfigureAWSPackage であり、それを組織横断で起動するために Systems Manager Automation を使っている、という構成です。
前提条件
今回の検証では、Distributor 用のファイル一式はすでに用意済みとします。
Distributor パッケージ作成時は、ZIP ファイルと JSON マニフェストファイルを S3 にアップロードして作成します。
To create a package using the advanced workflow, you upload package files and a JSON manifest file to an Amazon S3 bucket.
高度なワークフローを使用してパッケージを作成するには、パッケージファイルと JSON マニフェストファイルを Amazon S3 バケットにアップロードします
https://docs.aws.amazon.com/ja_jp/systems-manager/latest/userguide/distributor-working-with-packages-create.html

また、今回の検証では以下を前提とします。
- 対象 EC2 はマネージドインスタンス
- EC2 のインスタンスプロファイルは
AmazonSSMManagedInstanceCoreのみ - 対象 EC2 から AWS 管理 S3 バケットへ到達できる
なお、Distributor でパッケージをインストールする際に、なぜ AWS 管理 S3 バケットへの到達性が必要なのかは、以下の記事で整理しています。
IAMロール
管理アカウントからメンバーアカウントに対して SSM Automation を実行するには、管理アカウントとメンバーアカウントの両方に IAM ロールを作成する必要があります。
今回は、以下の 2 つのロールを用意します。
- 管理アカウント
AWS-SystemsManager-AutomationAdministrationRole
- メンバーアカウント
AWS-SystemsManager-AutomationExecutionRole
管理アカウント側の AWS-SystemsManager-AutomationAdministrationRole の作成方法は、以下の記事を参考にしてください。
メンバーアカウント側の AWS-SystemsManager-AutomationExecutionRole は、対象アカウントが多い場合、CloudFormation StackSets でまとめてデプロイすると管理しやすいです。
また、管理アカウント自身にも配布対象の EC2 インスタンスがある場合は、管理アカウントにも AWS-SystemsManager-AutomationExecutionRole を CloudFormation スタックで作成しておく必要があります。
パッケージドキュメント作成
今回の検証では、SSM Distributor で、名前は test-1 としてパッケージドキュメントを管理アカウントで作成しました。

Distributor で作成されたパッケージは、Systems Manager 上ではパッケージドキュメントとして扱われます。
後続の AWS-ConfigureAWSPackage では、このパッケージドキュメントを指定してインストールします。
今回の検証では、バージョン 1.0.1 を作成し、default version に設定しました。

作成後は、メンバーアカウントに共有する必要があるため、共有先のアカウント ID を指定します。

対象アカウント数が多い場合は、コンソールではなく AWS CloudShell から一括で共有してもよいです。
aws ssm modify-document-permission \
--name "test-1" \
--permission-type "Share" \
--account-ids-to-add "111111111111" "222222222222" \
--region ap-northeast-1
--name には Distributor のパッケージ名を指定します。
この共有もリージョン単位なので、複数リージョンで使う場合はリージョンごとに実施します。
Automation ランブック
次に、管理アカウントで Automation ランブックを作成します。
Systems Manager のドキュメント画面に遷移し、[ドキュメントの作成] から [オートメーション] を選択します。

以下のコードを貼り付け、CM-InstallDistributorPackage という名前でAutomation ランブックを作成します。
description: Install shared Distributor package to one EC2 instance in target account
schemaVersion: '0.3'
assumeRole: '{{ AutomationAssumeRole }}'
parameters:
AutomationAssumeRole:
type: String
description: ARN of AWS-SystemsManager-AutomationAdministrationRole in management account
InstanceId:
type: String
description: Target EC2 instance ID in member account
PackageArn:
type: String
description: Shared Distributor package ARN
mainSteps:
- name: installPackage
action: aws:runCommand
isEnd: true
inputs:
DocumentName: AWS-ConfigureAWSPackage
InstanceIds:
- '{{ InstanceId }}'
Parameters:
installationType:
- Uninstall and reinstall
name:
- '{{ PackageArn }}'
action:
- Install
このランブックは、管理アカウント側で Automation を実行し、その中で aws:runCommand を使って AWS-ConfigureAWSPackage を呼び出す構成です。
それぞれのパラメータの役割は以下です。
AutomationAssumeRole- 管理アカウント側の
AWS-SystemsManager-AutomationAdministrationRoleを指定します
- 管理アカウント側の
InstanceId- メンバーアカウント側の対象 EC2 インスタンス ID を受け取ります
PackageArn- Distributor で作成したパッケージドキュメントの ARN を指定します
このランブックでは package version をパラメータ化していないため、AWS-ConfigureAWSPackage 実行時には Distributor 側の default version が使用されます。
今回の検証では、default version を 1.0.1 に設定しているため、メンバーアカウント側でも 1.0.1 がインストールされる想定です。
なお、今回の検証では、管理アカウントで作成したこの Automation ランブックをメンバーアカウントへ共有しなくても実行できました。
一方で、Distributor パッケージドキュメントはメンバーアカウントに共有する必要がありました。
SSM Automationを実行
作成したランブックを使用して、対象アカウントの EC2 インスタンスへソフトウェアを配布します。
EC2 の指定方法としては、タグ指定とインスタンス ID 指定があります。
今回は、インスタンス ID 指定で実行しました。
管理アカウントの AWS CloudShell に遷移し、配布先アカウント ID および EC2 インスタンス ID を指定して以下のコマンドを修正後、実行します。
aws ssm start-automation-execution \
--document-name "CM-InstallDistributorPackage" \
--parameters '{
"AutomationAssumeRole": ["arn:aws:iam::111111111111:role/AWS-SystemsManager-AutomationAdministrationRole"],
"PackageArn": ["arn:aws:ssm:ap-northeast-1:111111111111:document/test-1"]
}' \
--target-parameter-name "InstanceId" \
--target-locations '[
{
"Accounts": ["111111111111"],
"Regions": ["ap-northeast-1"],
"ExecutionRoleName": "AWS-SystemsManager-AutomationExecutionRole",
"Targets": [
{
"Key": "ParameterValues",
"Values": [
"i-xxxxxxxxxxxxxxxxxx",
"i-yyyyyyyyyyyyyyyyyyy"
]
}
],
"TargetLocationMaxConcurrency": "50",
"TargetLocationMaxErrors": "100%",
"TargetsMaxConcurrency": "5",
"TargetsMaxErrors": "100%"
},
{
"Accounts": ["222222222222"],
"Regions": ["ap-northeast-1"],
"ExecutionRoleName": "AWS-SystemsManager-AutomationExecutionRole",
"Targets": [
{
"Key": "ParameterValues",
"Values": [
"i-zzzzzzzzzzzz"
]
}
],
"TargetLocationMaxConcurrency": "50",
"TargetLocationMaxErrors": "100%",
"TargetsMaxConcurrency": "5",
"TargetsMaxErrors": "100%"
}
]' \
--region ap-northeast-1
複数アカウント・複数リージョンの Automation 実行については、以下のドキュメントも参考になります。
このコマンドのポイントは以下です。
--document-name- 実行する Automation ランブック名です
AutomationAssumeRole- 管理アカウント側の AdministrationRole を指定します
PackageArn- Distributor で作成したパッケージドキュメント ARN を指定します
--target-parameter-name "InstanceId"- ランブックの
InstanceIdパラメータへ、対象 EC2 を渡します
- ランブックの
--target-locations- アカウントごとに対象 EC2 をセットで指定します
TargetLocationMaxConcurrency- アカウント単位の同時実行数です
TargetsMaxConcurrency- 各アカウント内のインスタンス単位の同時実行数です
タグ指定にするとコマンド自体はシンプルになりますが、今回はアカウントごとに一部の EC2 のみに実行したかったため、インスタンス ID 指定にしました。
また、OU 指定や Root 指定で一括実行する方法もありますが、その場合は、指定したインスタンス ID が存在しないアカウントでも child automation が実行され、失敗ステータスになることがあります。
同様に、対象 EC2 が停止中である場合や、非マネージドインスタンスである場合も失敗するため、今回はアカウント ID とインスタンスIDを明示的に指定する方式にしています。
コマンドが正常に受け付けられると、以下のレスポンスが返ります。
{
"AutomationExecutionId": "4884d67a-6270-4f1e-82e1-cbd71c73e0e4"
}
配布時の動き
ここで、実際に配布時にどのような流れでメンバーアカウントへインストールされるのかを整理します。
- 管理アカウントで
start-automation-executionを実行する - 指定した対象アカウントごとに child automation が作成される
- 対象アカウント側で
AWS-SystemsManager-AutomationExecutionRoleを使ってランブックが実行される - ランブック内の
aws:runCommandが、対象 EC2 に対してAWS-ConfigureAWSPackageを実行する - 対象 EC2 が、共有済みのパッケージドキュメントを参照し、Distributor の default version をインストールする
つまり、管理アカウントから起動した Automation によって、メンバーアカウント側で AWS-ConfigureAWSPackage が実行され、その結果として対象 EC2 にパッケージがインストールされます。
Automation の実行結果を確認する
Automation の実行結果は、オートメーションページから実行 ID で検索すると確認できます。

該当の実行 ID をクリックし、各アカウントの実行ステータスが「成功」であることを確認します。

なお、管理アカウントからはメンバーアカウント側の詳細な Run Command 結果までは確認できませんでした。
詳細を確認したい場合は、各メンバーアカウントの Automation や Run Command ページで個別に確認してください。
まとめ
今回は、AWS Systems Manager Distributor と Automation を組み合わせて、管理アカウントから組織配下の複数メンバーアカウントの EC2 インスタンスへソフトウェアを配布する構成を試しました。
管理アカウントで作成した Distributor のパッケージドキュメントをメンバーアカウントへ共有し、Automation から AWS-ConfigureAWSPackage を実行することで、組織横断でソフトウェアを配布できることを確認できました。
また、一部の EC2 のみを対象にする場合は、OU 指定よりもアカウント ID とインスタンス ID をセットで指定する方式のほうが扱いやすいことも分かりました。
組織横断で EC2 に同じソフトウェアを展開したい場合、SSM Distributor と Automation の組み合わせは有効な選択肢の1つだと思います。
参考






