Terraform - eekbot/public GitHub Wiki

Building a VM And Running Scripts on It


Initializing Inside Terraform Docker Container

This should build a container, mount the current directory inside the container, change to that directory in the container, and then run the init command.

docker container run -it --rm --name terraform -v $PWD:$PWD -w $PWD hashicorp/terraform:1.4 init

If there's a lock file (.hcl.lock), then you'll be blocked from doing another init, or it'll use what's in the existing lock file. To overwrite what's in the lock file, you can use -upgrade, or you can just delete the lock file and make it create another one.

For apply or destroy commands, throw in "-auto-approve" so I don't have to enter 'yes' after the command.

Provider Versioning

You should include a block of code that looks something like this for every provider that you use. Technically, you don't need this for official providers, but it's a good practice to have it. You DO need it for 3rd party providers though:

terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~>4.62.0"
 # Versioning Syntax Guide:
  = 1.0 means equal to version 1.0
  < 1.0 means the newest code less than 1.0
 <= 1.0 means the newest code less than or equal to 1.0
  > 1.0 means the newest code greater than 1.0
 >= 1.0 means the newest code greater than or equal to 1.0
 ~> 1.0 means the newest code where the numbers in front of the final dot must remain the same. (e.g. 1.0, 1.1, 1.2.2, etc, but not 2.0)

Building AWS EC2 Instance

 resource "aws_instance" "this" {
   ami                     = "ami-0dcc1e21636832c5d"
   instance_type           = "m5.large"
   host_resource_group_arn = "arn:aws:resource-groups:us-west-2:012345678901:group/win-testhost"
   tenancy                 = "host"

Destroying a Resource

  • Option 1: The Destroy Command
  • Option 2: Delete the config for the resource and apply
terraform destroy -target aws_instance.blahec2

Output Values

The following examples will reference this resource:

resource "aws_instance" "ec2demo" {
    ami             = "ami-0747e613a2a1ff483"
    instance_type   = "t2.micro"

If I'm not sure what attributes I can look up, this will output everything:

output "BLAH_ALL" {
    value = aws_instance.ec2demo

If I only want to recall the instance type to the above AWS instance:

    value = aws_instance.ec2demo.instance_type

If I need to recall an attribute value and attach other text to it, then I need to put it inside "${BLAH}". See the cidr_blocks value below where I needed to attach "/32" to the end of the output value:

resource "aws_security_group" "allow_icmp" {
  name        = "icmp"
  description = "Allow ICMP inbound traffic"

  ingress {
    description      = "ICMP from VPC"
    from_port        = 8
    to_port          = 0
    protocol         = "icmp"
    cidr_blocks      = ["${aws_instance.ec2demo.public_ip}/32"]


  1. Set default variables in the variables.tf file.
  2. Set specific variable values in the terraform.tfvars file. If you use a file name other than terraform.tfvars, then you have to specify it in the CLI with the option -var-file="custom.tfvars".
  3. Set cli values with -var="BLAHVAR=BLAHVALUE"
  4. Set the value in your environment variables.
  • In Windows, use:
# To set the value:
setx TF_VAR_instancetype t2.micro

# To confirm the value:
echo %TF_VAR_instancetype%

# In Windows, you may need to open a new command prompt for the value to be reflected.</pre>

* In Linux, use:
<pre># To set the value:
export TF_VAR_instancetype="t2.micro"

# To confirm the value:
echo $TF_VAR_instancetype</pre>

* In Docker:

<pre># To set the value in CLI:

docker container run -it --rm -e BLAHNAME=BLAHVALUE -v $PWD:$PWD -w $PWD hashicorp/terraform:1.4 init</pre>

Preference Order

From least preferred to most preferred:

  1. Environment variables
  2. terraform.tfvars file, if present
  3. any -var CLI flags and variables.tf values, in the order they are provided


Although not required, it's best practice to specify the type because anyone reading the variables.tf file won't know what's expected without it.

  1. String - Example: "hello123"
  2. List - Example: ["blah", "durrr", "uhhh"]
  3. Map - Example: {name: "Evo", age: 5}
  4. Number - Example: 15

Count and Count Index

# Example where you can use count:
 resource "aws_instance" "ec2demo" {
   ami             = "ami-0747e613a2a1ff483"
   instance_type   = var.instance_type
   tags            = {
     Name = "TerraformDemo.${count.index}"
   count = 5

# Consider using the count index on a list variable
 variable "blahName" {
   type    = list
   default = ["blah1", "bleh", "blue"]
# Then put this in your terrform file:

Conditional Expressions

# Format of the conditional expression:
 condition ? true_val : false_val

If the condition is true, then the result is true_val. Else, it's the false_val.

# In this example, b/c "istest" == false, the count will be 0 and the aws_instance will not be created 

variable "istest" {
   default = false
resource "aws_instance" "dev" {
   ami = "1234"
   instance_type = "t2.micro"
   count = var.istest == true ? 1 : 0

Authenticating Azure

The recommended method to authenticate Azure involves Azure CLI. In order to install Azure CLI on a Mac, you also need to install Homebrew.

# Here's the link to homebrew:

# This is the command they tell you to run on homebrew (as of 2024.02.11)
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"

# After homebrew is installed, you're supposed to run a couple of commands that are listed in the install output. 
# I ran into a permissions error and had to allow Terminal full disk access first.
# Use spotlight to look at the Privacy & Security settings > Full Disk Access > Click + > 
# Navigate to the /Applications/Utilities/ folder and choose “Terminal” to grant Terminal with Full Disk Access privileges

# Once that's done, then you run the install command for Azure CLI:
brew update && brew install azure-cli
# Now to authenticate to Azure, use the **azure cli** command that that will open up a browser window to log into Azure.
# They made me authenticate with MFA after I entered my username and once that was done, I got this message:

You have logged into Microsoft Azure!

You can close this window, or we will redirect you to the [Azure CLI documentation](https://docs.microsoft.com/cli/azure/) in 1 minute.

[Windows only] Azure CLI is collecting feedback on using the [Web Account Manager](https://learn.microsoft.com/windows/uwp/security/web-account-manager) (WAM) broker for the login experience.

You may opt-in to use WAM by running the following commands:
az config set core.allow_broker=true
az account clear
az login
# Back at the CLI, now we need to set the account:
BLAH@BLAH-BLAH Terraform %
⚠️ **GitHub.com Fallback** ⚠️