zoo200's MemoMemo
ホーム
AWS
アカウント周り
アカウント周り
MFAセキュリティ

AWSマルチアカウント 2段階認証(MFA)制限のスイッチロールで環境切替え

2022.03.17

こちらで提唱されているようにAWSは用途毎にアカウント自体を分けたほうがセキュリティ向上、作業ミスのリスク低減、コスト把握など様々な点でメリットがあります。

個人的には、開発環境用AWSアカウント、本番環境用AWSアカウントのようにわけることで、Terraformを実行するときに、そのありがたみを感じました。

気軽に destroy をできるので、試行錯誤しやすく(環境を作り直しやすい)、ソースコードがバグってて同じアカウント内の本番リソースを誤って変更してしまったらどうしよう。。。などの不安から解放されます。


ただ分割の弊害として、(何も考えずにやると)それぞれの環境ごとにIAMユーザーを用意し、環境ごとにサインイン、サインアウトを繰り返すハメになります。

特にQRコードのMFAを設定している場合、これらがかなりの手間となります。
スマホのロック解除してアプリ立ち上げて、コード確認して、、、手間すぎて運用できないと思います。(実際にすぐ心折れました)


で、その回避策として、ロールの切り替え(SwitchRole)という便利な機能があるのでそれを設定してみます。

これをすることにより一度サインインすれば、あとはクリックするだけで環境を切り替えられるようになります。

目次
  1. 前提
    1. CloudFormationを使用
    2. 環境
    3. 完成イメージ
      1. 踏み台環境(JUMP)のIAMユーザー
      2. 踏み台環境(JUMP)のIAMユーザーグループ
      3. 開発環境(DEV)、本番環境(PROD)のIAMロール
  2. マルチアカウント環境の構築手順
    1. CloudFormation YAMLファイル作成
      1. 踏み台環境(JUMP)用のYAMLファイル作成
      2. 開発環境(DEV)、本番環境(PROD)用のYAMLファイル作成
    2. CloudFormation 実行
      1. 踏み台環境(JUMP) でCloudFormation実行
      2. 開発環境(DEV)・本番環境(PROD) でCloudFormation実行
    3. スイッチロール確認
      1. うまく行かない場合
  3. Tips
    1. IAMユーザー情報の更新、追加、削除
    2. 便利ツール AWS Extend Switch Roles
  4. 参考
スポンサーリンク

前提

CloudFormationを使用

今回はCloudFormation(CFn)を使用します。

僕は通常、Terraformを使用しているのですが、以下の考えからチームメンバーが使うIAMユーザー、ロールに関してはCloudFormationで操作しています。

  • そもそも最初のTerraformを実行するユーザー作成自体は、コンソールから作成する必要がある。
    ユーザー作成のコードはTerraforomとCFnを分けずに、CFnにまとめたほうが混乱しなそう。
     
  • メンバー管理は、ディレクターを含むインフラエンジニア以外の人も、なるべくできるようにしたい。
    黒い画面でコマンドを叩く Terraform は拒絶反応おこされそう。
     

環境

AWS環境(アカウント)を3つ使用します。

環境AWSアカウントID
踏み台(JUMP)111111111111
開発(DEV)222222222222
本番(PROD)333333333333

完成イメージ

CFnを使用して最終的にできるイメージは以下となります。

踏み台環境(JUMP)のIAMユーザー

メールアドレスでログインするルートユーザーではロールを切り替えることはできません。

スイッチ元アカウントでIAMユーザーを使用します。そもそもルートユーザーを常時使用することは非推奨です。
(ベストプラクティス 個々の IAM ユーザーを作成する)

今回は管理者用ユーザー、開発者用ユーザーの2人を作成します。

踏み台環境(JUMP)のIAMユーザーグループ

アクセス許可はIAMユーザーには直接設定しません。

IAMユーザーグループに割り当て、ユーザーはそのグループに所属させます。
(ベストプラクティス IAM ユーザーにアクセス許可を割り当てるためには、ユーザーグループを使用する)

