HashiCorp Learn
Infrastructure
  • TerraformTerraformLearn terraformDocs
  • PackerPackerLearn packerDocs
  • VagrantVagrantLearn vagrantDocs
Security
  • VaultVaultLearn vaultDocs
  • BoundaryBoundaryLearn boundaryDocs
Networking
  • ConsulConsulLearn consulDocs
Applications
  • NomadNomadLearn nomadDocs
  • WaypointWaypointLearn waypointDocs
  • HashiCorp Cloud Platform (HCP) LogoHashiCorp Cloud Platform (HCP)HashiCorp Cloud Platform (HCP)Docs
Type '/' to Search
Loading account...
  • Bookmarks
  • Manage Account
  • Overview
  • Challenge
  • Solution
  • Prerequisites
  • Scenario introduction
  • Examine the Terraform files
  • Run Terraform to configure Vault
  • Verify the configuration
  • Clean up
  • Next steps
  • Help and Reference
DocsForum
Back to vault
FundamentalsView Collection
    Configure VaultVault High Availability with ConsulProduction HardeningVault PoliciesIdentity: Entities and GroupsGenerate Root Tokens Using Unseal KeysRekeying & Rotating VaultProtecting Vault with Resource QuotasCodify Management of VaultCodify Management of Vault EnterpriseTroubleshooting VaultPerformance TuningVault Usage Metrics

Codify Management of Vault

  • 8 min
  • Products Usedvaultterraform
  • This tutorial also appears in: Use Cases and Interactive.

»Challenge

A manual system administration can become a challenge as the scale of infrastructure increases. Often, an organization must manage multiple Vault environments (development, testing, staging, production, etc.). Keeping up with the increasing management demand soon becomes a challenge without some sort of automation.

»Solution

One of the pillars behind the Tao of Hashicorp is automation through codification.

HashiCorp Terraform is an infrastructure as code which enables the operation team to codify the Vault configuration tasks such as the creation of policies. Automation through codification allows operators to increase their productivity, move quicker, promote repeatable processes, and reduce human error.

This tutorial demonstrates techniques for creating Vault policies and configurations using Terraform Vault Provider.

NOTE: This tutorial focuses on codifying the Vault server configuration using Terraform. To deploy a Vault cluster using Terraform, refer to the Provision a Best Practices Vault Cluster in AWS for an example.

»Prerequisites

  • Terraform installed

  • A Vault environment to connect

    To test and learn the use of Vault provider, you can use a Vault server running in development mode since you are going to perform Vault admin tasks in this tutorial.

Online tutorial: An interactive tutorial is also available if you do not wish to install a Vault HA cluster locally. Click the Show Terminal button to start.

»Scenario introduction

Vault administrators must manage multiple Vault environments. The test servers get destroyed at the end of each test cycle and a new set of servers must be provisioned for the next test cycle. To automate the Vault server configuration, you are going to use Terraform to provision the following Vault resources.

TypeNameDescription
ACL PolicyadminsSets policies for the admin team
ACL Policyeaas-clientSets policies for clients to encrypt/decrypt data through transit secrets engine
auth methoduserpassEnable and create a user, "student" with admins and fpe-client policies
secrets enginekv-v2Enable kv-v2 secrets engine at kv-v2
secrets enginetransitEnable transit secrets engine at transit
encryption keypaymentEncryption key to encrypt/decrypt data

»Examine the Terraform files

Clone or download the demo assets from the hashicorp/vault-guides GitHub repository to perform the steps described in this tutorial.

To clone the repository, use the git clone command.

$ git clone https://github.com/hashicorp/vault-guides.git

Alternatively, you can download the repository.

Download

This repository contains supporting content for all of the Vault learn guides. The content specific to this tutorial can be found within a sub-directory.

Change the working directory to /operations/codify-mgmt/oss.

$ cd operations/codify-mgmt/oss

The directory contains Terraform files to configure Vault.

