カスタムAutomationをクロスアカウント実行する時にハマった話

北海道でも雪解けが進み、自転車を解禁したakiraです。最近は、平日の朝にジムに行って筋トレ、交代浴をすることにハマっています。
本ブログは趣味でハマっていることではなく、仕事でハマったことを書いていきたいと思います。
今回ハマったこととその原因
今回やりたかったこととハマったこと
管理アカウントから、SSMカスタムAutomationを実行して、対象アカウントのEC2へのアプリケーションインストールなどを自動化したいと考えていました。公式ドキュメントに沿ったRole作成後に、Automationを実行したところ、以下のエラーメッセージが発生しました。
The execution role arn:aws:iam::XXXXXXXXXXX:role/AWS-SystemsManager-AutomationExecutionRole in the target location is unable to be assumed.
原因の切り分けのために実行Roleを確認しましたが問題なく、AWSが保有しているのAutomationでは問題なく実行できました。今回作成したカスタムAutomationの問題を検証してみたのですが、同一アカウント内では問題なく実行でき完全にハマってしまいました…
エラー原因
結論から申し上げると、カスタムAutomationのアカウント共有が不足していたことが原因でした。これで終わってしまっては学びが少ないので、本ブログではAutomationのクロスアカウント実行がどのように実行され、なぜカスタムAutomationのみがアカウント共有を必要とするのかを解説します。
SSM Automationのクロスアカウント実行
SSM Automationとは
SSM Automationは、AWS Systems Managerの機能の1つで、システムの設定やメンテナンスを自動化するためのサービスです。
AWSが管理するマネージドAutomationを使用することもできますが、カスタムAutomationを使用することで、独自のAutomationを作成できます。たとえば、以下のように複数のRunコマンドやシェル実行、API実行を組み合わせて、システムの設定やメンテナンスを自動化できます。

SSM Automationの詳細については、以下のドキュメントをご参照ください。

カスタムAutomationのクロスアカウント実行
Automationのクロスアカウント実行にあたっては以下の手順を実行する必要があります。
- 管理アカウントにてAWS-SystemsManager-AutomationAdministrationRoleを作成
- 対象となるアカウントでAWS-SystemsManager-AutomationExecutionRoleを作成
- 管理アカウントでAutomationを作成
- 対象となるアカウントへ作成したAutomationを共有
- 管理アカウントでAutomationを実行
クロスアカウント実行はAWS Organizationsを利用する場合と、利用しない場合のどちらでも利用可能です。本ブログでは、AWS Organizationsを利用しない場合のクロスアカウント実行について解説します。
以下、各ステップについて以下にて簡単に解説します。実行するCloudFormationテンプレートは以下のページを参照ください。

