😎

AWSアカウントを開発環境ごとに分離し、同じIAMユーザーを使う方法

2021/08/23に公開

AWSアカウントを環境ごとに分離したい!!
でも、AWSアカウントごとにIAMユーザー切り替えるのがめんどくさいし、アクセスキーの管理したくないので、同じIAMユーザーで複数のAWSアカウントを管理する方法を調べたのでまとめました。

(画像のようにAWSアカウントを切り替えられるようになります)

結論

おすすめな方法は2つあります

  • AWS Organizationsの管理アカウントでAWS SSOを使って管理するパターン
    • AWS Organizationsの管理アカウントを利用できる場合はあり
    • terraformを使うときは相性悪そう
  • 分離する環境分のAWSアカウント + IAMユーザー管理用AWSアカウントを使うパターン
    • AWS Organizationsの管理アカウントを利用できない場合はこちら
    • terraformとの相性は抜群

この記事では方法②について詳しく解説します。(なぜなら僕がterraformで管理したかったからです)
他にも方法はいろいろありますが、開発環境ごとの差分をなるべく減らすことを考えた時に、上のふたつがベターだと思います。

背景

AWSとGCPのユーザーアカウント事情

僕はGCPでサービスを作ることが多いのですが、GCPのプロジェクトやユーザーアカウントの概念はこんな感じになっています。

役割 詳細
IAM User 主に人間が使うためのアカウント。Google Porject内で作るのもではなく、gmailなど普通にGoogle系のサービス使う時のユーザー。
Service Account 主にシステムが利用するためのアカウント。自分で好きにServiceAccountを作成することもできますし、GCPの各種サービスはそれぞれデフォルトのServiceAccountを持っています。
IAM Role 付与する権限を管理するもの。IAM UserやService Accountに紐づけて利用します。

GCPではGoogle Projectの外側にユーザー(IAM User)という概念が存在します。 そのおかげで、環境ごとにGoogle Projectを分離したとしても常に同じユーザーで利用できるので快適に開発できます。ブラウザでGCPコンソールを閲覧する場合も、ターミナルからCLIで操作する場合も、ローカルでterraformを実行するときも、常に同じユーザーで利用できます。

一方、AWSのアカウントやユーザーアカウントの概念はこんな感じになっています。

役割 詳細
IAM User 主に人間が使うためのアカウント。AWSアカウントごとに発行する。AWSコンソールにログインするためにはIAM Userが必須。
IAM Role 主にシステムが利用するためのアカウント。
IAM Policy 付与する権限を管理するもの。IAM UserやIAM Roleに紐づけて利用します。

AWSでは各AWSアカウントの内側にユーザーという概念が存在します。そのため、環境ごとにAWSアカウントを分離すると、環境の数分だけIAMユーザーを作成する必要があります。AWSコンソールを使う時には、prd環境からdev環境に切り替えたいときは、いちいちログアウトして別アカウントでログインし直す必要があります。

AWSで全環境で共通アカウントを使うイメージ

このようなアカウント事情があるので、AWSでもGCPのように開発するために以下のような構成をとります。

ポイントは

  • 開発環境ごとのAWSアカウントには IAM Roleしか作成しない
  • 踏み台的な役割のAWSアカウントを別に作り、そこでIAM Userを管理する
  • 踏み台的な役割のAWSアカウントから、assume roleを利用して各開発環境のIAM Roleの権限を委譲する

準備編

1.AWSアカウントを作成する

分離したい環境分のAWSアカウント + 踏み台用のAWSアカウントを作成します。AWSアカウントを作成する時にはルートユーザーとなるメールアドレスが必須となります。エイリアスを使えるメールアドレスであれば my-project+dev@example.com``my-project+prd@example.com``my-project+bastion@example.com のようにするのがおすすめです。

2.アカウントエイリアスを設定する

各AWSアカウントにログインして、https://console.aws.amazon.com/iamv2 を開き、アカウントエイリアスの「編集」ボタンからアカウントエイリアスを登録しておきましょう。my-project-dev``my-project-prd``my-project-bastionのような名前にするのがおすすめです。
また、数字12桁から成るアカウントIDも必要になるので、アカウントIDとアカウントエイリアスをメモしておきます。

3.各開発環境のAWSアカウントにロールを作成する

  1. 各開発環境のAWSアカウントにルートユーザーでログイン
  2. https://console.aws.amazon.com/iamv2/home?#/roles を開く
  3. 「ロールを作成」をクリック
  4. 「信頼されたエンティティの種類を選択」を「別のAWSアカウント」を選択し、アカウントIDに踏み台用のAWSアカウントIDを入力
  5. 作成するロールに与えるポリシーを付与します。管理者用ロールの場合はAdministratorAccessのポリシーを選択して「次のステップ:タグ」をクリック
  6. タグはいらないので「次のステップ:確認」をクリック
  7. 作成するロールの名前を入力。管理者用ロールの場合は adminがおすすめ。
  8. 1~8のステップを各開発環境のAWSアカウントで行う

