Terraform Cloudを使ったシークレットキー不要のAWSリソース管理
はじめに
AWS を中心にクラウド関連のキャッチアップを行なっていますが、悪戦苦闘している今日この頃です。
今回、 Terraform で AWS リソースを作成して遊んでいる際に、ふとチーム開発の時に tfstate の管理をどうやるのが良いかという疑問が生まれ、調べている中で Terraform Cloud に出会いました。
Terraform Cloud を使用することで、IAMユーザーやシークレットキーを発行することなく、OIDC(OpenID Connect)の仕組みを利用してAWSリソースの管理ができることを知り、体験として良かったので、今回はその方法について紹介します。
前準備
まず、Terraform Cloud のアカウントがない方は、以下のリンクからアカウントを作成してください。
Terraform Cloud 上にワークスペースを作成
Terraform Cloud にログイン後、任意の Organization を作成し、その中にワークスペースを作成します。今回は CLI を使用して動作確認を行うため、「CLI-Driven Workflow」でワークスペースを作成してください。
OIDC のためのAWSリソースを作成
まず、任意のディレクトリを作成し、その中に trust ディレクトリを作成します。次に、以下のファイルを作成します。
└── trust
├── main.tf
├── outputs.tf
├── terraform.tfvars
└── variables.tf
以下にmain.tfの内容を示します。
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "5.56.1"
}
}
}
provider "aws" {
default_tags {
tags = {
Terraform = "true"
}
}
}
# TLS 証明書を取得するためのデータソースを定義
data "tls_certificate" "terraform_cloud" {
url = "https://${var.terraform_cloud_host}"
}
# Terraform Cloud 用の OpenID Connect プロバイダを定義
resource "aws_iam_openid_connect_provider" "terraform_cloud" {
url = data.tls_certificate.terraform_cloud.url
# OpenID Connect audience
client_id_list = ["aws.workload.identity"]
thumbprint_list = [data.tls_certificate.terraform_cloud.certificates[0].sha1_fingerprint]
}
# 信頼ポリシー
data "aws_iam_policy_document" "terraform_assume_role_policy" {
statement {
effect = "Allow"
principals {
type = "Federated"
identifiers = [aws_iam_openid_connect_provider.terraform_cloud.arn]
}
actions = ["sts:AssumeRoleWithWebIdentity"]
condition {
test = "StringEquals"
variable = "${var.terraform_cloud_host}:aud"
values = [
# OpenID Connect audience
one(aws_iam_openid_connect_provider.terraform_cloud.client_id_list)
]
}
condition {
test = "StringLike"
variable = "${var.terraform_cloud_host}:sub"
values = [
"organization:${var.terraform_cloud_organization}:project:*:workspace:*:run_phase:*"
]
}
}
}
resource "aws_iam_role" "terraform_role" {
name = "terraform-role"
assume_role_policy = data.aws_iam_policy_document.terraform_assume_role_policy.json
}
# Terraform Cloud を介して AWS リソースを管理するためのポリシーになります。
# 用途によっては、より制限の厳しいポリシーを適用してください
data "aws_iam_policy_document" "terraform_policy" {
statement {
effect = "Allow"
actions = ["*"]
resources = ["*"]
}
}
resource "aws_iam_policy" "terraform_policy" {
name = "terraform-policy"
description = "Policy for Terraform Cloud"
policy = data.aws_iam_policy_document.terraform_policy.json
}
resource "aws_iam_role_policy_attachment" "terraform_policy_attachment" {
role = aws_iam_role.terraform_role.name
policy_arn = aws_iam_policy.terraform_policy.arn
}
variables.tf は以下のように定義します。
variable "terraform_cloud_host" {
type = string
description = "Terraform Cloud のホスト名"
}
variable "terraform_cloud_organization" {
type = string
description = "Terraform Cloud の組織名"
}
次に、terraform.tfvars を以下のように定義します。
terraform_cloud_host = "app.terraform.io"
terraform_cloud_organization = "作成した Organization の名前"
最後に、Terraform Cloud の設定で必要な IAM ロールの ARN を出力するために、outputs.tfを以下のように定義します。
output "role_arn" {
description = "Terraform 実行用のロール ARN"
value = aws_iam_role.terraform_role.arn
}
これで準備が整いました。terraform apply
を実行し、出力された IAM ロールの ARN を控えておいてください。
Terraform Cloud に環境変数を設定する
Terraform Cloud のダッシュボードで作成したワークスペースの詳細ページに進み、左側のサイドメニューから「Variables」を選択します。そして、以下の2つの環境変数を設定します。
環境変数名 | 値 |
---|---|
TFC_AWS_PROVIDER_AUTH | true |
TFC_AWS_RUN_ROLE_ARN | 手元に控えておいた IAM ロールの ARN |
これで OIDC 認証を行うための準備は全て完了となります!
Terraform Cloud の介して AWS リソースを作成する
ターミナルで terraform login
を実行し、表示される指示に従ってログインを行います。
次に、trust ディレクトリと同階層に infra ディレクトリを作成し、main.tf ファイルを新たに作成します。
├── infra
│ └── main.tf
└── trust
main.tf は以下のように定義します。
terraform {
cloud {
organization = "作成した Organization の名前"
workspaces {
name = "作成したワークスペースの名前"
}
}
required_providers {
aws = {
source = "hashicorp/aws"
version = "5.56.1"
}
}
}
provider "aws" {
region = "ap-northeast-1"
}
最後に、terraform apply
を実行して AWS リソースが作成できることを確認します。今回は、VPC を 1 つ作成します。
terraform {
cloud {
organization = "作成した Organization の名前"
workspaces {
name = "作成したワークスペースの名前"
}
}
required_providers {
aws = {
source = "hashicorp/aws"
version = "5.56.1"
}
}
}
provider "aws" {
region = "ap-northeast-1"
}
+ resource "aws_vpc" "main" {
+ cidr_block = "10.0.0.0/16"
+ enable_dns_support = true
+ enable_dns_hostnames = true
+ }
terraform apply
を実行し、期待通りにVPCが作成できました🎉
最後に
Terraform Cloud を活用することで、従来の IAM ユーザーやシークレットキーを使用せずに、セキュアかつ効率的に AWS リソースを管理する方法を紹介しました。また、Terraform Cloud の Free プランでは、1 organization あたりメンバー数に制限なく500
リソースまで作成可能であるため、チーム開発においても積極的に導入していく価値があるなと感じました。
Discussion