$ tree
.
├── auth.tf
├── main.tf
├── policies
│   ├── admin-policy.hcl
│   └── eaas-client-policy.hcl
├── policies.tf
└── secrets.tf

Open the main.tf file in your preferred text editor to examine its content.

provider "vault" {
  # It is strongly recommended to configure this provider through the
  # environment variables:
  #    - VAULT_ADDR
  #    - VAULT_TOKEN
  #    - VAULT_CACERT
  #    - VAULT_CAPATH
  #    - etc.
}

Within the file is a vault provider block. You can provide the server connection details inside this block (Vault server address, client tokens, etc.); however, it is strongly recommended to configure those target server specific information using environment variables. And that's what you are going to do in this tutorial.

Open the policies.tf file and examine the vault_policy resources.

# Create admin policy in the root namespace
resource "vault_policy" "admin_policy" {
  name   = "admins"
  policy = file("policies/admin-policy.hcl")
}

# Create 'training' policy
resource "vault_policy" "eaas-client" {
  name   = "eaas-client"
  policy = file("policies/eaas-client-policy.hcl")
}

Open the auth.tf file and note that it enables userpass auth method and create a user, "student" with admins and eaas-client policies attached. The password is set to "changeme".

resource "vault_auth_backend" "userpass" {
  type = "userpass"
}

# Create a user, 'student'
resource "vault_generic_endpoint" "student" {
  depends_on           = [vault_auth_backend.userpass]
  path                 = "auth/userpass/users/student"
  ignore_absent_fields = true

  data_json = <<EOT
{
  "policies": ["admins", "eaas-client"],
  "password": "changeme"
}
EOT
}

Open the secrets.tf file which enables kv-v2 secrets engine.

resource "vault_mount" "kv-v2" {
  path = "kv-v2"
  type = "kv-v2"
}

Also, it enables transit secrets engine at transit, and create an encryption key named, "payment".

resource "vault_mount" "transit" {
  path = "transit"
  type = "transit"
}

# Creating an encryption key named 'payment'
resource "vault_transit_secret_backend_key" "key" {
  depends_on = [vault_mount.transit]
  backend    = "transit"
  name       = "payment"
}

»Run Terraform to configure Vault

  1. Set the client token in the VAULT_TOKEN environment variable. If not using the root token, be sure that this token has permissions to create policies, enable secrets engines, and enable auth methods.

    $ export VAULT_TOKEN="<token>"
    
  2. Set the target Vault server address in the VAULT_ADDR environment variable if it's not done so already.

    $ export VAULT_ADDR="http://127.0.0.1:8200"
    
  3. Initialize Terraform to pull Vault provider plugin.

    $ terraform init
    
    Initializing the backend...
    ...snip...
    Terraform has been successfully initialized!
    

    This will download the Vault plugin.

  4. Execute the apply command to configure Vault.

    $ terraform apply
    

    This will displays the actions to be performed by Terraform.

    When prompted, enter yes to accept the plan and proceed with Vault configuration.

    Plan: 7 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
    

    Once completed, the output similar to the following displays.

    Apply complete! Resources: 7 added, 0 changed, 0 destroyed.
    

