はじめに
Terraformで複数のtfファイルを定期的にapply, destroyする必要があり、スクリプトを使って楽をしたいなぁという話になりました。
以下の流れをそれぞれスクリプトに分けて自動化したいです。
- IAMユーザーを作成
-
- のユーザーでリソースを作成
-
- のユーザーでリソースを削除
まずは、手動での実行がどのようなものか自分自身が理解する必要がありそうだなと。
ということで、TerraformとGnuPGを使って初期パスワードとアクセスキーを持つIAMユーザを作成してみます。
- IAMユーザを作成
-
- のユーザーでリソースを作成
環境
$ sw_vers
ProductName: macOS
ProductVersion: 11.1
BuildVersion: 20C69
$ terraform -version
Terraform v0.14.4
$ gpg --version
gpg (GnuPG) 2.2.27
libgcrypt 1.8.7
やること
- IAMユーザ作成のtfファイルを準備
- GnuPGを使って、公開鍵を作成。
gpg_key
に公開鍵を設定 - Administrator権限を持つユーザで
terraform apply
-
- で作成されたパスワードやシークレットアクセスキーを複合化
- EC2インスタンス作成のtfファイルを準備
- 複合化したシークレットアクセスキーをもとに、
terrafom apply
1. IAMユーザ作成のtfファイルを準備
$ tree
.
├── main.tf
├── outputs.tf
├── terraform.tfvars
├── variables.tf
└── version.tf
最低限EC2に関するポリシーがあれば良いので、以下のように各ファイルを作成。
resource "aws_iam_user" "ec2_execution_user" {
name = "ec2_execution_user"
tags = {
tag-key = "qiita"
}
}
resource "aws_iam_access_key" "user_access_key" {
user = aws_iam_user.ec2_execution_user.name
pgp_key = var.pgp_key
}
resource "aws_iam_user_policy" "ec2_execution_user_role" {
name = "ec2_execution_user_role"
user = aws_iam_user.ec2_execution_user.name
policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Action": [
"ec2:*"
],
"Effect": "Allow",
"Resource": "*"
}
]
}
EOF
}
resource "aws_iam_user_login_profile" "ec2_user_profile" {
user = aws_iam_user.ec2_execution_user.name
pgp_key = var.pgp_key
password_reset_required = false
depends_on = [aws_iam_user.ec2_execution_user]
}
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = ">= 3.24.0"
}
}
required_version = ">= 0.14.0"
}
output "first_password" {
value = aws_iam_user_login_profile.ec2_user_profile.encrypted_password
description = "IAMユーザの暗号化されたパスワード"
}
output "secret_access" {
value = aws_iam_access_key.user_access_key.encrypted_secret
description = "IAMユーザの暗号化されたシークレットキー"
}
variable "pgp_key" {
description = "IAMユーザーのパスワード生成で利用するpgpの公開鍵(base64形式)"
type = string
}
terraform.tfvars
については空欄にしておきます。
pgp_key = ""
2. GnuPGを使って、公開鍵を作成
IAMユーザを作成するにあたって、初期パスワードを暗号化して出力する必要があるため公開鍵を作成していきます。
また、日本語の公式サイトもあったのでこちらも見つつ進めます。
-
gpgのインストール
$ brew install gpg
-
鍵の出力
name
は任意の値を入力しています。$ gpg -o ./name.public.gpg --export name $ gpg -o ./name.private.gpg --export-secret-key name
-
Base64エンコード
公開鍵をBase64エンコードする必要があるようです。
この辺りも見る限り、AWSではBase64エンコードされたデータを扱っていると理解すれば良いのかな。
https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_user_login_profile#attributes-reference$ cat name.public.gpg | base64 | tr -d '\n' > name.public.gpg.base64 $ cat name.public.gpg.base64
-
出力された値を設定
catで出力された値をコピーし、
terraform.tfvars
に設定する。terraform.tfvarspgp_key = "mQGNBGAEO6cBDADVf3FBHM…"
3. Administrator権限を持つユーザで terraform apply
$ export AWS_ACCESS_KEY_ID=xxxx
$ export AWS_SECRET_ACCESS_KEY=xxxxxxx
$ aws sts get-caller-identity --query Account --output text
[Administrator権限を持つユーザ]
$ terraform init
$ terraform apply
…
Apply complete! Resources: 4 added, 0 changed, 0 destroyed.
Outputs:
first_password = "xxx"
secret_access = "xxx"
4. 3. で作成されたパスワードやシークレットアクセスキーを複合化
まずは初期パスワードである first_password
を複合化します。
$ export GPG_TTY=$(tty)
$ echo "[first_password]" | base64 -d | gpg -r name
gpg: *警告*: コマンドが指定されていません。なにを意味しているのか当ててみます ...
gpg: 3072-ビットRSA鍵, ID 503Fxxxxx, 日付2021-01-17に暗号化されました
"name <xxxx@icloud.com>"
xxxxxxxxxx
同様に、シークレットアクセスキーを複合化します。
$ echo "[secret_access]" | base64 -d | gpg -r name
gpg: *警告*: コマンドが指定されていません。なにを意味しているのか当ててみます ...
gpg: 3072-ビットRSA鍵, ID 503xxxxxxx, 日付2021-01-17に暗号化されました
"name <xxxxx@icloud.com>"
xxxxxxx
5. EC2インスタンス作成のtfファイルを準備
t2.micro
を構築するtfファイルを作成します。
$ tree
.
├── main.tf
└── version.tf
resource "aws_instance" "ec2_instance_t2" {
ami = "ami-0cc75a8978fbbc969"
instance_type = "t2.micro"
tags = {
tag_key = "qiita"
}
}
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = ">= 3.24.0"
}
}
required_version = ">= 0.14.0"
}
6. 複合化したシークレットアクセスキーをもとに、 terrafom apply
以前の手順で複合化したシークレットアクセスキーとアクセスキーを使ってユーザを切り替えます。
$ export AWS_ACCESS_KEY_ID=xxxx
$ export AWS_SECRET_ACCESS_KEY=xxxxxxx
$ aws sts get-caller-identity --query Account --output text
[新しく作成したIAMユーザ]
無事切り替えできました。よかった!
では terraform apply
をします。
$ terraform init
$ terraform apply
…
Apply complete! Resources: 1 added, 0 changed, 0 destroyed.
こちらも無事に作成できました!
このようにGnuPGを使った暗号化・複合化の手順も自動化する必要がありそうだということがわかったので、今回の目的は達成。