概要
AWSで複数アカウントを運用していると、場合によってはアカウントをまたいでアクセスしたいことがあります。
その辺りで使える要素技術の知見が溜まってきたのでまとめておきます。
アカウントをまたいでアクセスすることをクロスアカウントアクセスと言います。
https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/reference_policies_evaluation-logic-cross-account.html
IAM
AWSアカウントAからAWSアカウントBへアクセスして、なにかしらのリソースへ参照、更新などの作業を行いたい場合があるとします。
その場合は、AssumeRoleを使い、一時的にクロスアカウント先のIAMを使用するように許可することでクロスアカウント先のリソースを操作が行えます。
下記の例では、AWSアカウントAにあるEC2はAWSアカウントA内のリソース制御をIAM_Aというロール(インスタンスプロファイル)を使用しているとします。
このインスタンスプロファイルにはS3_Aにアクセスできる権限があるとします。
このIAM_Aを使用して、AWSアカウントBにあるEC2_Bの参照を行いたいとします。
構成
IAM_AのポリシーにIAM_Bへのsts:AssumeRole権限を付与します。
{
"Version": "2012-10-17",
"Statement": [
{
"Sid" : "AssumeRoleAccessIAMB"
"Effect" : "Allow"
"Action" : "sts:AssumeRole"
"Resource" : "arn:aws:iam::AWSアカウントB:role/IAM_B"
},
{
"S3_Aへのアクセス権限"
}
]
}
IAM_Bの信頼関係に、IAM_AからのAssumeRoleを信頼するようにします。
{
"Version": "2008-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::xxxxxxxxxxx:role/iam_a"
},
"Action": "sts:AssumeRole",
}
}
]
}
IAM_BのIAMポリシーで許可したいアクセスを追加します(今回で言えばEC2への参照権限)
IAM_AからIAM_Bへアクセスをする場合、そのままではAWSアカウントAへアクセスしてしまうため、AWSアカウントBへアクセスする場合はAssumeRoleして、一時的にAWSアカウントBの認証情報が必要です。
※下記はShellでの実行例
CREDS_JSON="$(
aws sts assume-role \
--role-arn ${ROLE_ARN_QA} \
--role-session-name ${ROLE_SESSION_NAME} \
--output json
)"
export AWS_ACCESS_KEY_ID="$(printf '%s' "${CREDS_JSON}" | jq -r '.Credentials.AccessKeyId')"
export AWS_SECRET_ACCESS_KEY="$(printf '%s' "${CREDS_JSON}" | jq -r '.Credentials.SecretAccessKey')"
export AWS_SESSION_TOKEN="$(printf '%s' "${CREDS_JSON}" | jq -r '.Credentials.SessionToken')"
export AWS_REGION="${REGION}"
export AWS_DEFAULT_REGION="${REGION}"
aws sts get-caller-identity --no-cli-pager
SecurityGroup
通常、AWSのSecurityGroup(以下SG)を活用してアクセス制限を行いますが、クロスアカウントでもクロスアカウントしている先のSecurityGroupにクロスアカウント元のSGを使って、アクセス制限が可能です。
例えば、クロスアカウント先のRDSのSGの接続元に、別のAWSアカウントにあるSGを指定するという場合です。
下記の例では、クロスアカウント元、つまりアクセス元とします。
クロスアカウント先、つまりアクセス先とします。
アクセス元であるEC2からアクセス先であるRDSへアクセスを行いますが、その際にアクセス先のRDSのSGにアクセス元のEC2が使用しているSGを3306でアクセス許可するという例です。
構成
前提条件
- VPCピアリング済みであること
設定方法
AWSアカウントBのSecurityGroupRDS でSecurityGroupEC2をそのまま指定しようとしても、一覧から出てきません。
しかし、SecurityGroupIDの書き方を通常の sg-xxxxx という書き方ではなく AWSアカウントID/sg-xxxxx にするだけでOKです。
SGとしてはリンクにはなりませんが、これでアクセス制御ができるようになります。
私は知りませんでしたが2016年3月1日からできたようです。
https://aws.amazon.com/jp/about-aws/whats-new/2016/03/announcing-support-for-security-group-references-in-a-peered-vpc/
同一AWSアカウント場合の話
通常SGはVPCに紐つくため同一AWSアカウント同士でもVPCをまたいだ場合、異なるVPCのSGは表示されません。
しかし、SGから「VPC関連付け」という機能を使用して任意のVPCと関連付けをすることで、VPCをまたいで使用することも可能になり、SG一覧で選択できるようにもなります。
SGのVPC関連付けは2024年10月30日から可能となっています。
https://aws.amazon.com/jp/about-aws/whats-new/2024/10/amazon-virtual-private-cloud-security-group-sharing/
AWS RAM(AWS Resource Access Manager)
AWS RAMを使用することで、AWS Organizationsの使用有無に関わらず、特定の機能のみクロスアカウントで操作を許可することが可能です。
また、AWS Organizationsを使用している場合は、組織内のAWSアカウントのみに許可ということも可能です。
前提条件
ありとあらゆるものが共有できるかどうかというと、そんなことは全くなく、かなり限定的なリソースのみ、且つ特定の操作が許可されています。
例えば、ECRのイメージなどはRAMを使ってリソース共有は行うことができません(ECRやKMS、S3バケットなどはそもそもそれらがクロスアカウントで許可することが可能なポリシー制御がある)。
RDSもクラスターごと共有可能ですが、クラスターのリソースそのものを許可するというわけではなく、クラスターのクローンのみを許可できます。
面白いことにクラスターそのものへの削除も参照も一切できません。
AWS CLIも存在を確認するのに、--include-sharedを指定する必要があります。
aws rds describe-db-clusters --no-cli-pager --include-shared
RAMでリソースを共有した先のアカウントにてdelete,modify,describe instancesを試しましたがクラスターそのものが見つからないとなりました(--include-sharedに至ってはCLIではオプションそのものが見つからないとなります)
ですので、リソースをまるごと共有していると思うと、面食らいます。
できることがかなり限られるため、上記共有可能なAWSリソースを参照してできることを確認したうえで使用するのが良さそうです。
構成要素
RDSを共有したい場合、下記の要素があります。
- RDS(共有したいリソース)
- RAM Resource Shared(リソースを共有する単位、グループのようなもの)
- RAM Shared Resources(共有するリソース、arn単位)
- 最初に共有したいリソースを選択します。
セキュリティグループも共有できるのかと思いきや、共有はできるのですがEC2などで使用するにはVPCサブネットごと共有しないと使用ができないという罠もあります(RAMで共有しただけでは例えばEC2のSG選択画面で選択ができません)。
- https://docs.aws.amazon.com/ja_jp/vpc/latest/userguide/security-group-sharing.html
- https://dev.classmethod.jp/articles/aws-shared-security-group-guide/
上記だけで、RAMにいくと自分が共有しているリソース、自分が共有されているリソースが確認できます。
逆に言うと、普段見ているコンソールではでてこなかったりするので注意が必要です。
例えばパラメータストアの一覧に共有したパラメータは表示されません。
RDS
クロスアカウント先で、RDSを参照したいとします。
この場合、いろいろな方法が考えられます。
例えば、先述のVPCピアリングとSGによる制御があります。
それとは別に、クラスター自体をクローンして使いたい場合は、上述のRAMを使うことが可能です。
可能ですが、これはこれで制約が多いので注意が必要です。
KMSによる暗号化有無
特にKMSがポイントになります。
KMSを使用して暗号化している場合、マネージドなKMSキーかカスタマー管理かで変わります。
もし暗号化している場合、そのキーが aws/rds となっているかどうかで判断できます。
aws/rdsとなっている場合、AWSマネージドキーなのでこの後の少し複雑な対応が必要です。
KMSキーで暗号化されている場合、クロスアカウント先ではそのクラスターにアクセスするためのKMSキーへのアクセスが行えないため、操作が一切できません。
仮にRAMでクラスターごと共有しても、クローンしようとするとKMSキーへのアクセスができずにエラーとなります。
そのためKMSキーそのものへ、クロスアカウントのアクセス許可が必要です。
しかしながら、マネージドなKMSキーはキーポリシーが最低元のアクセス許可となっており追加で設定できないため、クロスアカウントでのアクセスを許可できません。
この場合、カスタマー管理のKMSキーを使用する必要があります。
カスタマー管理のKMSキーではキーポリシーが追加でき、下記を追加することでクロスアカウントでもアクセスができるようになります。
{
"Sid": "Allow attachment of persistent resources",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::クロスアカウント先のAWSアカウント:root"
},
"Action": [
"kms: 必要な権限"
],
"Resource": "*",
"Condition": {
"Bool": {
"kms:GrantIsForAWSResource": "true"
}
}
}
スナップショットの共有
RDSのスナップショットにはクロスアカウントへの共有という機能があります。
しかし、これは自動スナップショットでは使用できません。
手動スナップショットのみ可能となります。
ただ、そのために毎回手動スナップショットを取得しなくても、スナップショット自体をコピーすることが可能です。
自動で取得したスナップショットをカスタマー管理のKMS Keyを指定することで、クロスアカウントアクセス可能なKMSキーでスナップショットがコピーできます。
しかもコピー自体はまるごとコピーしていないようで、かなり大きめのデータでも数分でコピーが完了します。
条件分岐
上記のややこしい話をまとめると下記のようなフローチャートとなります。
AWS Lattice Resource Gateway
クロスアカウント先のInternal ALBやPrivateSubnetにあるEC2へアクセスしたい場合に、インターネットを経由しないでアクセスするにはNLB+PrivateLinkを使用した場合と、Resource Gatewayを使用したパターンがあります。
VPCエンドポイントにはEC2インスタンス接続エンドポイントもあり、同一AWSアカウント内でVPCピアリングせずにVPCをまたいで他のEC2にアクセスする方法もあるようです(未検証)
Lattice Resource Gatewayについては理解が難しいところもあるため少し厚めに説明します。
構成
従来は前者のNLB+PrivateLinkのみの構成となり、ALBがある構成の場合、多段LB構成となっていました。
VPC Lattice Resource Gatewayを使用すると、下記のように多段LBが不要となります。
AWS RAMの要素が増える分は複雑になりますが、
- NLBリソースを管理しなくてよくなること
- NLBより若干安価になること
- CIDR重複などの対応も可能となること
以上がメリットとして挙げられます。
構成に必要な要素
- AWSアカウントA
- ResourceGateway(リソースゲートウェイ)
- ResourceConfiguration(リソース設定)
- AWS RAM
- AWSアカウントB
- VPCエンドポイント(AWS RAMで共有されたResourceConfigratuinを連携)
各種設定
AWSアカウントA(アクセス先)
最初にResourceGatewayを作成します。
ここではResourceConfigurationとの連携は行えません。

