TerraformでAWSアカウント作成すると苦しい
概要
AWSのベスプラ記事に倣って
マルチアカウントベースの最小構成Starting FrameworkをTerraformで作成してみることにした
(VPC単位ではなくAWSアカウントベースで環境構築することでスケーラブルなシステムが出来上がるらしい
...が、初っ端のOU(Organization Unit)、AWSアカウント作成あたりでだいぶ躓いたのでメモを書いておく
Terraformで作ったもの
事前準備
terraform操作する用のIAMメンバー作成
RootのAWSアカウントにAdministratorAccess
ポリシー付与したグループ作成
そのグループにIAMメンバーを作成する
IAMメンバーに用いるメールアドレスはgmailのエイリアスを使ってxxx+admin@gmail.com
とか適当な名前使う
IAMメンバーのアクセスキーの取得
コンソールから作成したIAMメンバーのアクセスキーを取得
※怖いのでMFA(多要素認証)は有効にしましょう
AWS CLIの設定
AWSのコマンドラインインストールしてアクセスキーを設定
profileにroot-admin
と適当な名前つけてます
$ brew install awscli
$ aws configure --profile root-admin
AWS Access Key ID [None]:
tfstate保管用のS3用意
tfstateを保管するS3をrootアカウントに用意しておく
ディレクトリ構成はこんな感じ
.
└── organization
├── .terraform-version
├── main.tf
├── provider.tf
└── versions.tf
それぞれファイルの中身はこんな感じ
tfenv用に使用するterraformのバージョンを教えてあげる
0.14.9
terraformとawsのバージョン指定
terraform {
required_version = "0.14.9"
required_providers {
aws = "3.35.0"
}
}
awsのprofileやregion指定
provider "aws" {
region = "ap-northeast-1"
profile = "root-admin"
}
S3を指定
# s3 bucket for tfstate
resource "aws_s3_bucket" "terraform_state" {
bucket = "test-root-admin-tfstate"
versioning {
enabled = true
}
}
organizationディレクトリで以下実行してS3作成
terraform init
terraform plan
terraform apply
OU作成
さっき作成したS3をbackendで指定して
OUとAWSアカウントを作成する
.
└── organization
├── .terraform-version
├── backend.tf
├── main.tf
├── provider.tf
└── versions.tf
tfstate管理のbackendはこんな感じで指定
terraform {
backend "s3" {
bucket = "test-root-admin-tfstate"
key = "organization.tfstate"
region = "ap-northeast-1"
profile = "root-admin"
}
}
OUとAWSアカウントを指定
まずは基盤→インフラ→production OUを作って、AWSアカウントを所属させてみる
# s3 bucket for tfstate
resource "aws_s3_bucket" "terraform_state" {
bucket = "test-root-admin-tfstate"
versioning {
enabled = true
}
}
# set default organization id
data "aws_organizations_organization" "root" {}
locals {
root_id = data.aws_organizations_organization.root.roots[0].id
}
/*
core organization unit
*/
resource aws_organizations_organizational_unit core-ou {
name = "core organization unit"
parent_id = local.root_id
}
# infra
resource aws_organizations_organizational_unit infra_organization_unit {
name = "infra"
parent_id = aws_organizations_organizational_unit.core-ou.id
}
# infra production
resource aws_organizations_organizational_unit infra_production_organization_unit {
name = "infra production"
parent_id = aws_organizations_organizational_unit.infra_organization_unit.id
}
resource aws_organizations_account infra_production_account {
name = "test+infra-production@gmail.com"
email = "test+infra-production@gmail.com"
parent_id = aws_organizations_organizational_unit.infra_production_organization_unit.id
}
organizationディレクトリで以下実行してOUとAWSアカウント作成
※うまく実行されない時はrm -rf .terraform
しちゃってもいいかも
terraform init
terraform plan
terraform apply
コンソール確認するとOUとAWSアカウント作成されてそう!!
だが、こんなエラーメッセージがターミナルに表示される・・・
Error: ConstraintViolationException: The member account must be configured with a valid payment method, such as a credit card.
色々躓いたところ
AWSアカウントの支払い方法がセットされてないと怒られてるし
「とりあえず作成したアカウント削除しとこうかな。。。」
と思いtfファイルからアカウントに関する記述を削除して再度terraform apply
するも
同じようなエラーが出て、消すことができない・・・・・行き止まりにぶつかった😫
ログインできない
ということで、まずコンソールから支払い方法登録してみようと思ったが...
パスワードとか何にも設定してないので、
登録したメールアドレス使ってパスワード再発行からのログイン
支払い方法の設定
支払い方法は右上のマイアカウント->お支払い方法からすぐに設定できた。
とりあえずクレジットカードを登録する
※クレジット登録したら一気にリスク増すのでMFA必須
電話番号の認証
ここがものすごい詰まった。。。。
クレジット登録したものの次は電話でのピンコード認証がされてないと怒られる・・・
Error: ConstraintViolationException: You cannot remove an account from the organization if the account owner has not completed phone pin verification.
色々ググったけどこの電話番号での認証URLがわからんかった・・・
が!古いコンソール画面でOUから除外しようとすると素敵なリンクがあった🤩
これが登録ステップのURL
クリックすると登録画面が出た!!!!
しばらくは削除できない
ついにOUから作ったAWSアカウントを外せる時が・・・
と思ったが・・・しばらく期間をおかないと外せないみたい・・・
まぁここまで来たらあとは時が解決してくれる(はず)
まとめ
AWS Control Towerが東京リージョンに来たら
クリック一発でLanding Zoneの環境できるみたいですが
自分で1から理解して進めたいので、愚直にやってみたら
出だしから恐ろしく躓いたのでメモを残しておいた
やっとOUとAWSアカウントの制御がterraformからできるようになったので
それぞれOU毎に必要なリソース作っていこうと思う🏄♂️
ひとつ分かったことは「Terraformで気軽にAWSアカウント作ると、消すのに苦労するので気をつけよう」ということでした🤮
Discussion