開発環境(DEV)、本番環境(PROD)のIAMロール

スイッチ先アカウントでIAMロールを作成します。IAMユーザーではないです。

今回はあらかじめAWSで用意されている、「管理者用ポリシーAdministratorAccess」 と 「開発者用ポリシーPowerUserAccess」 をそれぞれ管理者用ロール、開発者用ロールに割り当てます。

マルチアカウント環境の構築手順

それでは設定していきます。

CloudFormation YAMLファイル作成

踏み台環境(JUMP)用のYAMLファイル作成

まずスイッチ元(IAMユーザーにサインインする環境)で適用するYAMLファイルを作成します。ファイル名は任意で大丈夫です。

# 踏み台アカウントでユーザーを作成する
AWSTemplateFormatVersion: '2010-09-09'
Description: IAM User|Group of Jump Account
Mappings: 
  TagsMap:
    CreatedBy:
      Value: "CloudFormation"

# 認証情報管理ポリシー
Resources:
  ManageOwnAuthPolicy:
    Type: 'AWS::IAM::ManagedPolicy'
    Properties:
      ManagedPolicyName: ManageOwnAuthPolicy
      PolicyDocument:
          Version: 2012-10-17
          Statement:
            - Sid: AllowViewAccountInfo
              Effect: Allow
              Action:
                - iam:GetAccountPasswordPolicy
                - iam:ListVirtualMFADevices
              Resource: "*"
            - Sid: AllowManageOwnPasswords
              Effect: Allow
              Action:
                - iam:ChangePassword
                - iam:GetUser
              Resource: arn:aws:iam::*:user/${aws:username}
            - Sid: AllowManageOwnAccessKeys
              Effect: Allow
              Action:
                - iam:CreateAccessKey
                - iam:DeleteAccessKey
                - iam:ListAccessKeys
                - iam:UpdateAccessKey
                - iam:GetAccessKeyLastUsed
              Resource: arn:aws:iam::*:user/${aws:username}
            - Sid: AllowManageOwnVirtualMFADevice
              Effect: Allow
              Action:
                - iam:CreateVirtualMFADevice
                - iam:DeleteVirtualMFADevice
              Resource: arn:aws:iam::*:mfa/${aws:username}
            - Sid: AllowManageOwnUserMFA
              Effect: Allow
              Action:
                - iam:DeactivateMFADevice
                - iam:EnableMFADevice
                - iam:ListMFADevices
                - iam:ResyncMFADevice
              Resource: arn:aws:iam::*:user/${aws:username}
            - Sid: DenyAllExceptListedIfNoMFA
              Effect: Deny
              NotAction:
                - iam:CreateVirtualMFADevice
                - iam:EnableMFADevice
                - iam:GetUser
                - iam:ListMFADevices
                - iam:ListVirtualMFADevices
                - iam:ResyncMFADevice
                - sts:GetSessionToken
              Resource: "*"
              Condition:
                BoolIfExists:
                  aws:MultiFactorAuthPresent: 'false'

# 管理者グループ
  AdminJumpPolicy:
    Type: 'AWS::IAM::ManagedPolicy'
    Properties:
      ManagedPolicyName: AdminJumpPolicy
      PolicyDocument:
          Version: 2012-10-17
          Statement:
            - Sid: AdminAssumeRole
              Effect: Allow
              Action: 'sts:AssumeRole'
              Resource:
                - "arn:aws:iam::222222222222:role/AdminRoleFromJump"
                - "arn:aws:iam::333333333333:role/AdminRoleFromJump"
  AdminJumpGroup:
    Type: AWS::IAM::Group
    Properties: 
      GroupName: AdminJumpGroup
      ManagedPolicyArns: 
        - !Ref ManageOwnAuthPolicy
        - !Ref AdminJumpPolicy