»Verify the configuration

  1. List existing policies to make sure that admins and eaas-client policies were created.

    $ vault policy list
    
    admins
    default
    eaas-client
    root
    
  2. List enabled secrets engines to verify that kv-v2 and transit secrets engines are enabled.

    $ vault secrets list
    
    Path          Type         Accessor              Description
    ----          ----         --------              -----------
    ...
    kv-v2/        kv           kv_4ae6ced0           n/a
    ...
    transit/      transit      transit_5a1b59df      n/a
    
  3. List transit keys to make sure that payment key exists.

    $ vault list transit/keys
    Keys
    ----
    payment
    
  4. Now, verify that you can log in with userpass auth method using the username, student"" and password, "changeme".

    $ vault login -method=userpass username=student
    Password (will be hidden):
    
    Key                    Value
    ---                    -----
    token                  s.ac401MQbM0GMv6bS7UuZmxzi
    token_accessor         FDnXsZmgCWggMVlsJOjFaCLr
    token_duration         768h
    token_renewable        true
    token_policies         ["default" "eaas-client"]
    identity_policies      []
    policies               ["default" "eaas-client"]
    token_meta_username    student
    

    The generated token has eaas-client policy attached.

  5. Review the eaas-client policy.

    $ cat policies/eaas-client-policy.hcl
    
    # Permits CRUD operation on kv-v2
    path "kv-v2/data/*" {
      capabilities = ["create", "read", "update", "delete", "list"]
    }
    
    # Encrypt data with 'payment' key
    path "transit/encrypt/payment" {
      capabilities = ["update"]
    }
    
    # Decrypt data with 'payment' key
    path "transit/decrypt/payment" {
      capabilities = ["update"]
    }
    
    # Read and list keys under transit secrets engine
    path "transit/*" {
      capabilities = ["read", "list"]
    }
    
  6. Make sure that student can encrypt and decrypt data using the payment key.

    $ vault write transit/encrypt/payment \
         plaintext=$(base64 <<< "1111-2222-3333-4444")
    
    Key            Value
    ---            -----
    ciphertext     vault:v1:RYVesgy2eJe4LeJ7v38WYmBEDN6vjPnPfvZm1UCYTajIIlVWjFujNYlA6YZ06lRz
    key_version    1
    

    Now, decrypt the returned ciphertext.

    $ vault write transit/decrypt/payment \
        ciphertext="vault:v1:RYVesgy2eJe4LeJ7v38WYmBEDN6vjPnPfvZm1UCYTajIIlVWjFujNYlA6YZ06lRz"
    
    Key          Value
    ---          -----
    plaintext    MTExMS0yMjIyLTMzMzMtNDQ0NAo=
    

    The returned value is base64-encoded and must be decoded to reveal the original input value.

    $ base64 --decode <<< "MTExMS0yMjIyLTMzMzMtNDQ0NAo="
    
    1111-2222-3333-4444
    

NOTE: The details about how transit secrets engine works are out of scope for this tutorial. If you are not familiar with transit secrets engine, read the Encryption as a Service: Transit Secrets Engine tutorial.

»Clean up

When you are done exploring, you can undo the configuration made by Terraform.

First, log back in with the client token used to run the terraform commands.

$ vault login $VAULT_TOKEN

Destroy the Vault resources created by Terraform.

$ terraform destroy -auto-approve

...snip...

Destroy complete! Resources: 7 destroyed.

Remove the terraform state files.

$ rm *.tfstate.*

NOTE: To learn more about Terraform, visit Learn Terraform.

»Next steps

Treat your Terraform files like any other code and manage them through a version control system such as GitHub. You may integrate it with your favorite CI/CD tool (Jenkins, Travis CI, Circle CI, etc.), always review and test the configuration.

Integrate with CI/CD

Travis CI example:

You can test your Terraform files against a development server that runs locally, or use a Docker image of Vault.

sudo: false

env:
  - VAULT_ADDR=  VAULT_TOKEN=

before_install:
  - scripts/install.sh

before_script:
  - vault server -dev -dev-root-token-id="$VAULT_TOKEN"

script:
  - terraform init
  - terraform apply -auto-approve

»Help and Reference

  • Terraform Vault Provider documentation page
  • Terraform Provider GitHub repository
  • Learn Terraform

Terraform users can leverage the Vault's dynamic secrets engine to generate short-live cloud credentials when provisioning cloud resources. Inject secrets into Terraform using the Vault provider tutorial demonstrates the use of AWS secrets engine to manage AWS IAM credentials used by Terraform.


Back to Collection
HashiCorp
  • System Status
  • Terms of Use
  • Security
  • Privacy
stdin: is not a tty