次に、ResourceConfigratuionを設定します。
アクセスをさせるためのリソースが定義でき、EC2などのIPアドレスを単一で設定したり、リソースグループを設定することでドメイン単位でアクセスさせることも可能です。
ここで連携するResourceGatewayを定義します。
ResourceConfiguratinを設定すると、AWS RAMで共有ができます。
リソースタイプは「VPCラティスのリソース構成」となっており、若干日本語に表記揺れが発生しているので注意が必要です。

この状態でクロスアカウント先(アクセス元)で参照ができるようになっているはずです。

AWSアカウントB(アクセス元)
アクセス元のAWSアカウントでVPCエンドポイントを作成します。
その際にリソースを選択すると、AWS RAMで共有されているResourceConfiguratinを選択できるようになります。

以上で作成ができます。アクセス元からは、上記VPCエンドポイントのURLを指定してアクセスすればOKです。
課題
2026年2月13日現在、設定を削除しようとしても、ResourceConfigurationやResourceGatewayからカジュアルに削除することができません。
既存のResourceConfigrationから関連しているResourceGatewayを削除しようとしてもコンソールでは行えません。

また、ResourceGatewayからもResourceConfigurationを削除できません。

また、VPCエンドポイントと紐ついていると削除ができません。
aws vpc-lattice delete-resource-configuration --resource-configuration-identifier "arn:aws:vpc-lattice:ap-northeast-1:xxxxxx:resourceconfiguration/rcfg-xxxxx" --region ap-northeast-1
An error occurred (ValidationException) when calling the DeleteResourceConfiguration operation: rcfg-xxxx is associated with one or more Endpoint(s)
一度作ったResourceConfigrationかとResourceGatewayの連携を削除するにはCLIで実行する必要があります。
$ aws vpc-lattice list-resource-endpoint-associations --resource-configuration-identifier arn:aws:vpc-lattice:ap-northeast-xxxxx:xxxxx:resourceconfiguration/rcfg-xxxxx --no-cli-pager
{
"items": [
{
"id": "rea-xxxxx",
"arn": "arn:aws:vpc-lattice:ap-northeast-xxxxx:xxxxx:resourceendpointassociation/rea-xxxxx",
"resourceConfigurationId": "rcfg-xxxxx",
"resourceConfigurationArn": "arn:aws:vpc-lattice:ap-northeast-xxxxx:xxxxx:resourceconfiguration/rcfg-xxxxx",
"vpcEndpointId": "vpce-xxxxx",
"vpcEndpointOwner": "xxxxx",
"createdAt": "xxxxx-xxxxx-xxxxxTxxxxx:xxxxx:xxxxx.xxxxx+xxxxx:xxxxx"
}
]
}
aws vpc-lattice delete-resource-endpoint-association --resource-endpoint-association-identifier arn:aws:vpc-lattice:ap-northeast-xxxxx:xxxxx:resourceendpointassociation/rea-xxxxx
{
"id": "rea-xxxxx",
"arn": "arn:aws:vpc-lattice:ap-northeast-xxxxx:xxxxx:resourceendpointassociation/rea-xxxxx",
"resourceConfigurationId": "rcfg-xxxxx",
"resourceConfigurationArn": "arn:aws:vpc-lattice:ap-northeast-xxxxx:xxxxx:resourceconfiguration/rcfg-xxxxx",
"vpcEndpointId": "vpce-xxxxx"
}
グループ管理
ResourceConfigurationにはグループの概念があり、同一のResourceGatewayを使用して、複数のResourceConfigrationで設定したリソースへアクセスが可能です。
ResourceGatewayの作成はすでに済んでいるとします。
ResourceConfigurationで「リソースグループ」を設定します。
ここでは、紐つけるResourceGatewayのみを設定し、対象リソースは設置絵しません。

リソースグループを作成したのち、リソースタイプを「子」に設定して先ほど作成したグループを指定します。

ResourceGatewayを確認すると、グループの他にグループに紐つくResourceConfigurationが「子」として表示されています。
アクセス元のVPCエンドポイントには同一のResourceConfiguration(グループ)で、2つのエンドポイントが生えています。これらのエンドポイントを指定することでアクセスができるようになります。

未検証ではありますが、カスタムドメインを使用してアクセスすることも可能なようです。
色々調べていて知らなかった設定などもあり、これを知っていればあの時のあれは解決できたかもなぁと思ったりも
します。
他にもクロスアカウントで使える技術はありますが、この辺りを知っておくと一時的にクロスアカウントでのやりとりに使用できそうです。