# 開発者グループ
  DevJumpPolicy:
    Type: 'AWS::IAM::ManagedPolicy'
    Properties:
      ManagedPolicyName: DevJumpPolicy
      PolicyDocument:
          Version: 2012-10-17
          Statement:
            - Sid: DevAssumeRole
              Effect: Allow
              Action: 'sts:AssumeRole'
              Resource:
                - "arn:aws:iam::222222222222:role/DevRoleFromJump"
                - "arn:aws:iam::333333333333:role/DevRoleFromJump"
  DevJumpGroup:
    Type: AWS::IAM::Group
    Properties: 
      GroupName: DevJumpGroup
      ManagedPolicyArns: 
        - !Ref ManageOwnAuthPolicy
        - !Ref DevJumpPolicy

# ユーザー定義
  User01:
    Type: 'AWS::IAM::User'
    Properties:
      UserName: tester-01
      Groups:
        - !Ref AdminJumpGroup
      Tags:
        - Key: "my:createdBy"
          Value: !FindInMap [TagsMap,CreatedBy,Value]
  User02:
    Type: 'AWS::IAM::User'
    Properties: 
      UserName: tester-02
      Groups:
        - !Ref DevJumpGroup
      Tags:
        - Key: "my:createdBy"
          Value: !FindInMap [TagsMap,CreatedBy,Value]
  User03:
    Type: 'AWS::IAM::User'
    Properties: 
      UserName: tester-03
      Groups:
        - !Ref DevJumpGroup
      Tags:
        - Key: "my:createdBy"
          Value: !FindInMap [TagsMap,CreatedBy,Value]


このYAMLファイルのポイントは以下のとおりになります。

認証情報管理ポリシー ManageOwnAuthPolicy

公式サンプル MFA で認証された IAM ユーザーが My Security Credentials ページで自分の認証情報を管理できるようにする を利用しました。

DenyAllExceptListedIfNoMFA の設定により2段階認証されていないと NotAction 以外の操作はできないようになっています。このサンプルでは、実質MFA作成以外の操作はできません。

また今回は、以下4点の修正を行いました。

  • AllowManageOwnSigningCertificates デジタル署名用証明書の操作を削除。
    利用しない。
  • AllowManageOwnSSHPublicKeys CodeCommit の SSH パブリックキーの操作を削除。
    利用しない。
  • AllowManageOwnGitCredentials CodeCommit の Git 認証情報の操作を削除。
    利用しない。
  • AllowManageOwnAccessKeys の iam:GetAccessKeyLastUsed を追加。
    アクセスキーの最終使用日時は確認できるようにしておきたい。
管理者、開発者各グループ設定 [Admin|Dev]JumpGroup

スイッチ先アカウントで作成するIAMロール名を Resource に定義して、各環境の各ロールにスイッチできるようにします。

ユーザー定義 User

各ユーザーを作成します。Groups にてどのグループに所属させるか設定します。

なお僕の運用している環境は10人前後のメンバー管理なので、この記載方法でなんとかなっています。より大規模な環境ならばループ処理するとかいろいろ考えなければいけないかもです。

開発環境(DEV)、本番環境(PROD)用のYAMLファイル作成

次にスイッチ先(IAMロールにスイッチする環境)で適用するYAMLファイルを作成します。ファイル名は任意で大丈夫です。

# 各AWSアカウント環境でロールを作成する
AWSTemplateFormatVersion: 2010-09-09
Description: IAM Role of Service Account
# 踏み台AWSアカウントIDを引数として入力させる
Parameters:
  JumpAccountID:
    ConstraintDescription: AWS ID is Only Number with 12digit
    MinLength: 12
    MaxLength: 12
    AllowedPattern: "[0-9]*"
    Description: Please Enter Jump AWS Account ID!
    Type: String
Mappings: 
  TagsMap:
    CreatedBy:
      Value: "CloudFormation"