1. 管理アカウントにてAWS-SystemsManager-AutomationAdministrationRoleを作成
まずAWS-SystemsManager-AutomationAdministrationRole.zipをダウンロードして、CloudFormationテンプレートを実行します。
作成されるIAM RoleではAWS Systems Managerへの信頼ポリシーが定義されています。
Condition句との組み合わせでSystems Managerのオートメーション実行からarn:aws:ssm:*:*:automation-execution/*
というパターンにマッチするARNからのリクエストの場合のみSystems Managerこのロールを引き受けることができます。
- サンプル:AWS-SystemsManager-AutomationAdministrationRole.yml
-
AWSTemplateFormatVersion: '2010-09-09' Description: 'Configure the AWS-SystemsManager-AutomationAdministrationRole to enable use of AWS Systems Manager Cross Account/Region Automation execution.' Resources: MasterAccountRole: Type: AWS::IAM::Role Properties: RoleName: AWS-SystemsManager-AutomationAdministrationRole AssumeRolePolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Principal: Service: ssm.amazonaws.com Action: - sts:AssumeRole Condition: ArnLike: aws:SourceArn: Fn::Sub: arn:aws:ssm:*:*:automation-execution/* Path: "/" Policies: - PolicyName: AssumeRole-AWSSystemsManagerAutomationExecutionRole PolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Action: - sts:AssumeRole Resource: Fn::Sub: arn:${AWS::Partition}:iam::*:role/AWS-SystemsManager-AutomationExecutionRole
2. 対象となるアカウントでAWS-SystemsManager-AutomationExecutionRoleを作成
次にAWS-SystemsManager-AutomationExecutionRole.zipをダウンロードして、CloudFormationテンプレートを実行します。
作成されるIAM Roleでは管理アカウントのAWS-SystemsManager-AutomationAdministrationRoleおよびSystems Managerからの引き受けを許可しています。Systems Managerのオートメーション内でアクションを実行する際に、適切な権限を受け渡すためにiam:PassRole権限が自身のロールに限定されて付与されています。
- サンプル:AWS-SystemsManager-AutomationExecutionRole.yml
-
AWSTemplateFormatVersion: "2010-09-09" Description: "Configure the AWS-SystemsManager-AutomationExecutionRole." Parameters: AdminAccountId: Type: String Description: AWS Account ID of the primary account (the account from which AWS Systems Manager Automation will be initiated). MaxLength: 12 MinLength: 12 Resources: AWSSystemsManagerAutomationExecutionRole: Type: AWS::IAM::Role Properties: RoleName: AWS-SystemsManager-AutomationExecutionRole AssumeRolePolicyDocument: Version: "2012-10-17" Statement: - Effect: Allow Principal: AWS: Fn::Sub: - arn:aws:iam::${AdminAccountId}:role/AWS-SystemsManager-AutomationAdministrationRole - AdminAccountId: Ref: AdminAccountId Action: sts:AssumeRole - Effect: Allow Principal: Service: ssm.amazonaws.com Action: - sts:AssumeRole Condition: StringEquals: aws:SourceAccount: Fn::Sub: ${AWS::AccountId} ArnLike: aws:SourceArn: Fn::Sub: arn:aws:ssm:*:${AWS::AccountId}:automation-execution/* ManagedPolicyArns: - arn:aws:iam::aws:policy/service-role/AmazonSSMAutomationRole Path: "/" Policies: - PolicyName: ExecutionPolicy PolicyDocument: Version: "2012-10-17" Statement: - Effect: Allow Action: - resource-groups:ListGroupResources - tag:GetResources - ec2:DescribeInstances Resource: "*" - Effect: Allow Action: - iam:PassRole Resource: Fn::Sub: arn:${AWS::Partition}:iam::${AWS::AccountId}:role/AWS-SystemsManager-AutomationExecutionRole
3. 管理アカウントでAutomationを作成
実行したい内容をAutomationで作成します。今回は本題とはそれるので、Automationの作成方法は省略します。
4. 対象となるアカウントへ作成したAutomationを共有
作成したAutomationを対象となるアカウントに共有します。共有にはアカウントIDを指定して共有します。

5. 管理アカウントでAutomationを実行
AWSコンソール、もしくはaws cliを使用してAutomationを実行します。

なぜカスタムAutomationのみがアカウント共有を必要とするのか
やっと本題ではありますが、なぜカスタムAutomationのみがアカウント共有を必要とするのかを解説します。
そのためにまずは、Automationのクロスアカウント実行の流れを整理します。
Automationのクロスアカウント実行の流れ
今回の構成は以下のようになります。

図内の番号で実行される内容は以下になります。
- まず、管理アカウントにてAWS-SystemsManager-AutomationAdministrationRoleが呼び出されます
- 次にAWS-SystemsManager-AutomationExecutionRoleへとAssumeRoleします
- AWS-SystemsManager-AutomationExecutionRoleは対象アカウント上で指定されたAutomationを実行します
- Automationに含まれるRunブックもAWS-SystemsManager-AutomationExecutionRoleによって実行されます
改めて原因の解説
整理の中で理解いただけているかもしれませんが、カスタムAutomationのみがアカウント共有を必要とする理由は実行ロールが対象アカウント上でAutomationを実行するためです。
AWS-SystemsManager-AutomationExecutionRoleには管理アカウントへのAssumeやAutomationの実行権限が無いためエラーになったということです。

AWSマネージドのAutomationの場合、AWSから各アカウントにあらかじめ共有されているためアカウント共有を意識せずとも実行できたというわけです。
おまけ
実はAutomationの共有については公式ドキュメントに記載がありました…

注記の内容を見落としてだいぶハマったわけですがクロスアカウント実行の仕組みやアカウント感での共有が必要となる理由を理解できたことは良かったと思います。
※読者の皆様も見落としにはご注意ください
まとめ
SSM Automationのクロスアカウント実行についてハマった理由なども含めて解説しました。そもそもの原因は私の見落としではあるのですが、詳細に各ロールの動きを理解することでアカウント共有が必要な理由がわかりました。
SSM Automationのクロスアカウントを利用することでマルチアカウント管理がとても楽になりますが、注意点も多くあります。本ブログでは実行自体や、実行結果の通知などには触れることが出来なかったので次の機会に解説したいと思います。
本ブログがSSM Automationのクロスアカウント実行について理解するきっかけになれば幸いです。