Hashicorp-Terraform-Associate-Master-Cheat-Sheet3
Hashicorp-Terraform-Associate-Master-Cheat-Sheet3
Objectives
1. Understand Infrastructure as Code (IaC) concepts
pg. 1
SKILLCERTPRO
NOTE: Most of this information comes directly from the Hashicorp website I've
compiled the resources here for accessibility and easy review. 🙂
Infrastructure is described using a high-level configuration syntax. This allows a blueprint of our
data center to be versioned and treated as we would any other code. Additionally, infrastructure
can be shared and re-used.
IaC makes it easy to provision and apply infrastructure configurations, saving time. It standardizes
workflows across different infrastructure providers (e.g., VMware, AWS, Azure, GCP, etc.) by using
a common syntax across all of them.
It is infrastructure (CPUs, memory, disk, firewalls, etc.) defined as code within definition files.
Multi-cloud deployment increases fault tolerance. This means in the event of failure there is a
more graceful recovery of a region or provider.
pg. 2
SKILLCERTPRO
The benefits of being provider-agnostic means there can be a single configuration that manages
many providers.
Workflows
o Scope: Establish resources that need to be created for the project
o Author: Create the configuration based on the scoped parameters with HCL
o Initialize: run terraform init to download the provider plug-ins for the project
o Plan & Apply: run terraform plan to verify creation then terraform apply to
create the resources and state files
Advantages of Terraform
o Platform Agnostic: allows for management of a mixed environment with the same
workflow
o State Management: State files are created when a project is initialized. state is
used to create plans and update our infrastructure. State determines how
configuration changes are measured. When a change is made, those changes are
compared with the state file to determine resource creation or changes
o Operator Confidence: terraform apply allows for review before changes are
applied.
pg. 3
SKILLCERTPRO
Providers
The primary construct of the Terraform language are resources, the behaviors of
resources rely on the resource types, resource types are defined by providers.
Providers have a set of resource types that defines which arguments are accepted, what
attributes it exports, and how changes are applied to APIs.
Configuration
Initialization
Versions
pg. 4
SKILLCERTPRO
o When terraform init is re-run with providers already installed, it will use an
already-installed provider that meets the constraints in preference to
downloading a new version
o to upgrade all modules run terraform init -upgrade
o we can have multiple configs for the same provider by using the alias meta-
argument to allow for multiple regions per provider, targeting multiple Docker
hosts, etc.
o # The default provider configuration
o provider "aws" {
o region = "us-east-1"
o }
o
o # Additional provider configuration for west coast region
o provider "aws" {
o alias = "west"
o region = "us-west-2"
}
Plugin Cache
Terraform Settings
pg. 5
SKILLCERTPRO
Explain when to use and not use provisioners and when to use local-exec or remote-exec
Provisioners - provisioners are used to model specific actions on the local machine or on
a remote machine to prepare infrastructure objects
Provisioners are there if needed but they add complexity and uncertainty (should only be
used as a last result)
Provisioners should be used if no other option will work.
Use cases:
o Passing data into virtual machines and other compute resources
o running config management software
local-exec - invokes a local executable after the resource is created. Invokes a process on
the machine not on the resource.
pg. 6
SKILLCERTPRO
This command is used for rewriting Terraform configuration files to a canonical format
and style.
It applies the Terraform language style conventions along with other changes for
readability.
This insures consistency
There might be changes with Terraform versions so it is recommended to run this
command on modules after an upgrade.
Given a scenario: choose when to use terraform taint to taint Terraform resources
terraform taint
Marks a resource as tainted, forcing it to be destroyed and recreated on the next apply.
It does not modify infrastructure but does modify the state file
After a resource is marked the next plan shows it will be destroyed and recreated on the
next apply
Useful when we want a side effect of a recreation that is not visible in the attributes of the
resource. For ex/rebooting the machine from a base image causing a new startup script
to run.
This command can affect resources that depend on the tainted resource. Ex/ DNS
resource that uses IP of a server, that resource might need to be updated with the new IP
of a tainted server.
Examples:
#Tainting a Single Resource
terraform taint aws_security_group.allow_all
#Tainting a single resource created with for_each
terraform taint
'module.route_tables.azurerm_route_table.rt[\"DefaultSubnet\"]'
#Tainting a Resource within a Module
terraform taint "module.couchbase.aws_instance.cb_node[9]"
Given a scenario: choose when to use terraform import to import existing infrastructure into our
Terraform state
terraform import
pg. 7
SKILLCERTPRO
Terraform configuration has a backend that defines operations and where persistent data
is stored (state)
Persistent data in the backend belongs to a workspace.
Creating different workspaces is useful to manage different stages of deployment
(sandbox or production)
At first the backend only has one workspace 'default'. This workspace cannot be deleted.
Certain backends can support multiple named workspaces. This allows multiple states to
be associated with a single configuration.
Config still only has one backend with more than one instance of that config
Backends that support multiple workspaces:
o AzureRM
o Consul
o COS
o GCS
o Local
o Manta
o Postgres
o Remote
o S3
Examples:
#Creating a workspace
terraform workspace new bar
#Created and switched to workspace "bar"!
#We're now on a new, empty workspace. Workspaces isolate their state,
#so if we run "terraform plan" Terraform will not see any existing state
pg. 8
SKILLCERTPRO
Given a scenario: choose when to use terraform state to view Terraform state
terraform state
Given a scenario: choose when to enable verbose logging and what the outcome/value is
TF_LOG
#LOG LEVELS
TRACE
DEBUG
INFO
WARN
ERROR
TF_LOG_PATH #Persist logged output
Module Overview
Applications
pg. 9
SKILLCERTPRO
o Re-use configuration - share and re-use modules with the public and teams
o Provide consistency and ensure best practices
module "vpc" {
#<HOSTNAME>/<NAMESPACE>/<NAME>/ <PROVIDER>
source = "app.terraform.io/example_corp/vpc/aws"
version = "0.9.3"
}
pg. 10
SKILLCERTPRO
variable "availability_zone_names" {
type = list(string)
default = ["us-west-1a"]
#default means the variable is considered optional, used if no other value
is set when calling the module or running Terraform
description = "variable description, purpose and value expected"
}
variable "docker_ports" {
type = list(object({
internal = number
external = number
protocol = string
}))
default = [
{
internal = 8300
external = 8300
protocol = "tcp"
}
]
}
#---------------------
#To use validation we need to opt in
terraform {
experiments = [variable_validation]
}
Set root module variables 1) In Terraform Cloud Workspace 2) Individual CLI with -
var 3) In .tfvars file 4) As environment variable
child modules have variables set in the configuration of the parent module
pg. 11
SKILLCERTPRO
servers = 3
}
Write
o Author infrastructure as code
Plan
o Preview changes before applying
Create (Apply)
o Provision reproducible infrastructure
Configuration is written like any program, use version control to keep track of changes
# Create repository
$ git init my-infra && cd my-infra
Initialized empty Git repository in /.../my-infra/.git/
# Write initial config
$ vim main.tf
# Initialize Terraform
$ terraform init
Initializing provider plugins...
# ...
Terraform has been successfully initialized!
running Terraform plan repeatedly is useful to make sure there are no syntax errors and
the correct code is being written per the desired outcome.
First run Terraform apply before pushing to git to make sure the provisions are correct
While working in teams it is best to use branches to avoid code collision.
$ git checkout -b <branch-name>
Switched to a new branch <branch-name>
Teams can review changes via Terraform plans and pull requests
Terraform cloud helps streamline this process in a team setting
o Write - secure location for storing variables and state with the "remote" backend,
then a Terraform Cloud API key is used to edit the configuration and run plans
against the state file.
terraform {
backend "remote" {
organization = "my-org"
workspaces {
prefix = "my-app-"
}
}
}
#--------------------------------------
$ terraform workspace select my-app-dev
Switched to workspace "my-app-dev".
$ terraform plan
Running plan remotely in Terraform Enterprise.
Output will stream here. To view this plan in a browser, visit:
https://app.terraform.io/my-org/my-app-dev/.../
pg. 12
SKILLCERTPRO
o Plan - plans are automatically run when a pull request is created. Status updates are
shown in the pull request view.
o Apply - A confirm and apply is needed after merging to run an apply.
validates the configuration files in the dir, this does not apply to things like remote state or
provider APIs
validate checks for syntax, internal consistency, such as attribute names and value types
safe to run automatically or as a test step for CI
requires initialized working directory
pg. 13
SKILLCERTPRO
if supported by your backend state can be locked so others cannot change it while
another change is being made.
this is automatic for all operations that can write state
Backends types supporting
locking:(standard)artifactory,azurerm,consul,cos,etcd,etcdv3,gcs,http,manta,oss,pg,s3,swift
,terraform enterprise, and in enhanced backends there are remote operations as well
(plan, apply, etc.)
A lock can be forced open with force-unlock which requires a unique nonce lock ID
pg. 14
SKILLCERTPRO
terraform {
backend "azurerm" {
storage_account_name = "abcd1234"
container_name = "tfstate"
key = "prod.terraform.tfstate"
use_msi = true
subscription_id = "00000000-0000-0000-0000-000000000000"
tenant_id = "00000000-0000-0000-0000-000000000000"
}
}
Standard backends
artifactory,azurerm,consul,cos,etcd,etcdv3,gcs,http,manta,oss,pg,s3,swift,terraform
enterprise
terraform refresh
reconciles the state Terraform knows about via the state file.
refresh does not modify the infrastructure, it does modify the state file.
Describe backend block in configuration and best practices for partial configurations
Backend Config
terraform {
backend "consul" {
address = "demo.consul.io"
scheme = "https"
path = "example_app/terraform_state"
}
}
Partial Configuration
pg. 15
SKILLCERTPRO
state contains resource IDs and attributes, db data that may have passwords.
with remote state, state is only in memory when in use. This is more secure
also some backends can encrypt the state data at rest
Terraform Cloud encrypts state at rest and protects it with TLS in transit.
Terraform Cloud keeps track of user identity, and state changes.
Best Practices
o avoid putting secret or sensitive variables in config or state files.
o Webinar walk-through on Best Practices
o set secret variables for provider config block in environment variables.
provider "vault" {
auth_login {
path = "auth/userpass/login/${var.login_username}"
parameters = {
password = var.login_password
}
}
}
#auth_login Usage with approle
variable login_approle_role_id {}
variable login_approle_secret_id {}
provider "vault" {
auth_login {
path = "auth/approle/login"
parameters = {
role_id = var.login_approle_role_id
pg. 16
SKILLCERTPRO
secret_id = var.login_approle_secret_id
}
}
}
#For multiple namespace in vault use alias
provider "vault" {
alias = "ns1"
namespace = "ns1"
}
provider "vault" {
alias = "ns2"
namespace = "ns2"
}
complex types group values into a single value. 2 types: Collection type(grouping similar
values) and Structure types (grouping dissimilar values)
pg. 17
SKILLCERTPRO
Each
resource is
when you
associated
each create a new
with a single
blocks declare a resource resource it
resource
resource of a given has a single only exists in
type, which
type aws_instance with resource the
determines
a local name web. The type, each configuration
the kind of
Resources local name is used to type until
infrastructure
reference the resource belongs to a you apply it.
object it
in the module. In the provider, When its
manages and
braces {} config body of created it is
what
arguments are defined resource are saved in
arguments
for the resource type. specific to state, and can
and other
type be updated or
attributes the
destroyed
resource
supports
Each data
resource is
If the query
associated
constraint
with a
arguments
single data
for a data
source, this As data
resource
determines sources are
refer only to
the kind of essentially a
constant
object(s) it read only
values or
reads and subset of
values that
A data source is the resources,
are already
accessed via a special available they also
known, the
Data kind of resource known arguments. support the
data resource
Sources as a data resource, Most of the same meta-
will be read
declared using a data items arguments of
and its state
block within the resources
updated
body of a with the
during
data block exception of
Terraform's
are defined the lifecycle
"refresh"
by and configuration
phase, which
specific to block.
runs prior to
the selected
creating a
data source,
plan. more
and these
on behavior
arguments
can make
pg. 18
SKILLCERTPRO
full use of
expressions
and other
dynamic
Terraform
language
features.
Use resource addressing and resource parameters to connect resources together
Connecting resources
In top level block constructs(like resources) expressions can be used only when assigning
a value to an argument with name=expression
Some resource types have repeatable nested blocks in their arguments that don't accept
expressions.
Example:
resource "aws_elastic_beanstalk_environment" "tfenvtest" {
name = "tf-test-name" # can use expressions here
setting {
# but the "setting" block is always a literal block
}
}
You can create repeatable nested blocks with the block type dynamic. This is supported
with resource,data,provider, and provisioner blocks
Example:
resource "aws_elastic_beanstalk_environment" "tfenvtest" {
name = "tf-test-name"
application = "${aws_elastic_beanstalk_application.tftest.name}"
solution_stack_name = "64bit Amazon Linux 2018.03 v2.11.4 running Go
1.12.6"
dynamic "setting" {
for_each = var.settings
content {
namespace = setting.value["namespace"]
name = setting.value["name"]
pg. 19
SKILLCERTPRO
value = setting.value["value"]
}
}
}
Dynamic blocks can only produce arguments that belong to the resource type, data
source, provider or provisioner being configured.
Overuse of dynamic blocks can get hard to read, it's recommended to use them only to
hide details in order to build a clean user interface for re-usability.
Sentinel
Module Registry
pg. 20
SKILLCERTPRO
o Support includes module versioning, search and filtering list of modules, and a
configuration designer to build workspaces
o Similar to the Public Registry
o Module Registry Announcement
Workspaces
CLI Workspaces
o relates to persistent data stored in the backend, a feature for using one
configuration to manage many similar grouped resources.
o uses with a Terraform's command line interface: terraform workspace new bar
Enterprise/Cloud Workspaces
Terraform Cloud
o Terraform Cloud Pricing/Features
o Terraform Cloud Docs
o Main Features
Workflow
CLI, Remote Execution(Operations), Support for Local Execution,
Organize infra with workspaces, Remote state management, data
sharing, and run triggers, version control integration, private
module registry
Integrations
Full API, Notifications
Access Control and Governance
team based permission systems, sentinel policies, cost estimation
pg. 21