# 管理者ロール
Resources: 
  AdminRoleFromJump:
    Type: AWS::IAM::Role
    Properties:
      RoleName: AdminRoleFromJump
      AssumeRolePolicyDocument:
        Version: 2012-10-17
        Statement:
          - Effect: Allow
            Principal:
              AWS:
                - !Sub "arn:aws:iam::${JumpAccountID}:user/tester-01"
            Action:
              - 'sts:AssumeRole'
            Condition:
              Bool:
                aws:MultiFactorAuthPresent: true
      ManagedPolicyArns:
        - "arn:aws:iam::aws:policy/AdministratorAccess"
      Tags:
        - Key: "my:createdBy"
          Value: !FindInMap [TagsMap,CreatedBy,Value]

# 開発者ロール
  DevRoleFromJump:
    Type: AWS::IAM::Role
    Properties:
      RoleName: DevRoleFromJump
      AssumeRolePolicyDocument:
        Version: 2012-10-17
        Statement:
          - Effect: Allow
            Principal:
              AWS:
                - !Sub "arn:aws:iam::${JumpAccountID}:user/tester-02"
                - !Sub "arn:aws:iam::${JumpAccountID}:user/tester-03"
            Action:
              - 'sts:AssumeRole'
            Condition:
              Bool:
                aws:MultiFactorAuthPresent: true
      ManagedPolicyArns:
        - "arn:aws:iam::aws:policy/PowerUserAccess"
      Tags:
        - Key: "my:createdBy"
          Value: !FindInMap [TagsMap,CreatedBy,Value]

以下がポイントになります。

踏み台AWSアカウントID引数 JumpAccountID

こちらの記事を参考にさせていただきましたmm
CFnでの作成時に踏み台のAWSアカウントID(111111111111) を入力します。他のプロジェクトでもこのYAMLファイルをそのまま利用できたほうが便利かな、と考え引数にしてます。

管理者・開発者各ロール設定 [Admin|Dev]RoleFromJump

Principal で踏み台アカウントのどのユーザーが当該ロールにスイッチできるかを設定します。JumpAccountID には、前述の引数で入力した値が入ります。

ちなみにこの Principal 設定ですが前述のユーザー定義同様、僕は10人前後の管理かつ、環境が開発、ステージング、本番と3つ程度なので、この記載方法でなんとかなっています。

より大規模で便利な仕組みを構築できていない状態であれば、例えば user/hoge-*にするなど許可範囲を広げてユーザー更新作業の運用コストを減らすなど、いろいろ考えなければいけないかもです。
JSON ポリシーの要素: Principal が参考になると思います。

またCondition でMultiFactorAuthPresent: true を指定することにより2段階認証されていないとスイッチできないようにしています。

スポンサーリンク

CloudFormation 実行

設定ファイルを適用します。

踏み台環境(JUMP) でCloudFormation実行

踏み台環境(JUMP) 用のAWSコンソールにログインします。

ほんとに一発目であればIAMユーザーが存在しないのでルートユーザー(メールアドレスでサインインするアカウント)でやります。

既にIAMユーザーがいる場合、そちらで実施しましょう。CloudFormationでIAMの設定変更をするので、AdministratorAccess権限だとハマらずに楽です。

AWSコンソールにログイン後、 画面上部検索窓 [ CloudFormation ] で検索 → 当該サービスをクリック → 画面右上の [ スタックの作成 ] → [ 新しいリソースを使用(標準) ] で以下の通り選択し、 [ ファイルの選択 ] から作成した、踏み台環境(JUMP) 用 YAMLファイルをアップロードし、次へ 。



スタックの名前は、任意のわかりやすい名前をつけて [ 次へ ]、スタックオプションの設定 画面は全部デフォルトで大丈夫です。

レビュー画面の一番下の [ AWS CloudFormation によって IAM リソースがカスタム名で作成される場合があることを承認します。] にチェックを入れ、 [ スタックの作成 ] クリックします。

上記のチェックを入れないと「Requires capabilities : [CAPABILITY_NAMED_IAM]」のエラーが出ます。


