AWS+Terraform の記事を書くのってあまり好きじゃないんですけど、年末くらい1つ書いておこかなという義務感的なアレです、ハイ。
Terraform v0.7.8 から aws_iam_user_login_profile が追加され(CHANGELOG)、IAM User にログインパスワードを設定して、暗号化して state ファイルに保存できるようになったのでやってみましたという、たわい無い内容でございます。
概要
TerraformでIAM Userを作成します。管理画面ログイン用のパスワード設定も行い、パスワードは暗号化された状態で terraform.state に保存されます。aws_iam_user_login_profile に書いてありますが、使用する公開鍵は base64 でエンコードしたものを直書きするか、keybase のユーザー名を入力することになっています。今回はGPGコマンドを使って進行していきます。
GPG鍵の作成、Terraformでユーザー作成、暗号化パスワードの確認、パスワードの復号化、管理画面ログインの確認、といった流れになります。
今回の環境は、CentOS7.2 です。
GPGコマンドで鍵を生成する
鍵生成
一連の流れは gpgでのファイルの暗号化基礎 – akihiro_obの日記 を参考にするとよいでしょう。多分、入ってますが、gpg コマンドは gnupg2 に入ってるので、なければインストールしてください。まずは鍵を作成します。
1 2 |
yum -y install gnupg2 gpg --gen-key |
ほとんどデフォ値で進めてよく、入力するのは名前くらいです。今回は test_name としたことにします。また、パスワードは空にしたら怒られますけど入れるか空にするかは好みでいきましょう。パスワード有りにした場合、復号化する時にパスワードの入力を求められるだけです。
十分なエントロピーを供給する
鍵生成時に、キーボードやマウスを動かせとか、ディスクアクセスを── と要求してくるアレですが、環境によっては全然終わらないで無駄な時間を過ごすことになるので、強制的に十分なエントロピーを供給してやります。
1 2 3 |
yum -y install haveged systemctl start haveged systemctl stop haveged |
別のシェルで haveged を start するだけで、すぐ完了します。
鍵を保存する
あとで他の環境で復号化する時のために、鍵を取り出して、どこか共有のファイルサーバーなりS3なり保存しておきます。
1 2 3 4 5 6 7 |
cd /tmp gpg --list-keys gpg --list-secret-keys gpg -o ./test_name.public.gpg --export test_name gpg -o ./test_name.private.gpg --export-secret-key test_name # どこかに保存してから rm *.gpg |
TerraformでIAM Userを作成
公開鍵をBase64エンコードする必要があるため、さきほどの公開鍵をエンコードし、改行を取り除きファイルに出力しておきます。
1 2 |
cat test_name.public.gpg | base64 | tr -d '\n' > test_name.public.gpg.base64 cat test_name.public.gpg.base64 |
その文字列を使って、Terraformコードを書きます。
今回は全権限持ちのユーザーを、鍵とパスワード持ちで作る感じで。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
variable "pgp_key" { default = "wAENBFhSBCAC8Pn3LiIsZGyAEsP9D7i......ZRmB98Yxya7tbpAADJmJWkwnyISPh0tw=" } resource "aws_iam_user" "admin" { name = "admin" } resource "aws_iam_user_policy_attachment" "admin" { user = "${aws_iam_user.admin.name}" policy_arn = "arn:aws:iam::aws:policy/AdministratorAccess" } resource "aws_iam_user_login_profile" "admin" { user = "${aws_iam_user.admin.name}" pgp_key = "${var.pgp_key}" password_reset_required = false } output "aws_iam_user_admin_password" { value = "${aws_iam_user_login_profile.admin.encrypted_password}" } |
apply を実行すると、こんな感じで output の結果が表示され、terraform.state にも暗号化パスワードが残ることになります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
~snip~ aws_iam_policy_attachment.admin: Creation complete Apply complete! Resources: 3 added, 0 changed, 0 destroyed. The state of your infrastructure has been saved to the path below. This state is required to modify and destroy your infrastructure, so keep it safe. To inspect the complete state use the `terraform show` command. State path: terraform.tfstate Outputs: aws_iam_user_admin_password = wAENBFhSBCAC8Pn3LiIsZGyAEsP9D7i......ZRmB98Yxya7tbpAADJmJWkwnyISPh0tw= |
コンソールログインの確認
パスワードの復号化
さきほど、apply 実行時に Outputs に表示された文字列を echo してもいいのですが、せっかくデータが保存されてるので terraform コマンドからパスワードを復号化してみます。
1 2 |
terraform output aws_iam_user_admin_password | base64 -d | gpg -r test_name P}%u0eZ1P2I2lE3^ha[@ |
デフォでこんな20文字のパスワードになります。
鍵にパスワードを設定している場合、このタイミングで入力します。
秘密鍵のインポート
もし、他の環境で復号化したい場合は、秘密鍵をインポートしてから上記コマンドを打つ必要があります。
1 |
gpg --import test_name.private.gpg |
コンソールログインの確認
IAMダッシュボードにあるサインインリンクにアクセスし、作成したユーザー名と、復号化したパスワードでログインの確認がとれれば完了です。パスワードを暗号化してくれて、ちゃんと実装してくれたなーという印象ではあるのですが、aws_iam_access_key でアクセスキーも作成した場合、terraform.state にアクセスキーが平文で残ってしまうので、意味がないとは言いませんが、結局はTerraformコードを厳重管理する必要があるのは変わりないですね。
小さなことからコツコツ系エントリということで、お疲れ様でした:-)