4 Ways to Manage Your OpenStack Secrets with Terraform and git

Gepostet am: 29. November 2018

Uploading secrets (i.e. passwords and usernames) to version control is an obviously terrible idea. Yet, there are almost 450,000 commits to github for the search term „remove password“. Fortunately, Terraform and its OpenStack provider offer us some pretty nifty ways of keeping our secrets to ourselves and still using comfortable authentication and configuration. There are four main ways of authenticating to OpenStack through terraform that I will touch on in this article.

  • Command line
  • Environment variables
  • .tfvars file
  • clouds-public.yaml, clouds.yaml and secure.yaml

Command line

It is possible to pass your secrets into Terraform as command line arguments. To do this, define your provider like this:

When apply ing your Terraform code, you can then insert your secrets like so:

This is more secure than storing your secrets in repositories but not ideal as you have to type in the variable values at every terraform apply . It does however have the advantage of you never having to store your secrets on any hard drive.

Environment variables

Per default the OpenStack provider looks for environment variables in the shell where terraform apply is run. These environment variables usually start with „OS_“ and end in the name of the variable. There is an easy way of getting these variables from your OpenStack project:

  1. Go to your OpenStack Dashboard
  2. Navigate to ‚Project > API Access‘
  3. Click the button ‚Download OpenStack RC file‘
  4. source your freshly downloaded OpenRC file and type in your password when asked

This has the advantage of having most authentication options set correctly automatically. It does however still have the disadvantage of having to type your password on every source .

terraform.tfvars

If you don’t want to have to reload your OpenRC file with every new shell you open and you also don’t want to type your password time and again, you have to store your secrets somewhere on your hard drive.

The easiest way of doing this is creating a ‚terraform.tfvars‘ file in the root folder of your Terraform project. When running terraform apply , Terraform will automatically scour the root folder for a terraform.tfvars file and load all variables defined in this file. In order to use the terraform.tfvars file, first define your provider in the same way as the command line example. Then, create a file called terraform.tfvars and fill it with variable definitions like this:

Terraform will automatically substitute the variables at apply time.

Finally, don’t forget to add ‚terraform.tfvars‘ to your .gitignore so you don’t accidentally commit your secrets to version control.

Note that your file can also have a different name from ‚terraform.tfvars‘. If the file has another name (e.g. example.tfvars‘), you can run Terraform by calling

Now you have a possibility to store your OpenStack secrets locally without running the danger of sharing the code. But what if there are some OpenStack configuration options that you actually want to upload to version control? The options so far do not provide a way for splitting secrets. Therefore we sometimes need a more flexible approach.

clouds-public.yaml, clouds.yaml and secure.yaml

Fortunately the terraform-openstack-provider and OpenStack come with a built in support for splitting up your configuration. There are three special .yaml configuration files that Terraform searches for when authenticating. Each one of these files will be explained in detail in the next paragraphs. In order to use the files, put them in one of the following three locations:

  • current directory
  • ~/.config/openstack
  • /etc/openstack

The file that is found first wins. What this means is that if you have a clouds.yaml file in the current directory and one in /etc/openstack, terraform will use the one in the current directory.

As this feature has only been added somewhat recently, please note that you have to update your OpenStack provider to at least v1.11.0  for clouds-public.yaml and secure.yaml to be found. However clouds.yaml can also be used with earlier versions.

The way these files work is by defining clouds that each have their own authentication options. To use a cloud defined in the files, define your OpenStack provider like this:

clouds-public.yaml

This file should contain all information that is common across a number of users. Because clouds-public.yaml is meant to be, well, public, you should not put any secrets into this file. As a result, it should be safe to check it into version control.

You can put any information in here that you would normally define via environment variables. While the environment variables have an „OS_“ prefix and are usually uppercase only, the variables in the cloud definitions are usually all lowercase and missing the prefix.
The file has a format akin to this:

Please note that the profile value in a clouds-public.yaml will not be used. If you want to set this value, you have to use a clouds.yaml or secure.yaml.

clouds.yaml

Unlike clouds-public.yaml, this file is not explicitly supposed to be shared publicly. The values defined in this file override all values in clouds-public.yaml.

It is possible to define a clouds.yaml with only a cloud that references a profile with all values in it.

A typical clouds.yaml file could look like this:

 

If you have the above file and the clouds-public.yaml from the last section together, the resulting configuration when calling terraform apply  will be:

 

secure.yaml

This is where your sensitive information such as passwords and usernames should be stored. Because of its sensitive nature, this file will ideally never be uploaded to version control. Values in this file will override all values in clouds.yaml as well as clouds-public.yaml. Furthermore it is possible to define a complete cloud in this file without defining it in clouds.yaml or clouds-public.yaml.

Note that it is not possible to only define a cloud name in clouds.yaml and then fill in the rest in secure.yaml.

A typical secure.yaml would look like this:

 

This would then get merged with both other files into this final configuration:

After adding your secrets in the yaml files, please do not forget to add secure.yaml to your .gitignore.

To be even safer than that, it is advisable to not even store your secure.yaml in the same folder as your terraform code. Instead, store it in one of the other locations mentioned above. A good example file structure would look like this:

 

In conclusion, there are multiple ways of cleverly managing your secrets with Terraform and OpenStack and I hope that I made your Terraform configuration a little bit easier.

Read on

To get to know more about our cloud services please refer to our portfolio. You might also want to have a look at our current job listings if you’re looking to put your skills to good use.

2018-11-29T09:49:00+00:00