作成が完了すると CREATE_COMPLETE となります。

[ リソース ] タブで作成されたリソースを確認でき、名前をクリックするとそれぞれのリソース画面に遷移できます。


ここから各IAMユーザーの機密情報を設定してメンバーに渡していきます。ここらへんの塩梅は、それぞれの運用方針次第かと思います。

僕は作成されたユーザー画面へ遷移して、パスワード、QRコードを設定して、各メンバーへ渡しています。
(公式的にはIAM ユーザーを安全に作成するにはどうすればよいですか? で方針が示されています)


QRコードの設定は、以前書いたこちらの記事を参照ください。

開発環境(DEV)・本番環境(PROD) でCloudFormation実行

スイッチ元の設定が完了したので、次にスイッチ先の設定を行います。

開発環境(DEV)・本番環境(PROD)のAWSコンソールにログインし、踏み台環境(JUMP)と同様の手順で、CloudFormationを実行します。

唯一の違いは、[ スタックの詳細を指定 ] 画面で踏み台AWSアカウントIDをパラメータとして入力する必要があることです。



スイッチロール確認

設定が完了したので、実際にスイッチロールの確認をしてみます。

踏み台環境(JUMP)環境のAWSコンソールにログインし、画面上部の自分のAWSアカウント名をクリックして [ ロールの切り替え ] を選択します。



次の画面で適切に情報を入力し、[ ロールの切り替え ]をクリックすると各環境へスイッチできます。

うまく行かない場合

スイッチの際、「1 つ以上のフィールドに無効な情報があります。情報を確認するか、管理者に連絡してください。」 とエラーになる場合があります。

設定ミス、入力ミス

YAMLで定義した許可設定がスイッチ元、先でそれぞれ合致しているか確認してください。また間違いなく入力できているかも確認してみてください。

2段階認証でログインしてない

踏み台のIAMユーザーで2段階認証を設定する前に、パスワードのみでログインし、MFAを設定、サインアウトせずにそのままスイッチロールをしようとするとエラーとなります。

一度サインアウトしてから再度サインイン、スイッチロールをしてみてください。

Tips

IAMユーザー情報の更新、追加、削除

IAMユーザーの更新、追加、削除などの操作は、CloudFormation の画面右側にあるタブの [ 変更セット ] から変更しましょう。

やり方は、前述の CloudFormation実行 と全く一緒です。

途中で変更セットの確認ができるので誤った変更をしてないか適用前に確認してください。

便利ツール AWS Extend Switch Roles

こちらの記事で紹介されていた、AWS Extend Switch Roles がとても便利です。

  • Chrome ウェブストア – 拡張機能 AWS Extend Switch Roles
  • Firefox (ja) 向け拡張機能を入手 AWS Extend Switch Roles


今回の例だと以下のような設定をすることで、いつでもすぐに切り替えられます。

[Dev]
role_arn = arn:aws:iam::222222222222:role/AdminRoleFromJump
color = 87ceeb
[Prod]
role_arn = arn:aws:iam::333333333333:role/AdminRoleFromJump
color = ff2600

またスイッチロールの履歴(画面上部の自分のAWSアカウント名をクリックして表示される)は直近の5個しか保存されない点からも、上記の静的設定をしておいたほうが良いと思います。



今回は以上です〜ノシ

参考

