kakakakakku blog

Weekly Tech Blog: Keep on Learning!

Terraform Cloud で IAM Role から一時的なアクセスキーを取得する

Terraform Cloud で AWS を操作するときにアクセスキー(AWS_ACCESS_KEY_IDAWS_SECRET_ACCESS_KEY)を使いたくなく,Terraform Cloud の「Dynamic Provider Credentials」を使って OpenID Connect (OIDC) と連携する仕組みを構築したので,ポイントをまとめておく❗️

\( 'ω')/ アクセスキー撲滅だ〜

参考になる記事

Terraform のドキュメントと AWS Partner Network (APN) Blog の記事は特に参考になった💡

developer.hashicorp.com

aws.amazon.com

Step.1 IAM ID プロバイダを構築する

まず,Terraform Cloud 用に「IAM ID プロバイダ」を構築する.コンソールだと以下のように設定する.サムプリントはコンソールから取得できる👌

  • プロバイダのタイプ: OpenID Connect
  • プロバイダの URL: https://app.terraform.io
  • 対象者: aws.workload.identity

もし AWS CloudFormation で構築する場合は以下のテンプレートを参考にしてもらえればと❗️

AWSTemplateFormatVersion: 2010-09-09

Parameters:
  Thumbprint:
    Type: String
    Default: '9e99a48a9960b14926bb7f3b02e22da2b0ab7280'

Resources:
  TerraformCloudOidcProvider:
    Type: AWS::IAM::OIDCProvider
    Properties:
      Url: https://app.terraform.io
      ClientIdList:
        - aws.workload.identity
      ThumbprintList:
        - !Ref Thumbprint

docs.aws.amazon.com

構築できた👏

Step.2 IAM Role を構築する

次に IAM ID プロバイダと連携する「IAM Role」を構築する.ポリシーは Terraform Cloud に必要な権限に抑えつつ,信頼関係は以下の値を埋めつつ設定する.

  • <AccountId>: AWS アカウント ID
  • <Organization>: Terraform Cloud の Organization 名
  • <Project>: Terraform Cloud の Project 名
  • <Workspace>: Terraform Cloud の Workspace 名
  • <RunPhase>: plan もしくは apply(基本的には * で良いと思う)

特に app.terraform.io:sub に設定する ID に関しては範囲を狭めるために * を避けて <Organization><Project><Workspace> を設定する.<RunPhase>planapply の権限を分割して管理する場合を除いて,基本的には * で良いと思う.きめ細かく ID を指定できるのは助かる💡

{
    "Version": "2008-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "Federated": "arn:aws:iam::<AccountId>:oidc-provider/app.terraform.io"
            },
            "Action": "sts:AssumeRoleWithWebIdentity",
            "Condition": {
                "StringEquals": {
                    "app.terraform.io:aud": "aws.workload.identity"
                },
                "StringLike": {
                    "app.terraform.io:sub": "organization:<Organization>:project:<Project>:workspace:<Workspace>:run_phase:<RunPhase>"
                }
            }
        }
    ]
}

もし AWS CloudFormation で構築する場合は以下のテンプレートを参考にしてもらえればと❗️ポリシーはサンプルとして AmazonEC2FullAccess を設定してある.

AWSTemplateFormatVersion: 2010-09-09

Resources:
  TerraformCloudRole:
    Type: AWS::IAM::Role
    Properties:
      RoleName: terraform-cloud-role
      AssumeRolePolicyDocument:
        Statement:
          - Effect: Allow
            Action: sts:AssumeRoleWithWebIdentity
            Principal:
              Federated: !Sub arn:aws:iam::${AWS::AccountId}:oidc-provider/app.terraform.io
            Condition:
              StringEquals:
                app.terraform.io:aud: aws.workload.identity
              StringLike:
                app.terraform.io:sub: organization:<Organization>:project:<Project>:workspace:<Workspace>:run_phase:<RunPhase>
      ManagedPolicyArns:
        - arn:aws:iam::aws:policy/AmazonEC2FullAccess

docs.aws.amazon.com

Step.3 Terraform Cloud に環境変数を設定する

最後は Terraform Cloud の Workspace で環境変数 (Environment variable) を2つ設定する.

  • TFC_AWS_PROVIDER_AUTH: true
  • TFC_AWS_RUN_ROLE_ARN: IAM Role の ARN(例: arn:aws:iam::<AccountId>:role/terraform-cloud-role

あとは Terraform Cloud で planapply を実行すれば OK❗️

\( 'ω')/ 簡単便利〜

関連記事

www.hashicorp.com

www.hashicorp.com