使用Terraform创建AWS(EC2)的密钥对
假设
- Terraform 0.11系。
解释
- 以下のように「ssh-keygen」などで作成したものを利用しているのを、Terraformの方に作成までやらせてみる。
ssh-keygen -t rsa -b 4096 -C '' -N '' -f example.id_rsa
tf文件
生成密钥对 duì)
「TLS」プロバイダの「tls_private_key」リソースを利用して作成する。
https://www.terraform.io/docs/providers/tls/r/private_key.html
/**
* require
**/
terraform {
required_version = ">= 0.11.0"
}
/**
* variable
**/
variable "key_name" {
type = "string"
description = "keypair name"
#default = "example" # キー名を固定したかったらdefault指定。指定なしならインタラクティブにキー入力して決定。
}
# キーファイル
## 生成場所のPATH指定をしたければ、ここを変更するとよい。
locals {
public_key_file = "./${var.key_name}.id_rsa.pub"
private_key_file = "./${var.key_name}.id_rsa"
}
/**
* resource
**/
# キーペアを作る
resource "tls_private_key" "keygen" {
algorithm = "RSA"
rsa_bits = 4096
}
/**
* file
**/
# 秘密鍵ファイルを作る
resource "local_file" "private_key_pem" {
filename = "${local.private_key_file}"
content = "${tls_private_key.keygen.private_key_pem}"
# local_fileでファイルを作ると実行権限が付与されてしまうので、local-execでchmodしておく。
provisioner "local-exec" {
command = "chmod 600 ${local.private_key_file}"
}
}
resource "local_file" "public_key_openssh" {
filename = "${local.public_key_file}"
content = "${tls_private_key.keygen.public_key_openssh}"
# local_fileでファイルを作ると実行権限が付与されてしまうので、local-execでchmodしておく。
provisioner "local-exec" {
command = "chmod 600 ${local.public_key_file}"
}
}
/**
* output
**/
# キー名
output "key_name" {
value = "${var.key_name}"
}
# 秘密鍵ファイルPATH(このファイルを利用してサーバへアクセスする。)
output "private_key_file" {
value = "${local.private_key_file}"
}
# 秘密鍵内容
output "private_key_pem" {
value = "${tls_private_key.keygen.private_key_pem}"
}
# 公開鍵ファイルPATH
output "public_key_file" {
value = "${local.public_key_file}"
}
# 公開鍵内容(サーバの~/.ssh/authorized_keysに登録して利用する。)
output "public_key_openssh" {
value = "${tls_private_key.keygen.public_key_openssh}"
}
AWS账户信息
provider "aws" {
profile = "example"
region = "ap-northeast-1"
}
- 「profile」にはAWS CLIのプロファイル名を指定。
注册为EC2密钥对
「AWS」プロバイダの「aws_key_pair」リソースを利用。
https://www.terraform.io/docs/providers/aws/r/key_pair.html
resource "aws_key_pair" "key_pair" {
key_name = "${var.key_name}"
public_key = "${tls_private_key.keygen.public_key_openssh}"
}
用法
- キーペア作成するだけなら、AWSプロバイダ関連の記述は不要(上記tfファイル群のうち「keygen.tf」だけで良い)。
计划
terraform plan
var.key_name
keypair name
Enter a value:
- キーペア名を聞かれるので、「example」と入力すると、以下のように表示される。
An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
+ create
Terraform will perform the following actions:
+ local_file.private_key_pem
id: <computed>
content: "${tls_private_key.keygen.private_key_pem}"
filename: "./example.id_rsa"
+ local_file.public_key_openssh
id: <computed>
content: "${tls_private_key.keygen.public_key_openssh}"
filename: "./example.id_rsa.pub"
+ tls_private_key.keygen
id: <computed>
algorithm: "RSA"
ecdsa_curve: "P224"
private_key_pem: <computed>
public_key_fingerprint_md5: <computed>
public_key_openssh: <computed>
public_key_pem: <computed>
rsa_bits: "4096"
Plan: 3 to add, 0 to change, 0 to destroy.
申请
terraform plan
var.key_name
keypair name
Enter a value:
- ここでもキーペア名を聞かれるので、「example」と入力すると、以下のように表示される。
An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
+ create
Terraform will perform the following actions:
+ local_file.private_key_pem
id: <computed>
content: "${tls_private_key.keygen.private_key_pem}"
filename: "./example.id_rsa"
+ local_file.public_key_openssh
id: <computed>
content: "${tls_private_key.keygen.public_key_openssh}"
filename: "./example.id_rsa.pub"
+ tls_private_key.keygen
id: <computed>
algorithm: "RSA"
ecdsa_curve: "P224"
private_key_pem: <computed>
public_key_fingerprint_md5: <computed>
public_key_openssh: <computed>
public_key_pem: <computed>
rsa_bits: "4096"
Plan: 3 to add, 0 to change, 0 to destroy.
Do you want to perform these actions?
Terraform will perform the actions described above.
Only 'yes' will be accepted to approve.
Enter a value:
-
- 最終確認が入るので、「yes」と入力すると、キーペアが作成される。
AWSへのEC2キーペア登録もするなら、同時に登録される。
可以按照以下的方式指定变量。
terraform apply -var 'key_name=example'
请留意
-
- ssh-keygenと同じような感覚で、このまま「キーペア生成ツール」としては利用できない。
「key_name」変数を変更すると、既に作成したキーペアファイルが削除(destroy)されてしまう。
lifecycleブロックで適切にignore_changes 指定してやればいける?(未検証)
以下で検証した通り、単にignore_changes指定しただけでは「キーペア生成ツール」として利用することはできない、ということが分かった。
【追記】关于ignore_changes的验证结果
- 例えば以下のように、上記例「keygen.tf」のうち、秘密鍵(private_key_pem)、公開鍵(public_key_openssh)それぞれについて、lifecycleブロックで「filename」をignore_changes指定してやったところ、削除(destroy)はされなくなったものの、単にそれだけで、再生成自体が行われなくなった。
resource "local_file" "private_key_pem" {
filename = "${local.private_key_file}"
content = "${tls_private_key.keygen.private_key_pem}"
provisioner "local-exec" {
command = "chmod 600 ${local.private_key_file}"
}
lifecycle {
ignore_changes = [
"filename",
]
}
}
-
- 考えてみれば当たり前のことで、「ignore_changes」は変更を無視するということなんだから、ここに「filename」を指定すれば、「変数の値を変更してファイル名が変わったとしても、何もしない。」となるだけの、至って正常な挙動だった。
-
- 「lifecycle」ブロックには、「ignore_changes」も含め、以下のような項目がある。(※ 詳細はマニュアル参照)
ignore_changes
指定した属性の変更を無視して何もしない。
属性名をlist指定
prevent_destroy
このリソースをdestroyしない。変更などの影響でdestroyが実行されるとエラーになる。
true/falseのbool指定
create_before_destroy
同名リソースを再生成(create)する時に、先に削除(destroy)する。
false指定すると、createしてからdestroyするようになるという、処理順制御の項目。(削除はされる)
true/falseのbool指定
暗黙のデフォルト値は「true」になっている。
因此,结论是“无法像ssh-keygen命令一样,只能生成密钥对的工具不能使用。”相反,如果不将密钥名称变为变量,那么删除或生成操作将与tf文件的描述内容相联动,可能可以将其作为“密钥管理工具”来使用。
参考资料等
关于模块
-
- 外部モジュールとして指定してやれば、変数指定だけで利用できたりする。
- 「Terraform Module Registry」で探すと良い。
One possible paraphrase in Chinese for “参考モジュール” is “参考模块” .
cloudposse/terraform-aws-key-pair: Terraform Module to Automatically Generate SSH Key Pairs (Public/Private Keys)
https://github.com/cloudposse/terraform-aws-key-pair
Terraform Module Registry URL
https://registry.terraform.io/modules/cloudposse/key-pair
様々なTerraformモジュールを作っている「Cloud Posse」謹製モジュール。色々指定できる。ガッツリ系。
cloudposse/terraform-tls-ssh-key-pair: Terraform module for generating an SSH public/private key file.
https://github.com/cloudposse/terraform-tls-ssh-key-pair
Terraform Module Registry URL
https://registry.terraform.io/modules/cloudposse/ssh-key-pair
上記モジュールからAWS部分を除外して、キーペア作成だけにしたもの。
mitchellh/terraform-aws-dynamic-keys: Terraform module that dynamically generates a public/private keypair.
https://github.com/mitchellh/terraform-aws-dynamic-keys
Terraform Module Registry URL
https://registry.terraform.io/modules/mitchellh/dynamic-keys
Terraformを作っているHashiCorp代表、ミッチェル・ハシモト氏(mitchellh)謹製モジュール。アッサリ系。分かりやすい。
今回の記事は、ほぼこのモジュール内容のパクリ。