4.踏み台AWSアカウントにIAMユーザーを作成する

  1. 踏み台AWSアカウントにルートユーザーでログイン
  2. https://console.aws.amazon.com/iamv2/home?#/users を開く
  3. 「ユーザーを追加」をクリック
  4. ユーザー名を入力し、「AWS マネジメントコンソールへのアクセス」にチェックをいれ「次のステップ:アクセス権限」をクリック
  5. 「ポリシーの作成」をクリック
  6. 新しいタブが開くので、「JSON」タブをクリックして、以下のようにポリシーを記述し、「次のステップ:タグ」をクリック。112233445566のところは、各開発環境のAWSアカウントIDに変更する。your_role_nameのところは各開発環境のAWSアカウントに作成したロール名に変更する。
{
    "Statement": [
        {
            "Action": [
                "sts:AssumeRole"
            ],
            "Effect": "Allow",
            "Resource": [
                "arn:aws:iam::112233445566:role/your_role_name",
                "arn:aws:iam::223344556677:role/your_role_name"
            ]
        }
    ],
    "Version": "2012-10-17"
}
  1. タグはいらないので「次のステップ:確認」をクリック
  2. 作成するポリシーの名前を入力。管理者用ポリシーの場合は adminがおすすめ。
  3. 下のタブに戻り、今作成したポリシーを選択し、「次のステップ:タグ」をクリック
  4. タグはいらないので「次のステップ:確認」をクリック
  5. 「ユーザーの作成」をクリック

使い方編

AWSコーンソールでIAM Roleを切り替える

以下の手順を踏むと、AWSコンソール上で画像のようにロールを簡単に切り替えられるようになります!

  1. 踏み台AWSアカウントにIAMユーザーでログイン
  2. 画面右上のIAM User名が表示されてる箇所をクリックし、「ロールの切り替え」をクリック
  3. 「ロールの切り替え」をクリック
  4. 「アカウント」に切り替え先のAWSアカウントID、「ロール」に切り替え先のロール名、表示名は入力してもしなくてもどちらでもよいです。
  5. 1~4のステップを各開発環境のAWSアカウント分だけ行います

ローカルでAWS CLIを使ってIAM Roleを切り替える

  1. 踏み台AWSアカウントにIAMユーザーでログイン
  2. https://console.aws.amazon.com/iamv2/home#/users を開く
  3. 対象のユーザーを選択
  4. 「認証情報」タブから「アクセスキーの作成」をクリックし「アクセスキー ID」「シークレットアクセスキー」をメモする
  5. 以下のコマンドでデフォルトのプロフィールを作成する
$ aws configure --profile default
AWS Access Key ID [None]: アクセスキーIDを入力
AWS Secret Access Key [None]: シークレットアクセスキーを入力
Default region name [None]: 
Default output format [None]: 
  1. 以下のコマンドでassumeRoleする。112233445566のところは、各開発環境のAWSアカウントIDに変更する。your_role_nameのところは各開発環境のAWSアカウントに作成したロール名に変更する。
aws sts assume-role --role-arn "arn:aws:iam::112233445566:role/your_role_name" --role-session-name AWSCLI-Session
  1. すでにロールの切り替えは完了。確認する場合は以下のコマンドを実行する。
$ aws sts get-caller-identity

terraformでIAM Roleを切り替える

個人的にはこれが一番やりたかったことです!
以下のように providerでawsを指定する時に assume_roleを選択することが可能です。

provider "aws" {
  region = "ap-northeast-1"
  assume_role {
    role_arn = "arn:aws:iam::${var.aws_account[terraform.workspace]}:role/terraform"
  }
}

variable "aws_account" {
  type = map(string)
  default = {
    "dev"     = "112233445566"
    "stg"     = "223344556677"
    "prd"     = "334455667788"
  }
}

これをやっておけば、AWS CLIのdefaultのプロフィールに踏み台サーバーのIAM Userの認証情報を登録しておけば、terraformのworkspaceの切り替えをするだけで、terraformを実行するAWSアカウントを切り替えることができるので、決して誤操作をすることがなくなります。

最後に

他にもっとよい方法があれば教えていただけると嬉しいです!また僕の認識間違っていたらすみません、ご指摘いただけると嬉しいです!

Discussion