AWS環境を利用して開発を行う上で、複数のアカウントを跨ぎながら開発を行うことが一般的になってきました。例えば、商用環境(production)と開発環境(development)のアカウントを分離して利用したり、ステージング環境やQA環境を別途用意して検証を行うこともあるかと思います。一方、様々な組織がAWS環境を利用していて、それらの組織に対して個別にアカウントを払い出し、各アカウントがどのように利用されているか管理を行っていく場面も多々あるかと思います。
本記事では、そういった場面においてどのように複数のアカウントを管理し、AWSを開発基盤として利用していけるかについて、セキュリティを考慮した観点を交えてお伝えしていきたいと思います。
マルチアカウント構成にする理由
「一つのAWSアカウント」を複数の組織が利用したり、複数のシステムの構築運用に利用すること自体、可能です。しかし、管理において例えば以下のような悩みが発生することになります。
- 別の組織や業務委託先によるアクセスを防ぐなど、AWSリソースやデータに対して細かく権限制御を行いたい
- 組織・システムごとに費用を分けて管理したい
- 商用環境へのアクセスや操作を限定し、意図しないミスを防ぎたい
- 大規模なプロジェクトに取り組んでいて、ユーザー管理及び権限管理をしやすくしたい
- 監査対応とログ管理のコストが増大し、そのための仕組みや運用の工夫が必要になる
具体的には、複数の組織やプロジェクトから共通のAWSサービスを利用する場合、見せたくないリソースが他の組織から見えてしまったり、操作ができてしまうことが考えられます。IAM ポリシーなどで細かく制御することは十分可能ですが、変更がある度にリソースレベルで権限制御を行うことは辛い作業になることもあるかと思います。
また、シングルアカウントでは、複数のユーザーグループによるAWS サービスの利用状況・ネットワーク構成・ロギング・DB運用やデータ管理など、様々な領域において密度の高いアカウント構成となるため、監査対応やログの調査にも膨大なコストがかかることが想定されます。
これらの悩みを効果的に解決するために必要になるのがマルチアカウント戦略となります。
AWS アカウント管理を行う上で考えたいポイント
以下のような分類で、マルチアカウント構成の観点から考慮すべきポイントがあります。
認証方法
どのような方法でAWSアカウントへアクセスするかという点においては、AWS IAM アイデンティティセンター(AWS SSO)を利用して認証する場所を一つにまとめることができます。ID/PASS及びMFA認証を経て、以下のような画面からマネジメントコンソールを開くことができ、また一時的なアクセスキーを発行して利用することが可能です。
アカウントを分離する基準と構成
どのようにアカウントを分離するかについての基準と構成のアウトラインが必要です。具体的には、AWS Organizations の OU(Organization Unit)構成について考えることになりますが、「AWS Control Tower」 というマルチアカウント管理サービスの基本構成をベースラインとすることがおすすめです。
また、環境によってもアカウントを分離することが考えられます。以下のようにアカウントを分離することで、各アカウントのクオーターをフルで活用でき、システムコンポーネントやワークロードの分離、IaCによるリソース管理、ログ収集などが明確な権限の境界線を持った上で拡張・分離できるというメリットがあります。
権限設定
SSOで認証したユーザーに対して持たせる権限と、システムとしてアカウントを跨いだ構成になる場合の Assume Role 構成を検討します。ユーザー権限については、関係各者をグループングしてどのアカウントに・どこまでの権限を渡すかについても考えておく必要があります。例えば、以下のようなグループとして分離することが考えられます。
- AWS開発基盤管理者
- プロジェクト関係者、開発者
- 外部パートナーなど、業務委託先の作業者
- QA, 監視, 監査担当者
それぞれのポジションをロールとして適切な権限を適用し、メンバー入れ替え時も簡単に対応できる仕組みがAWS IAM アイデンティティセンター(AWS SSO)に備わっています。以下のように Permission Set を構成して各アカウント及びユーザーグループに指定する形で設定を行います。
費用
AWS Organizations の一括請求によって支払が統合されます。注意点として、全体及びアカウントごとの Billing Alert または AWS Budgets を設定して監視を行うことをおすすめします。設定ミスや無限ループなどによる予期せぬコスト増にも早めに気づくことができます。
マルチアカウント構成を取り入れた開発基盤の構成イメージ
例えば、複数のDevOpsチームを持ち、複数のプロダクトを構えるプラットフォーム開発基盤としての構成イメージがこちらになります。必要に応じて OU 及びそれに属する AWS アカウントを柔軟に追加することができ、アカウントレベルでも疎結合なアプローチとなります。
セキュリティにおける考慮事項
複数のアカウントを管理していくときの懸念点として、コンプライアンスやセキュリティ面におけるリスク対応のための共通設定を適用する必要があります。一方で、一部のアカウントには開発のための例外措置や、より厳しいルールを指定するといったカスタマイズが必要になるケースがあります。
マルチアカウント構成において AWS Control Tower を利用することである程度基本的なところは整いますが、各組織の特性や制約などを踏まえると、AWS Config によるルールの整備と、ルールに違反した構成が組まれた際の監視を自動化する仕組みが必要になります。そのためのアプローチとしては、以下のようは方法があります。
- AWS Security Hub / AWS Config / Amazon GuardDuty など、各種セキュリティ関連サービスの有効化と設定
- 有事の際や検証にひかかったときに通知を行う仕組み
Security Hub の設定では、標準としてAWSベストプラクティス・CIS AWS Foundations Benchmark (v1.2.0, v1,4,0)・NIST SP 800-53 などがサポートされています。
また、AWS Config を利用してカスタムルールを適用する機能も使えます。AWS Lambda と連動して、チェックする周期の指定やチェックのロジックを実行して監視することができます。
セキュリティに関するルールセットや監視については、作成するアカウント全てに適用しておくことが望ましいです。しかし、個別のアカウントごとに同じ設定をマニュアル対応することはやや現実的ではありません。よって、次項で説明するアカウント作成の自動化(Account Factory)を検討してみることをおすすめします。
アカウント作成の自動化
AWS Control Tower を利用すると、Account Factory という機能を使って新規アカウントを作成することができます。Service Catalog に新規アカウント Product が登録されており、連携してアカウント名やOUなど必要なパラメータ情報を入力すると新規アカウントが作成されます。完了後は AWS Control Tower 管理下のアカウントとして紐づく流れになります。
この一連の流れについて、公式でサポートされている「AFT(Account Factory for Terraform)」というソリューションがあります。アカウント新規作成、アカウント作成時のカスタマイズ、アカウント作成後の個別アカウントごとのカスタマイズ、アカウント作成後の全アカウント共通設定を適用するカスタマイズなど、様々な形でマルチアカウント構成を構築運用するための機能が含まれています。
しかし、公式では、利用しない間にも発生する固定費用(NAT Gateway の料金など)を含めややコストが発生したり、高機能であるが故に、カジュアルに利用するという観点ではどうかなという疑問もあるかと思います。その場合、公式のAFTの構成を参考に、以下のようにカジュアルな形でアカウント作成とカスタマイズの設定を行う構成の仕組みを構築することができます。Terraform コードでアカウント作成情報を記載し、Terraform Cloud からデプロイする構成になります。フルサーバーレスで対応できる点もメリットになります。
アカウント作成リクエストに関しては、以下のような Terraform コードを書いて IaC 化することが可能です。
enviroment/main.tf
provider "aws" {
region = "ap-northeast-1"
}
module "sandbox_account_01" {
source = "../modules/sandbox_account/"
account_name = "sandbox01"
product_id = "prod-xxxxxxxxxx"
provisioning_artifact_id = "pa-xxxxxxxxxxxx"
new_account_params = {
account_email = "sandbox01@example.com"
account_name = "sandbox01"
ou = "Sandbox (ou-xxxx)"
sso_user_email = "sandbox01@example.com"
sso_user_first_name = "Katsuo"
sso_user_last_name = "Isono"
}
}
modules/sandbox_account/main.tf
resource "aws_servicecatalog_provisioned_product" "new_controll_tower_managed_account" {
name = var.account_name
product_id = var.product_id
provisioning_artifact_id = var.provisioning_artifact_id
provisioning_parameters {
key = "AccountEmail"
value = var.new_account_params.account_email
}
provisioning_parameters {
key = "AccountName"
value = var.new_account_params.account_name
}
# ...
}
アカウント作成が完了すれば、EventBridge から以下のようなイベントを取得することが可能です。このイベントを拾って別途 Terraform Cloud 上で workspace を作成し、後続処理として AWS Config のカスタムルールの設定やアカウントごとのカスタマイズなどを適用することが可能になります。
{
"detail-type": "AWS Service Event via CloudTrail",
"source": "aws.controltower",
"detail": {
"eventSource": "controltower.amazonaws.com",
"eventName": "CreateManagedAccount",
"awsRegion": "ap-northeast-1",
"serviceEventDetails": {
"createManagedAccountStatus": {
"organizationalUnit": {
"organizationalUnitName": "Sandbox",
"organizationalUnitId": "ou-xxxx-xxxxx"
},
"account": {
"accountName": "sandbox05",
"accountId": "111122223333"
},
"state": "SUCCEEDED",
"message": "AWS Control Tower successfully created an enrolled account.",
}
}
// ...
}
}
いかがだったでしょうか。結論としては、各組織・プロジェクトの特性と制約を鑑みながら、可能な限りセキュリティと運用効率の両方を向上できる形で開発基盤を構築することを目指す形になります。AWSのベストプラクティスを積極的に理解して活用することも大事ですので、そういった情報を探していた方々の参考になると幸いです。不明点などあれば、お気軽にお問い合わせください。