はじめに
AWS環境でアカウントをまたいで2パターンあります。
リソースポリシーで別アカウントに対して直接アクセスを許可する
STSを使ってAssumeRoleする
基本的にリソースポリシーを使うほうがお手軽ですが、すべてのAWSサービスがサポートしているわけではなりません。
例えばAWS IoTでは使用できません。そういった場合は、AssumeRoleできるように構成する必要があります。
リソースポリシー
サポートしているものの例
Amazon S3 バケット
Amazon Simple Notification Service (Amazon SNS) トピック
Amazon Simple Queue Service (Amazon SQS) キュー
ECR リポジトリポリシー
https://docs.aws.amazon.com/ja_jp/AmazonECR/latest/userguide/set-repository-policy.html
API Gatewayリソースポリシー
https://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/apigateway-resource-policies.html
CodeCommit
https://docs.aws.amazon.com/ja_jp/codecommit/latest/userguide/auth-and-access-control-iam-access-control-identity-based.html
AssumeRoleする際の流れ
クロスアカウント→アカウントA
クロスアカウント先→アカウントB
前準備
アカウントBで対象のリソースにアクセス権限を持ったIAMロールを作成する
アカウントBでアカウントAのIAMロールやIAMユーザに対して、AssumeRole出来る権限を付与する
アカウントAでAssumeRole出来る権限を付与する
処理の流れ
アカウントAで認証
アカウントAでAssumeRole
アカウントAでアカウントBのリソースを操作する
AWS CLIを使って試してみます
アカウントBでの作業
アカウントBでIAMロールを作成する
IoT操作に必要な権限が記述されたIAMポリシーを作成したIAMロールに付与する
アカウントAでの作業
IAMポリシー作成
{
"Version": "2012-10-17",
"Statement": [
{
"Action": [
"sts:AssumeRole"
],
"Effect": "Allow",
"Resource": [ "arn:aws:iam::アカウントB:role/IAMロール名" ]
}
]
}
IAMユーザを作成してIAMポリシーをアタッチする
アクセスキー、シークレットアクセスキーを作成する
swtichというプロファイルでアクセスキー、シークレットアクセスキーを登録する
$ emacs .aws/credentials
[switch]
aws_access_key_id = <アクセスキー>
aws_secret_access_key = <シークレットアクセスキー>
AssumeRoleする先のIAMロールのARNと元になるプロファイルを指定する
$ emacs .aws/config [profile target]
role_arn = arn:aws:iam::<アカウントB>:role/<IAMロール>
source_profile = switch
アカウントBのIoTコンソールでtopic/testをサブスクライブする
topic/testに対してPublishする
$ aws --profile target --region ap-northeast-1 iot-data publish --topic topic/test --qos 1 --payload "publish from cli"
アカウントBのIoTコンソールでメッセージが表示されていることを確認する
node.jsで試す
npm init
npm install aws-sdk --save
npm install aws-iot-device-sdk --save
var AWS = require('aws-sdk');
var awsIot = require('aws-iot-device-sdk');
var params = {
RoleArn: '<アカウントBのIAMロールのARN>',
RoleSessionName: 'test'
};
AWS.config.update({
accessKeyId: "<アカウントAのアクセスキー>",
secretAccessKey: "<アカウントAのシークレットアクセスキー>",
region: "ap-northeast-1"
});
var topic = 'topic/test';
var sts = new AWS.STS();
sts.assumeRole(params, function (err, data) {
if (err)
console.log(err, err.stack);
else
var device = awsIot.device({
region: 'ap-northeast-1',
host: 'a2f3k5gm6f35cb-ats.iot.ap-northeast-1.amazonaws.com',
protocol: 'wss',
accessKeyId: data.Credentials.AccessKeyId,
secretKey: data.Credentials.SecretAccessKey,
sessionToken: data.Credentials.SessionToken,
clientId: '12345'
});
device.publish(topic, JSON.stringify({"message": "message from other AWS account"}));
});
$ npm start
> cross@1.0.0 start /Users/Work/cross
> node test.js
アカウントBのIoTコンソールにメッセージが出力されることを確認する
約束
投稿内容は私個人の意見であり、所属企業・部門見解を代表するものではありません。