├── .gitignore ├── README.md ├── main.tf ├── outputs.tf └── variables.tf /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | *.dll 3 | *.exe 4 | .DS_Store 5 | example.tf 6 | terraform.tfplan 7 | terraform.tfstate 8 | bin/ 9 | modules-dev/ 10 | /pkg/ 11 | website/.vagrant 12 | website/.bundle 13 | website/build 14 | website/node_modules 15 | .vagrant/ 16 | *.backup 17 | ./*.tfstate 18 | .terraform/ 19 | *.log 20 | *.bak 21 | *~ 22 | .*.swp 23 | .idea 24 | *.iml 25 | *.test 26 | *.iml 27 | *.versions.tf 28 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | AWS Dynamic Keypair 2 | ======================== 3 | 4 | This Terraform module dynamically generates an SSH key pair, imports it 5 | into AWS, and provides the keypair via outputs. 6 | 7 | This can be used to create AWS resources with a keypair that doesn't have 8 | to exist prior to the Terraform run. This is great for demos! Warning that 9 | the private key information will be in the Terraform state, so this isn't 10 | well suited currently for production environments. 11 | 12 | What This Module Does 13 | --------------------- 14 | 15 | Features: 16 | 17 | * Creates a public/private keypair. 18 | 19 | * Writes the keypair into files (optional). 20 | 21 | * Imports the keypair into AWS. 22 | 23 | * Provides the OpenSSH-formatted public key and a PEM-encoded private 24 | key as output values that can be used directly with `connection` blocks. 25 | 26 | Usage 27 | ----- 28 | 29 | Run `terraform apply` against the example configuration below: 30 | 31 | ```hcl 32 | provider "aws" { 33 | version = "~> 1.0.0" 34 | region = "us-west-2" 35 | } 36 | 37 | module "keypair" { 38 | source = "mitchellh/dynamic-keys/aws" 39 | path = "${path.root}/keys" 40 | } 41 | 42 | output "private_key_pem" { 43 | value = "${module.keypair.private_key_pem}" 44 | } 45 | ``` 46 | 47 | The SSH keys created are also in the `./keys` subdirectory relative to 48 | the root Terraform configuration if you need those for any other reason. 49 | These keys will be automatically deleted and removed when your configuration 50 | is destroyed (via `terraform destroy`). 51 | 52 | Terraform version 53 | ----------------- 54 | 55 | Terraform version 0.11.0 or newer is required for this version to work. 56 | -------------------------------------------------------------------------------- /main.tf: -------------------------------------------------------------------------------- 1 | terraform { 2 | required_version = ">= 0.12.0" 3 | } 4 | 5 | locals { 6 | public_key_filename = "${var.path}/${var.name}.pub" 7 | private_key_filename = "${var.path}/${var.name}.pem" 8 | } 9 | 10 | resource "tls_private_key" "generated" { 11 | algorithm = "RSA" 12 | } 13 | 14 | resource "aws_key_pair" "generated" { 15 | key_name = var.name 16 | public_key = tls_private_key.generated.public_key_openssh 17 | 18 | lifecycle { 19 | ignore_changes = [key_name] 20 | } 21 | } 22 | 23 | resource "local_file" "public_key_openssh" { 24 | count = var.path != "" ? 1 : 0 25 | content = tls_private_key.generated.public_key_openssh 26 | filename = local.public_key_filename 27 | } 28 | 29 | resource "local_file" "private_key_pem" { 30 | count = var.path != "" ? 1 : 0 31 | content = tls_private_key.generated.private_key_pem 32 | filename = local.private_key_filename 33 | } 34 | 35 | resource "null_resource" "chmod" { 36 | count = var.path != "" ? 1 : 0 37 | depends_on = [local_file.private_key_pem] 38 | 39 | triggers = { 40 | key = tls_private_key.generated.private_key_pem 41 | } 42 | 43 | provisioner "local-exec" { 44 | command = "chmod 600 ${local.private_key_filename}" 45 | } 46 | } 47 | 48 | -------------------------------------------------------------------------------- /outputs.tf: -------------------------------------------------------------------------------- 1 | output "key_name" { 2 | value = aws_key_pair.generated.key_name 3 | } 4 | 5 | output "public_key_openssh" { 6 | value = tls_private_key.generated.public_key_openssh 7 | } 8 | 9 | output "private_key_pem" { 10 | value = tls_private_key.generated.private_key_pem 11 | sensitive = true 12 | } 13 | 14 | output "public_key_filepath" { 15 | value = local.public_key_filename 16 | } 17 | 18 | output "private_key_filepath" { 19 | value = local.private_key_filename 20 | } 21 | 22 | -------------------------------------------------------------------------------- /variables.tf: -------------------------------------------------------------------------------- 1 | variable "name" { 2 | description = "Unique name for the key, should also be a valid filename. This will prefix the public/private key." 3 | } 4 | 5 | variable "path" { 6 | description = "Path to a directory where the public and private key will be stored." 7 | default = "" 8 | } 9 | 10 | --------------------------------------------------------------------------------