TerraformとAWS SSOでマルチアカウント管理
概要
最近はちょくちょく時間をみつけて
Landing Zoneの最小構成Starting Frameworkを作ってみてる
前回はOrganizational unit(OU)をterraformで作ってみたので
今回はAWS SSOを使って各OU配下のアカウントへのアクセスを簡便にしてみた
基本的にはこのベスプラ記事みながらやってみる
整理した図
実際に作ってみたものを絵にするとこんな感じ(多分
やったこと
毎度お馴染みClassmethod様の素敵記事があったので、基本これに準じてる感じ
SSOのユーザー、グループ作成とかはTerraformではまだ管理できないみたいで
一部コンソールから、一部terraformからって感じ。
コンソールでSSO有効化
SSOの有効化
ユーザー、グループを作成
正直自分はプライベートの勉強で作ってるので、そんなグループ分けする必要ないですが、
まぁ権限付与したグループを作成して、そこに人をくっつけていく感じ。
今回は練習程度に以下2グループ作成
- Landing Zone Admin Group
- 全アカウントを操作できるグループ
- Application Developer Group
- アプリケーション開発のworkloadアカウントにはAdminポリシー
- ログ貯めとくLog ArchiveアカウントにはReadポリシー
terraform管理部分の記載
sso permission setの作成
有効化したSSOをdataで読み込み
AdministratorAccess
とReadOnlyAccess
というpermission setを作成
permission setにadminとreadのpolicyをセットする
# read sso instance
data "aws_ssoadmin_instances" "main" {}
# create sso permission set
locals {
administrator_access = "AdministratorAccess"
read_only_access = "ReadOnlyAccess"
}
resource "aws_ssoadmin_permission_set" "main" {
for_each = toset([
local.administrator_access,
local.read_only_access
])
name = each.value
instance_arn = tolist(data.aws_ssoadmin_instances.main.arns)[0]
}
# set policy to sso permission set
resource "aws_ssoadmin_managed_policy_attachment" "main" {
for_each = aws_ssoadmin_permission_set.main
instance_arn = tolist(data.aws_ssoadmin_instances.main.arns)[0]
managed_policy_arn = "arn:aws:iam::aws:policy/${each.key}"
permission_set_arn = each.value.arn
}
landing zone admin groupの関連ずけ
DisplayNameでFilterして作成したGroupを読み込み
後は全AWSアカウントにadminのpermissionを紐づける
これでlanding zone admin groupに属するuserは全アカウントにadminでアクセスできるはず
// landing zone admin group
# find sso landing zone admin group
data "aws_identitystore_group" "admin" {
identity_store_id = tolist(data.aws_ssoadmin_instances.main.identity_store_ids)[0]
filter {
attribute_path = "DisplayName"
attribute_value = "landing-zone-admin"
}
}
# set admin permission to admin group and link to all aws account
resource "aws_ssoadmin_account_assignment" "admin" {
for_each = toset(aws_organizations_organization.org.accounts[*].id)
instance_arn = tolist(data.aws_ssoadmin_instances.main.arns)[0]
permission_set_arn = aws_ssoadmin_permission_set.main[local.administrator_access].arn
principal_id = data.aws_identitystore_group.admin.group_id
principal_type = "GROUP"
target_id = each.value
target_type = "AWS_ACCOUNT"
}
application developer groupの関連ずけ
DisplayNameでFilterして作成したapplication developer groupを読み込み
アプリケーション開発用のworkload AWSアカウントにadminのpermissionを紐づける
ConfigLogやCloudTrailのログがたまるLog Archive AWSアカウントにはreadのpermissionを紐付ける
// application developer group
# find application developer group
data "aws_identitystore_group" "application_developer" {
identity_store_id = tolist(data.aws_ssoadmin_instances.main.identity_store_ids)[0]
filter {
attribute_path = "DisplayName"
attribute_value = "application-developer"
}
}
# set admin permission to admin group and link to all aws account
resource "aws_ssoadmin_account_assignment" "application_developer" {
for_each = { for ap in [
{
account_id = aws_organizations_account.ucwork_production_account.id,
permission_set = local.administrator_access
},
{
account_id = aws_organizations_account.log_archive_production_account.id,
permission_set = local.read_only_access
}
] : ap.account_id => ap }
instance_arn = tolist(data.aws_ssoadmin_instances.main.arns)[0]
permission_set_arn = aws_ssoadmin_permission_set.main[each.value.permission_set].arn
principal_id = data.aws_identitystore_group.application_developer.group_id
principal_type = "GROUP"
target_id = each.value.account_id
target_type = "AWS_ACCOUNT"
}
(terraform初心者すぎて、ループの書きっぷりが合ってるかわからん
後はお馴染みの
terraform plan
、terraform plan
でAWSに適用する
検証
それでは実際のログインして検証してみまっす
SSOでサインインしてみる
SSOページにログインのURLはってあるのでアクセス
SSOユーザーで登録したアカウントとパスワードでログイン
landing zone admin groupに属したユーザーは全AWSアカウントにアクセスできそう
application developer groupに属したユーザーでログインすると
workload用のucwork productionアカウントにadmin権限、ログはread権限になってました
実際にManagement Consoleからログインしてみると
なんか専用のAWSReservedSSO_xxx
っていうアカウントでサインインできた
terraformのprofileもSSOのユーザーに切り替える
ここまできたら、manegement accountのIAMユーザーcredentialで操作してた
TerraformもSSOのlanding zone admin userのcredentialで操作したい
(基本ユーザー管理はSSOのものだけでやりたい
$ # sso使ってprofileファイルの生成
$ aws configure sso
$
$ # profile指定すると対象のアカウントを操作できる
$ aws s3 ls --profile AdministratorAccess-xxx
$
$ # SSO経由でログインする
$ aws sso login --profile AdministratorAccess-xxx
$
$ # 環境変数セットしとくとこのProfile見てくれるようになる
$ echo "export AWS_PROFILE=AdministratorAccess-xxx" >> ~/.zshenv
後はterraform init
, terraform plan
, terraform apply
で使えるようになるさ
まとめ
AWSを使う側はログインさえしてしまえば
権限が付与されたアカウントの操作ができるのでとっても便利すね。アカウントの管理1箇所で済むし😎
そして、OU, AWS Accountのterraform管理は気軽にdestroyできないので
ディレクトリ単位で区切った方が良さそう・・・
とにかく長くなった。先は長い。
そろそろコード書きたいけど。インフラ強い男になりたいので頑張って続ける🤹♂️
Discussion