【AWS】AssumeRoleしてTerraformをより安全に実行する!

August 14, 2020

S3で静的ウェブサイトを公開するための方法を解説します。

目次

  • 仕組み
  • AssumeRoleするユーザー
  • Terraformの設定
  • Terraformの実行


仕組み

TerraformでAssumeRoleする仕組み

ポイントは、Terraformで使用するIAMユーザーには、SystemAdminロール(独自に作成したシステム管理用のロール)にAssumeRoleできるだけの権限しか与えてないことです。そのため、もしこのユーザーのアクセスキーが流出した場合でも被害を最小限に抑えることができます。


AssumeRoleするユーザー

今回使用するIAMユーザーに付与するポリシーです。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "sts:AssumeRole",
            "Resource": "arn:aws:iam::XXXXXXXXXX:role/SystemAdmin"
        }
    ]
}

“Action”: “sts:AssumeRole”:AssumeRole 指定します。

“Resource”: “arn:aws:iam::XXXXXXXXXX:role/SystemAdministrator”:SystemAdminロールを指定します。

以上の設定でSystemAdminロールにAssumeRoleできるようになります。

また、Terraformを実行する環境にて、IAMユーザーの認証情報の設定もお忘れなく!

~/.aws/credentials

[default]
aws_access_key_id = [アクセスキー]
aws_secret_access_key = [シークレットキー]

~/.aws/config

[default]
region = [リージョン]
output = json

Terraformの設定

providerbackend でAssumeRoleを設定していきます。

provider "aws" {
  region = "ap-northeast-1"
  assume_role {
    role_arn = "arn:aws:iam::XXXXXXXXXX:role/SystemAdmin"
  }
}

terraform {
  required_version = "0.12.24"
  backend "s3" {
    bucket   = "tfstate.mini-schna.com"
    region   = "ap-northeast-1"
    key      = "blog/public-s3.tfstate"
    encrypt  = true
    role_arn = "arn:aws:iam::XXXXXXXXXX:role/SystemAdmin"
  }
}

module "aws" {
  source = "./modules"
}

それでは、解説していきます。注目して欲しい箇所は2箇所。

provider "aws" {
  region = "ap-northeast-1"
  assume_role {
    role_arn = "arn:aws:iam::XXXXXXXXXX:role/SystemAdmin"
  }
}

assume_role { role_arn = "arn:aws:iam::XXXXXXXXXX:role/SystemAdmin" }role_arn にAssumeRoleしたいロールのARNを設定します。今回は、SystemAdminロールのARNを指定しました。


backend "s3" {
  bucket   = "tfstate.mini-schna.com"
  region   = "ap-northeast-1"
  key      = "blog/public-s3.tfstate"
  encrypt  = true
  role_arn = "arn:aws:iam::XXXXXXXXXX:role/SystemAdmin"
}

role_arn にAssumeRoleしたいロールのARNを設定します。今回は、SystemAdminロールのARNを指定しました。


Terraformの実行

作成したコードでTerraformを実行してみると以下のようなります。

# Terraformの処理が分かるようにログレベルをDEBUGにして実行しています。(TF_LOG=DEBUG)
$ TF_LOG=DEBUG terraform init
...
-----------------------------------------------------
2020/08/14 00:28:45 [DEBUG] [aws-sdk-go] DEBUG: Response sts/GetCallerIdentity Details:
---[ RESPONSE ]--------------------------------------
HTTP/1.1 200 OK
Connection: close
Content-Length: 456
Content-Type: text/xml
Date: Fri, 14 Aug 2020 00:28:44 GMT
X-Amzn-Requestid: XXXXXXXXXXX

-----------------------------------------------------
2020/08/14 00:28:45 [DEBUG] [aws-sdk-go] <GetCallerIdentityResponse xmlns="https://sts.amazonaws.com/doc/2011-06-15/">
  <GetCallerIdentityResult>
    # 「SystemAdmin」 に AssumeRole しています。
    <Arn>arn:aws:sts::XXXXXXXXXXX:assumed-role/SystemAdmin/XXXXXXXXXXXX</Arn>
    <UserId>XXXXXXXXXXX:XXXXXXXXXXX</UserId>
    <Account>XXXXXXXXXXX</Account>
  </GetCallerIdentityResult>
  <ResponseMetadata>
    <RequestId>XXXXXXXXXXX</RequestId>
  </ResponseMetadata>
</GetCallerIdentityResponse>
...

今回は分かりやすいようにTerraformのログレベルをDEBUGにして、処理の詳細を確認できるようにしています。このログから、AssumeRoleが上手くいっていることが分かります。

以上で、AssumeRoleしてTerraformが実行できるようになりました。

最後までご覧頂きありがとうございました。