Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Secretless Terraform

Kerim Satirli
September 29, 2020

Secretless Terraform

In this talk, Rob Barnes (Developer Advocate at HashiCorp) and I look at how to use Terraform to write and read random passwords and how to create cloud resources, without seeing secret data such as instance passwords.

This version of the presentation was given at a DevOps Oxford meetup in September 2020.

---

Companion Code: github.com/ksatirli/secretless-terraform

Kerim Satirli

September 29, 2020
Tweet

More Decks by Kerim Satirli

Other Decks in Technology

Transcript

  1. Agenda Adding Secrets to Vault Creating passwords with the Random

    Provider Consuming Secrets with Terraform Reading passwords with the Vault Provider Questions and Answers Ask us anything (related to Terraform and Vault)
  2. Environment TERMINAL > vault status Key Value --- ----- Seal

    Type shamir Initialized true Sealed false Total Shares 1 Threshold 1 Version 1.5.3 Cluster Name vault
  3. Generating Random Data CODE EDITOR resource "random_password" "pass" { length

    = 16 special = false } locals { pass = jsonencode({ "pass" : random_password.pass.result }) }
  4. Writing Data to Vault CODE EDITOR resource "vault_generic_secret" "aws_db_instance" {

    path = "secret/aws_db_instance" data_json = local.pass }
  5. Writing Data to Vault TERMINAL > terraform plan -out="provisioner.tfplan" Terraform

    will perform the following actions: # vault_generic_secret.aws_db_instance will be created + resource "vault_generic_secret" "aws_db_instance" { + data = (sensitive value) + data_json = (sensitive value) + disable_read = false + id = (known after apply) + path = "secret/aws_db_instance" } Plan: 1 to add, 0 to change, 0 to destroy.
  6. Writing Data to Vault TERMINAL > terraform apply "provisioner.tfplan" vault_generic_secret.aws_db_instance:

    Creating... vault_generic_secret.aws_db_instance: Creation complete after 0s Apply complete! Resources: 1 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
  7. Writing Data to Vault TERMINAL Apply complete! Resources: 1 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: instance_password = tx964n7QA2cD3xmi
  8. Reading Data from Vault CODE EDITOR data "aws_vpc" "secretless_terraform" {

    } resource "aws_security_group" "secretless_terraform" { } resource "aws_security_group_rule" "allow_from_self" { }
  9. Reading Data from Vault CODE EDITOR data "vault_generic_secret" "aws_db_instance" {

    path = "secret/aws_db_instance" version = 1 } resource "aws_db_instance" "secretless_terraform" { password = data.vault_generic_secret.pass.data["password"] }
  10. Reading Data from Vault TERMINAL Terraform will perform the following

    actions: # aws_db_instance.secretless_terraform will be created + resource "aws_db_instance" "secretless_terraform" { + password = (sensitive value) } # aws_security_group.secretless_terraform will be created + resource "aws_security_group" "secretless_terraform" {} # aws_security_group_rule.allow_mysql_from_self will be created + resource "aws_security_group_rule" "allow_mysql_from_self" {} Plan: 3 to add, 0 to change, 0 to destroy.
  11. Reading Data from Vault TERMINAL > terraform apply "consumer.tfplan" aws_security_group.secretless_terraform:

    Creating... aws_security_group.secretless_terraform: Creation complete aws_security_group_rule.allow_mysql_from_self: Creating... aws_security_group_rule.allow_mysql_from_self: Creation complete aws_db_instance.secretless_terraform: Creating... aws_db_instance.secretless_terraform: Creation complete Apply complete! Resources: 3 added, 0 changed, 0 destroyed. Outputs:
  12. Reading Data from Vault TERMINAL Outputs: connection_string = \ mysql

    --host="instance.eu-west-2.rds.amazonaws.com" \ --port="3306" \ --user="devops" \ --password="tx964n7QA2cD3xmi"
  13. Connecting to RDS TERMINAL mysql --host="instance.eu-west-2.rds.amazonaws.com" --port="3306" --user="devops" --password="tx964n7QA2cD3xmi" mysql:

    [Warning] Using a password on the command line interface can be insecure. Welcome to the MySQL monitor. Server version: 5.5.5-10.4.8-MariaDB Source distribution
  14. Connecting to RDS TERMINAL mysql> SHOW DATABASES; +----------------------+ | Database

    | +----------------------+ | information_schema | | innodb | | mysql | | performance_schema | | secretless_terraform | | test | +----------------------+ 6 rows in set (0.10 sec)