LoginSignup
13
6

More than 3 years have passed since last update.

Terraformで初期パスワードとシークレットアクセスキーを持つIAMユーザを作成する

Posted at

はじめに

Terraformで複数のtfファイルを定期的にapply, destroyする必要があり、スクリプトを使って楽をしたいなぁという話になりました。

以下の流れをそれぞれスクリプトに分けて自動化したいです。

  1. IAMユーザーを作成
  2. 1. のユーザーでリソースを作成
  3. 1. のユーザーでリソースを削除

まずは、手動での実行がどのようなものか自分自身が理解する必要がありそうだなと。
ということで、TerraformとGnuPGを使って初期パスワードとアクセスキーを持つIAMユーザを作成してみます。

  1. IAMユーザを作成
  2. 1. のユーザーでリソースを作成

環境

$ 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

やること

  1. IAMユーザ作成のtfファイルを準備
  2. GnuPGを使って、公開鍵を作成。 gpg_key に公開鍵を設定
  3. Administrator権限を持つユーザで terraform apply
  4. 3. で作成されたパスワードやシークレットアクセスキーを複合化
  5. EC2インスタンス作成のtfファイルを準備
  6. 複合化したシークレットアクセスキーをもとに、 terrafom apply

1. IAMユーザ作成のtfファイルを準備

$ tree
.
├── main.tf
├── outputs.tf
├── terraform.tfvars
├── variables.tf
└── version.tf

最低限EC2に関するポリシーがあれば良いので、以下のように各ファイルを作成。

main.tf

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]
}
version.tf
terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = ">= 3.24.0"
    }
  }
  required_version = ">= 0.14.0"
}
outputs.tf
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ユーザの暗号化されたシークレットキー"
}
variables.tf
variable "pgp_key" {
  description = "IAMユーザーのパスワード生成で利用するpgpの公開鍵(base64形式)"
  type        = string
}

terraform.tfvars については空欄にしておきます。

terraform.tfvars
pgp_key = ""

2. GnuPGを使って、公開鍵を作成

IAMユーザを作成するにあたって、初期パスワードを暗号化して出力する必要があるため公開鍵を作成していきます。

公開鍵設定について

また、日本語の公式サイトもあったのでこちらも見つつ進めます。

  1. gpgのインストール

    $ brew install gpg
    
  2. 鍵の出力
    name は任意の値を入力しています。

    $ gpg -o ./name.public.gpg  --export name
    $ gpg -o ./name.private.gpg --export-secret-key name
    
  3. 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
    
  4. 出力された値を設定

    catで出力された値をコピーし、 terraform.tfvars に設定する。

    terraform.tfvars
    pgp_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
main.tf
resource "aws_instance" "ec2_instance_t2" {
  ami           = "ami-0cc75a8978fbbc969"
  instance_type = "t2.micro"

  tags = {
    tag_key = "qiita"
  }
}
version.tf
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を使った暗号化・複合化の手順も自動化する必要がありそうだということがわかったので、今回の目的は達成。

13
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
13
6