Permalink
Switch branches/tags
Nothing to show
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
96 lines (81 sloc) 5.57 KB
type layout title excerpt published last_modified_at header classes toc categories tags meta
post
single
Terraform Global Variables
A simple way to implement global variables in Terraform. {::nomarkdown}<br><br>Example available in the <strong>VMUG-Labs</strong> project.<br><br><iframe style="display: inline-block;" src="https://ghbtns.com/github-btn.html?user=vmug-labs&repo=vmug-labs&type=star&count=true&size=large" frameborder="0" scrolling="0" width="160px" height="30px"></iframe> <iframe style="display: inline-block;" src="https://ghbtns.com/github-btn.html?user=vmug-labs&repo=vmug-labs&type=fork&count=true&size=large" frameborder="0" scrolling="0" width="158px" height="30px"></iframe>{:/nomarkdown}
true
2018-05-19
overlay_image overlay_filter teaser caption cta_label cta_url
/assets/images/pixabay-sunrise-1756274.jpg
0.5
/assets/images/pixabay-sunrise-1756274_640.jpg
GitHub Repository
wide
false
Automation
Cloud Computing
Virtualization
HashiCorp
Open source
Terraform
VMUG
_wpcom_is_markdown _publicize_done_external _rest_api_published _rest_api_client_id _publicize_job_id timeline_notification _publicize_done_18611616 _wpas_done_18402702 publicize_twitter_user publicize_google_plus_url _publicize_done_18611618 _wpas_done_18402704 publicize_linkedin_url _publicize_done_18611619 _wpas_done_18402705 _publicize_done_19035169 _wpas_done_18883722
1
1
-1
16726215685
1523543801
1
1
troylindsay42
1
1
1
1
1
1

Anyone who has developed a highly modular Terraform project has wished at some point that there was a simple way to implement global variables.  This feature will probably not be developed though, because as Paul Hinze of HashiCorp stated:

In general we're against the particular solution of Global Variables, since it makes the input -> resources -> output flow of Modules less explicit, and explicitness is a core design goal.

I am an advocate of the DRY software development principle, and two of the key goals for my open source VMUG Labs project are simplicity & ease of use for the end user, so I started brainstorming for a better way to implement this- a solution where you do not have to remember to specify a shared tfvars file, use a a script that specifies the shared tfvars file or run-line variables for you, group resources that you want segregated, or reference the value from the state file of one of the other modules or use a default value for the variable when those doesn't make sense.

Eventually, it dawned on me- create a global variable module with static outputs and reference the module in your Terraform resource configuration files.  The optimal implementation of this would be to store the module in a private source control repository because remote modules can reference specific versions, though this can also implemented via a local module, which was the best fit for my VMUG Labs project since it is open source (public) and I wanted to minimize the number of components necessary for end users.

At first, I thought that I was the first to think of this solution (and document it publicly), but then I found that @keirhbadger beat me to it by almost a year.  Oh well.

Here are a couple of example output values from the outputs.tf.example file in the local global_variables module in the VMUG Labs project.  You would make your own copy of this file named outputs.tf and set the values appropriately. The new outputs.tf will be ignored by your git client per the entry in the .gitignore file to prevent the sensitive data in this file from being accidentally committed into source control.

{% highlight ruby %} output "aws_profile" { value = "aws_profile" }

output "aws_region" { value = "us-west-2" } {% endhighlight %}

I can then use the static output values in the global_variables module to set input parameters in segregated resources with separate state files.  For example, the domain_controller and jumphost Terraform config files:

{% highlight ruby %} module "global_variables" { source = "../../../modules/global_variables" }

provider "aws" { version = "~> 1.13" profile = "${module.global_variables.aws_profile}" region = "${module.global_variables.aws_region}" } {% endhighlight %}

Voila! That's it!

This solution can be a more intuitive approach for end users that may be less experienced with Terraform.

Enjoy!