DEVOPS
BOOTCAMP Infrastructure as
Code with Terraform
Introduction to Terraform - 1
An open-source infrastructure as code (IaC) tool by HashiCorp
Let's you automate and manage:
your infrastructure your platform services that run on that platform
By defining the resources in human-readable configuration files that you
can:
version reuse share
Definition of configuration Declarative = define WHAT end result or desired state you want
files is declarative!
Imperative = define exact steps - HOW
Introduction to Terraform - 2
Infrastructure Provisioning Manage existing infratructure Replicating Infrastructure
Prepare Infrastructure: Automate the Easily replicate infrastructure
1. Private Network space continuous changes to on different environments,
2. EC2 server instances your infrastructure like DEV, STAGING, PROD
3. Install Docker and other tools
4. Configure Security
5. ...
DEV PROD
Difference of Ansible and Terraform
Both:
Infrastructure as Code
Mainly infrastructure
Mainly a configuration
provisioning tool
management tool
More advanced in orchestration
Better for: Provisioning the Better for: Configuring the
infrastructure provisioned infrastructure
How Terraform works - 1
An important part of Terraform (TF) is that TF knows:
your desired state (config file) and
keeps track of your existing real infrastructure (in a state file)
TF compares your desired with actual Without state, you would always have to
state to know which changes it needs to check the current state yourself and see
make to your infrastructure how to update your desired state!
How Terraform works - 2
This is the core workflow
1) Write 2) Plan 2) Apply
Define your Based on the config file and TF executes the
infrastructure resources state file, changes to your
in the configuration file TF creates an execution plan infrastructure
E.g. creating 2 EC2 - the changes it will make to And updates the state
instances on AWS your infrastructure file, so it is up-to-date
main.tf
Terraform Architecture
TF executes the plan with Providers real infrastructure
main.tf
CORE
terraform.tfstate
Providers
IaaS: AWS | Azure Providers enable TF
2 input sources
PaaS: Kubernetes to work with any
SaaS: Fastly platform or service
Core Terraform Commands
Example configuration file -
the desired state refresh query infrastructure provider to get current state
plan create an execution plan and review it
apply actually execute the plan
destroy destroy the resources/infrastructure
Terraform Providers
Plugins Terraform uses to manage
the resources
Providers expose resources for
specific infrastructure platform
(e.g. AWS)
Responsible for understanding
API of that platform
Just code that knows how to talk to
specific technology or platform
Resources and Data Sources
Resources
Data Source
To create a new resource
Data Sources
To query an existing resource
Resource
Variables in Terraform - 1
Define
Variables (Input variables) let you customize
behavior without editing the terraform configuration
file
2 steps to use variables in Terraform Use that
variable
1) Define variable and use it in your TF script:
2) Set the variable values when applying the script
Variables in Terraform - 2
3 ways to set values for the defined variables
1) Interactively when applying the TF script
2) Better: Set as CLI option
3) Even better: Set in variable file
Variables in Terraform - 3
Real use case with variables:
Same script parameterized
with variables
And own vars file for each
environment
Environment Variables in Terraform
Predefined Env Vars export TF_LOG=off
TF-Env Vars: TF has env vars, which you can use to change
some of TF's default behavior, for example enabling detailed
logs
AWS Env Vars: Set AWS credentials for AWS provider as
environment variable
Define your own custom Env Vars
This is technically the 4th way of setting a variable value, because we define a variable and
set its value through TF environment variable
Git Repository for Terraform Project
Like your application code, Terraform scripts being Why use Version Control?
Infrastructure as code, should be managed by safekeeping
version control system Git and be hosted in a git history of changes
team collaboration
repository
review infrastructure changes using
Best Practice: Have a separate git repository merge requests
for app code and terraform code
Executing commands on virtual servers
"user_data" attribute Provisioners
When deploying virtual machines, we often need Another way are Provisioners
to pass in initial data when launching the instance Can be used to execute commands on the local
Most cloud providers have a mechanism to machine or remote machine to prepare the
pass data to instances at the time of creation: infrastructure
There are different types of provisioners
available
Provisioners - 1 Different types of provisioners
"remote-exec" provisioner "file" provisioner "local-exec" provisioner
Copy files or directories from Invokes a local
Invokes script on a remote
local to newly created resource executable after resource
resource after it's created
source: source file or is created
inline: list of commands
folder Locally, NOT on the
script: path
destination: absolute path created resource!
Difference:
=> user_data: passing data to AWS
=> remote-exec: connect via ssh using TF
Provisioners - 2
Provisioners are NOT recommended:
Use user_data if available
Breaks idempotency concept
TF doesn't know what you execute
Breaks current-desired state comparison
Alternative to remote-exec:
Use configuration management tools
Once server provisioned, hand over to those
tools, like Ansible
Modules - 1
A module is a container for multiple resources that are used together
Why modules? An example could be a module for EC2 instance
Organize and group configurations with configured networking and permissions:
Encapsulate into distinct logical components
Reuse
Without modules, complex configurations in
a huge file with no overview
Modules - 2
Then you can easily reuse same configuration, e.g.
for different AWS regions:
Like Function Definition
You can customize the configuration with
input variables
variables
= like function arguments
And expose created resources or specific
output values
attributes with output values
= like function return values
Modules - 3
Use existing modules Create your own modules
There are many available on To clean up your code
TF registry Modules have a pre-defined structure:
Automate provisioning EKS cluster with TF
Previously, we created EKS cluster manually
Many components to create and configure
No version control (history)
No simple replication of infra possible
No simple clean up
Team collaboration difficult
Terraform is currently the best way to
provision an EKS cluster!
Remote State in Terraform - 1
With remote state, Terraform writes the state data to a remote data store
Own state file:
Each user/CI server must make sure they
always have the latest state data before
running TF
So team collaboration very difficult
With shared remote state:
Data backup
Can be shared
Keep sensitive data off disk
Remote State in Terraform - 2
Terraform Cloud Azure Blob Storage & more!
Terraform supports storing state in...
Amazon S3 Google Cloud Storage
Steps to configure remote state in AWS S3 bucket:
1) Create bucket 2) Configure bucket as remote state location
S3
bucket
Best Practices - 1
Best practice around Terraform state:
Manipulate state only through TF commands
Always set up a shared remote state instead of on your laptop or in Git
Use state locking (locks state file until writing of state file is completed)
Back up your state file and enable versioning (allows for state recovery)
Use 1 state per environment
Best Practices - 2
Others:
Host TF scripts in Git repository
CI for TF code (review TF code, run automated tests)
Apply TF ONLY through CD pipeline (instead of manually)
Use _ (underscore) instead of - (dash) in all resource names, data source names, variable
names, outputs etc.
Only use lowercase letters and numbers
Use a consistent structure and naming convention
Don’t hardcode values as much as possible - pass as variables or use data sources to get a
value