Creating a Git Repo with Terraform In Mind

terraform-logo

Creating a Git repository is an easy enough task:

mkdir my-new-repo
cd my-new-repo
git init

If this is just a local repository, you might be safe to just start using it. However, if there is any chance that this repository is going to be stored in a platform, whether it is public or private, it is likely that storing sensitive information is less than desirable.

Using .gitignore

The .gitignore file defines local files to not be incorporated into the repository versioning, pushing, pulling, or cloning operations. The purpose of the file allows the the creator to exclude files that are unnecessary to the repository (like the .vscode directory) and those that contain sensitive information.

In UNIX-type operating systems, preceding a file or directory with a dot is how files become “hidden”; this is why the file begins with a dot.

Which Files Should Be Excluded for Terraform

The “consulting” answer is: it depends. Any files that could contain sensitive or irrelevant information should be excluded. If you make some of your own files that contain such information, please exclude them.

With respect to Terraform, there are some specific files that should be excluded:

  • State files: *.tfstate, *.tfstate.backup, and *.tfstate.lock.info
  • The Terraform directory: .terraform/
  • TFVARS files: *.tfvars

State Files

State files are an interesting point. During the execution of terraform refresh (which happens automatically with other operations), the .tfstate file is created and/or updated against the deployed locations to validate that Terraform understands the current state of the environment.

The state file is a representation of the environment in JSON that includes subscription IDs, resource names, and even output secrets, like keys, and more. As such, state files should not be included in a repository.

Terraform Directory

The .terraform/ directory is built with the terraform init execution and is the location for files that Terraform downloads to complete a deployment, including necessary providers. These could be different for anyone based on their platform. Further, the downloads get the latest or specified versions of files. This means that the files are superfluous in addition to potentially being wrong for the platform.

For instance, if you are building your files on a local Windows machine but you have a pipeline that initiates after you commit to your repository, the build agent for your pipeline could be running on another platform. Further, if you work on a team, other members of your team could be using different platforms, like Linux or macOS, and their hardware might be ARM while your hardware is x86_64.

TFVARS Files

When building out a Terraform configuration, input variables are a handy way to ensure your configuration is portable and does not contain secrets. For instance, authentication information is a good reason to have input variables:

variable “subscription_id” {}
variable “client_id” {}
variable “client_secret” {}
variable “tenant_id” {}

These could be in a single configuration or broken out into a variables configuration file. It could be tempting to assign the values of these variables, and it is fine to do when you are getting things up and running. However NEVER do this while you are working in a repository. There is a chance that you could forget to clear these out.

Instead, define the values in a TFVARS file. Multiple files can exist, which is great because you might different files for dev, test, and prod, for instance. Since secrets can be exposed here, these need to be excluded. In addition, environment specific values could be present which are not appropriate in a repository.

A Note About Defaults

The file extensions and directories mentioned have been the defaults that are used by Terraform if you do not explicitly use other names. If you are in the habit of using other names, be cautious and include any of those files in your .gitignore file, as well.

Conclusion

Leaking secrets can be devastating to your deployments. Exclude all sensitive information from your repositories. Even a repository that is intended to be local could be a challenge if this changes and previous commits contained sensitive information.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s