AWSでクロスアカウントアクセスと相性のよいサービス
最近AWSでクロスアカウントアクセスを前提とした場合、どのような連携方法がうまくフィットするのかを調べていました。
ある程度知見が溜まって体系化できてきたので、まとめておくことにしました。
最初にまとめ
クロスアカウントアクセスの際は、リージョンサービスがインタフェースとなるように設計することが大事。
リージョンサービスを活用することで、コストを抑制しつつ、クレデンシャルレスなアクセス制御が実現できる。
リソースベースのポリシーをサポートしているサービスであれば、ポリシー定義の変更だけで実現できる。
AZサービスを利用するとネットワークの関心事が入ってきて、セキュリティグループやIPアドレスを意識する必要が出てくる。
特にRDS系はAZサービスであるため、クロスアカウントではRDBを直接インタフェースとせずに連携することが重要となる。
参考:グローバルサービス、リージョンサービス、AZサービス
クロスアカウントアクセスと相性のよいサービス
S3
S3は以下のようなケースでフィットする。
- ファイルデータをクロスアカウントで連携したい場合
- 連携するデータを永続化したい場合1
- オプション:ファイル配置など、S3のオブジェクトのイベントをトリガーとして何かしらの処理を行いたい場合
他のアカウントからアクセスを許可するためには、バケットポリシーで他のAWSアカウントのIAMロールを指定すればよい。2
例えばBUCKET-NAME
のバケットに対して以下のバケットポリシーを指定すれば、異なるAWSアカウントACCOUNT-ID
にあるIAMロールから、GetやListの操作が可能となる。
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "CrossAccountAccess",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::ACCOUNT-ID:role/xxxxxxxxxxxx"
},
"Action": [
"s3:Get*",
"s3:List*"
],
"Resource": [
"arn:aws:s3:::BUCKET-NAME/*",
"arn:aws:s3:::BUCKET-NAME"
]
}
]
}
クレデンシャル(パスワード・トークン・シークレットキーなど)を使用しないため、クロスアカウント連携に必要な情報はパブリックチャンネルで堂々と受け渡しができるし、定期的なローテーションも必要ないので運用しやすい。
同一リージョンであればデータ転送コストもかからない3ので、GET/PUTなどのAPIリクエストやストレージの料金のみで運用することができる。
SQS/SNS
SQSやSNSがフィットするのは、以下のようなケース。
- 小さなメッセージデータ(256KiB以内)をクロスアカウントで連携したい場合
- 永続化が不要なデータを受け渡す場合
- 連携後に何かしらの処理をトリガーしたい場合
SQSの例:キューに以下のようなキューポリシーを設定すると、ACCOUNT-B-ID
にあるIAMロールからACCOUNT-A-ID
のキューへメッセージの送信を許可することができる。(参考:Amazon SQSポリシーの基本例 - Amazon Simple Queue Service)
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowCrossAccountSendMessage",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::ACCOUNT-B-ID:role/ROLE-NAME"
},
"Action": "sqs:SendMessage",
"Resource": "arn:aws:sqs:REGION:ACCOUNT-A-ID:QUEUE-NAME"
}
]
}
SNSの例:トピックに以下のようなアクセスポリシーを設定すると、ACCOUNT-B-ID
にあるIAMロールからACCOUNT-A-ID
のトピックへメッセージのPublishを許可することができる。(参考:ステップ 5: オプション - Amazon SNSトピックに発行するアクセス許可をユーザーに付与する - Amazon Simple Notification Service)
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowCrossAccountPublish",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::ACCOUNT-B-ID:role/ROLE-NAME"
},
"Action": "sns:Publish",
"Resource": "arn:aws:sns:REGION:ACCOUNT-A-ID:TOPIC-NAME"
}
]
}
S3と同様、クレデンシャルを使用しないため扱いやすい。
DynamoDB
DynamoDBがフィットするのは、以下のようなケース。
- ファイルでないデータをクロスアカウントで連携したい場合
- データを永続化したい場合1
- オプション:配置後に何かしらの処理をトリガーしたい場合
こちらは2024年3月にできるようになったばかりのようで、以下の記事が参考になる。
これもS3などと同様、テーブル・インデックス・ストリームに対してポリシーを記述することでアクセス許可できると捉えればよいだろう。
Parameter Store
Parameter Storeは以下のようなケースで有用だろう。
- 組織・チーム・システムを跨いでクレデンシャルを受け渡す場合
- クレデンシャルの自動ローテーション
こちらは2024年2月にできるようになったばかりのようで、以下が参考になる。
- Parameter Store での共有パラメータの使用 - AWS Systems Manager
- [アップデート] SSMパラメータストアがRAMを使用してクロスアカウントで共有できるようになっていたので試してみる | DevelopersIO
Parameter Storeの中でもアドバンストパラメータを使用する他、KMSも使用するため、これらの料金が発生する。
ローテーションを想定する場合は、更新時のフローを考えておくことが重要だろう。
サービスによっては即時切り替えることで問題が出たり、移行期間を用意する必要がある。
Gitやコンテナと同様にlatest
やv1
のような名称で参照できるようにすると、切り替え時の運用を軽減できそうだ。
クロスアカウントアクセスに不向きなサービス
RDS(on Private Subnet)
RDBをPrivate Subnetに配置した上でクロスアカウントを実現するのは、困難だということがわかった。
まずネットワークを共有する方法として、以下のような方法がある。
- VPC Peering
- Transit Gateway
- VPCサブネット共有4
しかしこれらは連携するアカウント間でIPアドレス空間が重複しないように設計する必要があるし、データ転送料も発生する。
また以下のような方法も存在するが、それなりに付随的なリソースおよびコストが発生する。
- RDS Proxyを使ったRDSのクロスアカウントアクセスを試してみる | DevelopersIO
- PrivateLinkとNLBを使ったRDSクロスアカウントアクセスを試してみる | DevelopersIO
これらを見て感じるのはAZサービス(VPC)を扱う限り付随的なリソース・コストの発生は避けられないということだ。それはVPCエンドポイントだったり、NLBだったりするが、VPCを超えるにはそれだけの通行料がかかるということだろう。
クロスアカウントアクセスにフィットするのがリージョンサービスであると捉えると、RDS Proxyを用いるのが最もスマートな構成に感じられるが、それなりの付随的なコストの発生は覚悟する必要がある。
-
ライフサイクルポリシー(S3)やTTL(DynamoDB)を使えば、自動的な削除も可能 ↩︎
-
IAMユーザでも可能だが、システム間連携であればIAMロールのほうが適切なケースが多いだろう ↩︎
-
[アップデート]VPCサブネットを複数のAWSアカウントで共有できるようになりました!! #reinvent | DevelopersIO ↩︎