terraform init # Initialize the directory & check out an existing configuration from version control
terraform plan # To perform certain limited verification of the validity of a Terraform configuration, without affecting real infrastructure.
terraform apply # Apply the changes required to reach the desired state of the configuration.
terraform destroy # Terminates all the resources specified in your Terraform state.
terraform console # Command provides an interactive console for evaluating expressions.
terraform output # Command is used to extract the value of an output variable from the state file.
terraform show # Command is used to provide human-readable output from a state or plan file.
terraform taint aws_instance.server2 - Terraform will propose to replace it in the next plan you create.
terraform apply
Or
terraform apply -replace="aws_instance.server2"
Workspaces allow you to use the same working copy of your configuration and the same plugin and module caches, while still keeping separate states for each collection of resources you manage.
workspace list - The command will list all existing workspaces.
workspace select NAME - This command will select another workspace.
workspace new NAME - This command will create a new workspace with the given name.
workspace delete NAME - This command will delete the specified workspace.
workspace show - The command will display the current workspace.
Link: https://www.terraform.io/docs/cli/workspaces/index.html
You can provide your credentials via the AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY, environment variables, representing your AWS Access Key and AWS Secret Key:
export AWS_ACCESS_KEY_ID="xxxxxxxxxx"
export AWS_SECRET_ACCESS_KEY="yyyyyyyyy"
terraform plan
Or you can use an AWS credentials or configuration file to specify your credentials. The default location is $HOME/.aws/credentials
provider "aws" {
region = "us-west-2"
shared_credentials_file = "/home/user/.aws/credentials"
}
Section "providers" are responsible for understanding API interactions and exposing resources.
provider "google" {
credentials = file("project-creds.json")
project = "my-project-id"
region = "us-central1"
zone = "us-central1-c"
}
provider "aws" {
region = "us-west-2"
shared_credentials_file = "/home/user/.aws/credentials"
}
resource "aws_instance" "name_my_instance" {
count = 2
# Make 2 similar servers
ami = "ami-xxxxxxxxx"
instance_type = "t3.micro"
tags = {
Name = "NameInstance"
Project = "Tesla"
}
}
Each "resource" block describes one or more infrastructure objects, such as virtual networks, compute instances, or higher-level components such as DNS records.
The usual way to run Terraform is to first switch to the directory containing the .tf files for your root module (for example, using the cd command). Then:
terraform plan
terraform apply
The "chdir" option instructs Terraform to change its working directory to the given directory before running the given subcommand.
terraform -chdir=environments/production apply
/*
Info:
Project - Apache server
Client - Billy Bob
*/
provider "aws" {
region = "us-west-2"
shared_credentials_file = "/home/user/.aws/credentials"
}
resource "aws_instance" "webserver" {
ami = "ami-xxxxxxxxx"
instance_type = "t2.micro"
vpc_security_group_ids = [
aws_security_group.webserver.id]
#attach security group
# bash code
user_data = <<EOF
#!/bin/bash
apt -y update
apt -y install apache2
ip=`curl http://169.254.169.254/latest/meta-data/local-ipv4`
echo "<h2>Apache Server <br> IP: $ip</h2>" > /var/www/html/index.html
sudo systemctl start apache2
EOF
tags = {
Name = "Apache server"
Client = "Billy Bob"
}
}
resource "aws_security_group" "webserver" {
name = "webserver security group"
description = "Allow TLS inbound traffic"
# Incoming traffic
ingress {
description = "http"
from_port = 80
to_port = 80
protocol = "tcp"
cidr_blocks = [
"0.0.0.0/0"]
ipv6_cidr_blocks = [
"::/0"]
}
ingress {
description = "https"
from_port = 443
to_port = 443
protocol = "tcp"
cidr_blocks = [
"0.0.0.0/0"]
ipv6_cidr_blocks = [
"::/0"]
}
ingress {
description = "ssh"
from_port = 22
to_port = 22
protocol = "tcp"
cidr_blocks = [
"0.0.0.0/0"]
ipv6_cidr_blocks = [
"::/0"]
}
# Outcoming traffic
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = [
"0.0.0.0/0"]
ipv6_cidr_blocks = [
"::/0"]
}
tags = {
Name = "WebserverSG"
}
}
Main.tf
provider "aws" {
region = "eu-central-1"
shared_credentials_file = "/home/user/.aws/credentials"
}
resource "aws_instance" "webserver" {
ami = "ami-xxxxxxxxx"
instance_type = "t2.micro"
# Outside bash code
user_data = file("webserver.sh")
tags = {
Name = "Apache server"
Client = "Billy Bob"
}
}
webserver.sh
#!/bin/bash
apt -y update
apt -y install apache2
ip=$(curl http://169.254.169.254/latest/meta-data/local-ipv4)
echo "<h2>Apache Server <br> IP: $ip</h2>" >/var/www/html/index.html
sudo systemctl start apache2
Main.tf
provider "aws" {
region = "eu-central-1"
shared_credentials_file = "/home/user/.aws/credentials"
}
resource "aws_instance" "webserver" {
ami = "ami-05f7491af5eef733a"
instance_type = "t2.micro"
# Outside bash code with variable "info"
user_data = templatefile("webserver.sh", {
info = "sample web server"
})
tags = {
Name = "Apache server"
Client = "Billy Bob"
}
}
webserver.sh
#!/bin/bash
apt -y update
apt -y install apache2
ip=$(curl http://169.254.169.254/latest/meta-data/local-ipv4)
echo "<h2>Apache Server <br> IP: $ip</h2><br> ${info} " >/var/www/html/index.ht$
sudo systemctl start apache2
To call a module means to include the contents of that module into the configuration with specific values for its input variables.
provider "aws" {
region = "us-west-2"
shared_credentials_file = "/home/user/.aws/credentials"
}
module "servers" {
source = "./app-cluster"
servers = 5
}
S3 Bucket
module "consul" {
source = "s3::https://s3-eu-west-1.amazonaws.com/examplecorp-terraform-modules/vpc.zip"
}
GitHub
module "consul" {
source = "git@github.com:hashicorp/example.git"
}
Link: https://www.terraform.io/docs/language/modules/sources.html#s3-bucket