The advantages of IaC can be broken down into a few categories:
terraform planterraform plan -refresh=falseterraform plan -target=
This is used in exceptional circumstances
—
terraform_providers block
terraform {
required_providers {
azurerm = {
source = "hashicorp/azurerm"
version = "~>4.22"
}
}
}
required_providers block sets the version for all instances of the provider, including child modules>= 4.22.0 is greater or equal to the version
<= 4.22.0 is less than or equal to the version
~> 4.22.0 any version on the 4.22.x range. Keeps you on the major range
>= 1.22, <= 4.22 is any version between 1.22 and 4.22 inclusive
terraform.lock.hcl. This records the versions of providers and can be checked into the VCS.
This allows a consistent provider version used across the team.
You can upgrade the provider version (within the version constraints defined in the required_providers block) by using the command terraform init -upgrade
required_providers block or implied by creating resources that use multiple providersalias meta-argument. This enables you to reference that provider in the resource declerations
terraform {
provider "aws" {
region = "us-east-1"
}
provider "aws" {
region = us-west-2
alias = "west"
}
resource aws_ec2_instance "ec2-east-1" {
name = "instance2"
}
resource aws_ec2_instance "ec2-west-1" {
name = "instance2"
provider = aws.west
}
}
The required providers block is defined in the terraform block
// SYNTAX
terraform {
required_providers {
<LOCAL NAME> {
<SOURCE> = <hostname/organisation/provider>
#If hostname is omitted then terraform assumes public repo
<VERSION>
}
}
}
// Example
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 4.22"
}
azure = {
source = "hashicorp/azurerm"
version = "~>3.0"
}
}
}
.terraform directory in the same directory as the local configurationplugin_cache_dir cli argumentTF_PLUGIN_CACHE_DIR environmental variable
user_data and Azure custom_dataterraform or terraform <command> -help
terraform fmt command is used to format the configuration files to match the canonical format and style outlined in Terraform language style conventionsterraform fmt command looks for .tf and .tfvars files-recursive command to traverse a directory structure looking for .tf and .tfvars files.
terraform taint it will taint a resource to be recreated at the next applySYNTAX
terraform taint <RESOURCE ID>
EXAMPLE
terraform taint aws_iam_user.name.joe
terraform taint 'module.iam.aws_iam_user.iam["neo"]'
<module_name>.<resource_provider><resource_name><instance>
To remove a resource from being tained you can use the command terraform untaint <path to resource>
SYNTAX
terraform import <state file resource location><Instance> <cloud ID>
EXAMPLE
terraform import 'module.iam.aws_iam_user.iam["boo"]' boo
terraform import aws_iam_user.users boo
terraform workspace are:
```
terraform workspaceterraform mv command has a few options:
dry-run - like a what-if
state - This is the path to the source state file
state-out - This is the path to the destination file.
TF_LOGTF_LOG_PATH with the full path as it’s valueTF_LOG_CORE or TF_LOG_PROVIDER# 5 Interact with terraform modules
module <name_label> {} configurationfor_each,count and depends_on meta-arguments in the root module configuration block
= specific version>= greater or equal to~> any version in the >= 1.0.0, <= 2.0.0 any version in between the two versionsThe terraform defines the core workflow in three parts:
terraform init multiple times without issue. If nothing has changed nothing will happen. You do however need to run terraform init when:
terraform init it created a file called .terraform.lock.hcl. This contains a list of providers used, including the version constraints and hashes of the provider plugin
terraform_remote_state
terraform refresh will analyse the resource provisioned in the real world and compare them to the state file. If there are any differences in the real world it will update the state file to reflect the real worldterraform refresh has been deprected as it will update the state file without allowing you to review the changes. It is recommended to use terraform plan -refresh-only or terraform apply -refresh-only which will give you the chance to review the changes
-backend-config with a key/value pairs-backend-config to a file containing a key/value pairsterraform init the details will be saved in the .terraform/terraform.tfstate file. This directory should be omitted from the VCS using the .gitignore file
6 is the highest priority and 1 being the lowest. 6 will override 1
variable "my_list" {
type = list(string)
}
variable "my_map" {values can be multiple types
type = map(number)
}
Example of Tuple variable “pi_tuple” { type = tuple ( [string, number, boolean, list(number)] ) } [“Pi”, “25.1”, true, [3, 1, 5, 6] ]
## 8D Create and differentiate resource and data configuration
### Looping and multiple Instances
* For_each meta-argument takes either a **set** or **map** of **strings** as a value.
**You may need to convert tuples to sets to ensure the correct data type is submitted to a for_each**
``` javascript
Example: for_each with set
resource "aws_bucket" "my_buckets" {
for_each = to_set(["Red", "Green", "Blue"])
name = "this-is-my-${each.key}-bucket"
}
Example: for_each with map
resource "aws_bucket" "my_bucket" {
for_each = {
Red = "Sand"
Green = "Rocks"
Blue = "Dirt"
}
name = "this-is-my-${each.key}-bucket"
tags = {
contents = each.value
}
}
This will loop through the map and for each element (Red, Green, Blue) it will set the tag using the each.value
resource “azurerm_virtual_network” “vnet” { name = “prod-vnet” resource_group_name = “eastus” address_space = “var.address_space”
dynamic "subnet" {
for_each = var.subnet_data
content {
name = subnet.value["name"]
address_prefix = subnet.value["address_prefix"]
}
} } ``` * the data stored in the subnet_data variable needs to be a **map** or **set** * The keyword dynamic estalishes this is a dynamic block expression * the name label of subnet lets terraform know that this will be a set of nested block each of type subnet. * the content section defines the actual content of each generated nested block * within each content section we need to be able to refer to the information in the subnet_data variable * terraform creates a temporary iterator with the same name as the name label of the dynamic block "subnet" ## 8H describe built-in dependency management * when terraform is analysing a configuration it creates a resource graph that lists out all the resources in your configuration and their dependencies. This allows terraform to create the resources in the proper order. * you can create an explicit dependency using the depends_on statement --- # 9 Understand terraform enterprise capabilities * terraform enterprise is an on-prem version of terraform cloud without resource limits, SAML integration and audit logging ## 9A describe the benefits of sentinel, registry and workspaces ### sentinel * sentinel is a language and framework for policy enabling fine-grained logic based policy decisions * sentinel is an enterprise only feature of hashicorp console, nomad, terraform and vault * the sentinel intergation runs within the terraform cloud after the terraform plan and before the terraform apply * the policies have access to the terraform plan, the state at the time of the plan, and the configuration at the time of the plan * sentinel policies are rules enfoced on terraform runs to validate the plan and corresponding resources follow the defined policies ### Registry * terraform cloud offers a private registry to share modules and proivders * companies can go one tep further and host theor own terraform enterprise with their own registry ### Terraform Cloud Workspaces * the terraform cloud workspace contains:
- terraform configuration (usually pulled from VCS)
- variables, values, secrets and credentials
- logs from the last plans and applies ## 9C summerise features of terraform cloud * workspaces * VCS intergation * Private module registry * remote operations - terraform cloud uses managed, disposable VMs to run terraform OSS commands remotely and provide advanced features like sentinel policy enforcement and cost estimations * Organisations: access control is managed through users, groups and organisations * sentinel: used for policy definition and enforcement * cost estimation: estimate the cost of resources being provisioned * API: a subset of terraform clouds features are available through their API * serviceNow: integration with serviceNow is available for terraform enterprise customers --- ## Terraform files ### Terraform System Files * terraform.tfstate - Terraform state file (don't check into VCS) * terraform.hcl.lock - provider versions and hashes (check into VCS) * .terraform/terraform.tfstate - defines the remote back-end ### User created terraform files * README - description of the module and what it should be used for * *.tfvars - Key/Value pair of input variables (check into VCS) * auto.tfvars - Key/Value pair of input variables (check into VCS) * main.tf - Main terraform module (check into VCS) * variables.tf - Module Input Variables file(Input Parameters(check into VCS)) * providers.tf - providers configuration block (check into VCS) * version.tf - defines the terraform block with `required_providers` and the `providers` configuration blocks * output.tf - module output configuration block (check into VCS)