HashiCorp Terraform
You might want to cover these before starting with Terraform ( or come back to them as needed ):
Learn Terraform:
- Terraform - Introduction
- Terraform - Install
- Terraform Basics - Create Infrastructure with Docker
- Terraform Basics - Update and Destroy with Docker
- Terraform Basics - Variables and Outputs
- Terraform Basics - AWS
Install Terraform
Manual Install
You can either build from source or just download a binary. This can be done for Linux, Mac OSX, or Windows.
To download a binary just go to this URL, download the package for your system, and unzip it:
Compile from source instead of downloading the binary:
git clone https://github.com/hashicorp/terraform.git
cd terraform
go install
Once you have either built or downloaded the binary you will need to either place it somewhere on your path or change your path.
For Linux or Mac OSX
echo $PATH
sudo mv ~/Downloads/terraform /usr/local/bin/
- Setting up the path is similar for windows
Verify that it works with the help command:
terraform -help # get help
terraform -help plan # get help for sub command
Setup tab completion for BASH:
touch ~/.bashrcterraform -install-autocomplete
Setup tab completion for Zsh:
vi ~/.zshrcterraform -install-autocomplete
OSX Homebrew
Install:
brew tap hashicorp/tap # install repo
brew install hashicorp/tap/terraform # install Terraform
Update:
brew update # update Homebrew
brew upgrade hashicorp/tap/terraform # update Terraform
Windows with Chocolatey
choco install terraform
Debian / Ubuntu
- Update repo info and grab prerequisites
- Add key for new repo
- Add new repo
- Install Terraform
sudo apt-get update && sudo apt-get install -y gnupg software-properties-common curl
curl -fsSL https://apt.releases.hashicorp.com/gpg | sudo apt-key add -
sudo apt-add-repository "deb [arch=amd64] https://apt.releases.hashicorp.com $(lsb_release -cs) main"
sudo apt-get update && sudo apt-get install terraform
RHEL / CentOS - YUM
sudo yum install -y yum-utils
sudo yum-config-manager --add-repo https://rpm.releases.hashicorp.com/RHEL/hashicorp.repo
sudo yum -y install terraform
Fedora - DNF
sudo dnf install -y dnf-plugins-core
sudo dnf config-manager --add-repo https://rpm.releases.hashicorp.com/fedora/hashicorp.repo
sudo dnf -y install terraform
- Vault, Consul, Nomad and Packer - These can also be installed from the HashiCorp repos.
Amazon Linux
sudo yum install -y yum-utils
sudo yum-config-manager --add-repo https://rpm.releases.hashicorp.com/AmazonLinux/hashicorp.repo
sudo yum -y install terraform
Quick Docker Example
- Prerequisite - You will need Docker installed and running.
Create a directory and enter it:
mkdir test1
cd test1
Define your infrastructure:
main.tfterraform { required_providers { docker = { source = "kreuzwerker/docker" version = "~> 2.13.0" } } } provider "docker" {} resource "docker_image" "nginx" { name = "nginx:latest" keep_locally = false } resource "docker_container" "nginx" { image = docker_image.nginx.latest name = "test1" ports { internal = 80 external = 8000 } }
Change the providor for Windows:
provider "docker" {
host = "npipe:////.//pipe//docker_engine"
}
Use these commands:
terraform init
terraform apply
docker ps
terraform destroy
Build Infrastructure (AWS)
Prerequisites:
- Terraform installed
- AWS CLI
- AWS account
NOTE - AWS generally costs money and you will probably incur charges .
Export variables for your credentials:
export AWS_ACCESS_KEY_ID="xxxxxxxx"
export AWS_SECRET_ACCESS_KEY="xxxxxxxx"
export AWS_DEFAULT_REGION="xxxxxxxx"
Create and enter directory:
mkdir deploy1
cd deploy1
Create a .tf file like this:
vi main.tfterraform { required_providers { aws = { source = "hashicorp/aws" version = "~> 3.27" } } required_version = ">= 0.14.9" } provider "aws" { profile = "default" region = "us-west-2" } resource "aws_instance" "app_server" { ami = "ami-830c94e3" instance_type = "t2.micro" tags = { Name = "ExampleAppServerInstance" } }
NOTE
- Your AMI ID needs to match your region.
- You need a default VPC in your region.
Terraform block:
- hashicorp/aws short for registry.terraform.io/hashicorp/aws
- registry.terraform.io is default
- providor version is optional but recommended
Provider block:
- profile - refers to AWS creds in AWS config
Resource block:
- resource –type– –name– {
- Unique resource ID: name and type, ex: aws_instance.app_server
Download / install providers:
terraform init
- .terraform - Terraform providers installed here
- *.terraform.lock.hcl - specifies provider version
Fix formatting for all of your files:
terraform fmt
Check if configs are valid:
terraform validate
Apply the changes to actually create a resource:
terraform apply
-
review plan and type “yes” to continue
-
terraform.tfstate
- the state file, tracks managed resources
- can sensitive info and needs to be secure
- store remotely for prod
Inspect current state:
terraform show
List resources in project state:
terraform state list
You can set these if needed:
vpc_security_group_ids = ["sg-0077..."]
subnet_id = "subnet-923a..."
Updates / Changes
Just edit your .tf files and run:
terraform apply
Destroy Infrastructure
Just run this:
terraform destroy
- type “yes”
Variables
All files with a .tf extension are loaded so the names don’t matter.
variables.tfvariable "instance_name" { description = "Value of the Name tag for the EC2 instance" type = string default = "DifferentDefaultAppServerInstance" }
Access your variable like this:
main.tf... tags = { Name = var.instance_name } ...
Specify variable when applying changes like this:
terraform apply -var "instance_name=Server1"
Outputs to Query Data
These allow you to easily query useful data.
Define outputs:
outputs.tfoutput "instance_id" { description = "ID of the EC2 instance" value = aws_instance.app_server.id } output "instance_public_ip" { description = "Public IP address of the EC2 instance" value = aws_instance.app_server.public_ip }
Apply the new config:
terraform apply
Query output values:
terraform output
Remote state storage
main.tfterraform { cloud { organization = "ORG_NAME" workspaces { name = "Workspace1" } } ....
Login:
terraform login
- type “yes”
terraform init
- type “yes”
Remove the state file:
rm terraform.tfstate
- Fill AWS info into Terraform cloud web UI.