アリガト━━━ヾ(´∀`)ノ━━━━♪

公式ドキュメント ロールへの切り替え (コンソール)
Swith Roleで複数のAWSアカウント間を切替える
AWSにおけるマルチアカウント管理の手法とベストプラクティス

リンク

リンク

zoo200's MemoMemo
zoo200's MemoMemo

関連記事

アカウント周り

AWSマルチアカウント 新規アカウントを追加してみる

アカウント周り

AWSアカウント 2段階認証の設定

アカウント周り

AWS 無料枠を超えそうになったらアラートメールで通知する

アカウント周り

AWSアカウント ルートユーザーでのみできること一覧

スポンサーリンク
catコマンドで改行コードやタブ,行末の制御文字を表示する(Linux/Mac)
Athenaがブラウザで操作できない、固まったときの対処
スポンサーリンク

プロフィール

zoo200
zoo200

TOKYO2020、 AWSデビューを機にインフラ・サーバ周りをいろいろメモしてきます!

zoo200をフォローする
dopdop

カテゴリー

  • AWS40
    • Athena2
    • Aurora2
    • AWS認定試験2
    • CDK2
    • CLI4
    • CloudFront2
    • CodeBuild2
    • ECS9
    • S32
    • アカウント周り6
  • Linux9
  • Terraform19
  • プログラミング6
    • Go1
    • PHP4
    • Python1
  • ミドルウェア2
    • Apache1
    • NGINX1
  • ローカルPC・開発環境周り2

タグ

トラブルシューティング17セキュリティ10コマンド9Docker6Terragrunt6Mac6初心者向け4MFA4sops3AWS Vault3Terraformクラウド3tgenv2無料枠2tfenv2Pdsh1pyenv1
スポンサーリンク
スポンサーリンク
Terraform 特定moduleのみを指定して実行する
2020.12.312023.01.02
ECS FargateとALBで冗長化&負荷分散された環境を構築する
2024.01.232024.01.23
AWS FargateのFireLens(FluentBit)でログをCloudWatchとS3へ出力する
2022.12.312022.12.31
Amazon AuroraのタイムゾーンをUTCからJSTへ変更する
2022.07.122023.01.10
初心者向け入門 ECS FargateでDockerを動かしてみる
2022.02.262024.01.20

最近の投稿

  • ECS FargateとALBで冗長化&負荷分散された環境を構築する
  • Mac sedコマンドの-iオプションでunterminated substitute patternのエラー
  • Amazon AuroraのスロークエリをCloudWatchへ出力する
  • Go Dockertestでコンテナが突然起動しなくなる
  • Terraform state mvコマンド,movedブロックでリファクタリング

アーカイブ

  • 2024年1月1
  • 2023年2月3
  • 2023年1月2
  • 2022年12月2
  • 2022年11月1
  • 2022年9月1
  • 2022年7月1
  • 2022年6月2
  • 2022年5月7
  • 2022年4月4
  • 2022年3月2
  • 2022年2月2
  • 2022年1月1
  • 2021年12月1
  • 2021年9月4
  • 2021年8月3
  • 2021年7月5
  • 2021年6月1
  • 2021年5月2
  • 2021年2月1
  • 2021年1月1
  • 2020年12月5
  • 2020年11月6
  • 2020年10月5
  • 2020年9月5
  • 2020年8月6
  • 2018年1月3
  • 2017年12月1
目次
  1. 前提
    1. CloudFormationを使用
    2. 環境
    3. 完成イメージ
      1. 踏み台環境(JUMP)のIAMユーザー
      2. 踏み台環境(JUMP)のIAMユーザーグループ
      3. 開発環境(DEV)、本番環境(PROD)のIAMロール
  2. マルチアカウント環境の構築手順
    1. CloudFormation YAMLファイル作成
      1. 踏み台環境(JUMP)用のYAMLファイル作成
      2. 開発環境(DEV)、本番環境(PROD)用のYAMLファイル作成
    2. CloudFormation 実行
      1. 踏み台環境(JUMP) でCloudFormation実行
      2. 開発環境(DEV)・本番環境(PROD) でCloudFormation実行
    3. スイッチロール確認
      1. うまく行かない場合
  3. Tips
    1. IAMユーザー情報の更新、追加、削除
    2. 便利ツール AWS Extend Switch Roles
  4. 参考
zoo200's MemoMemo
  • お問い合わせ
  • プライバシーポリシー
  • サイトマップ
© 2020 zoo200's MemoMemo.
  • ホーム
  • トップ