Terraform Basic Commands & Fundamentals: # Configure The AWS Provider

Download as pdf or txt
Download as pdf or txt
You are on page 1of 7

Terraform Basic Commands & Fundamentals

Terraform init > to initialise it and install the provider to communicate etc.
Terraform plan > dry run command
Terraform apply
Terraform destroy - for single deletes you need to add in parameters or comment the code out
--auto-approve > can be used with any of the top commands and you wont be asked to type yes.

Launch a simple ec2 instance

# Configure the AWS Provider


provider "aws" {
region = "ap-southeast-2"
access_key = "AKIAWFFCSE7KXWV4A7DU"
secret_key = "T/ "
}
resource "aws_instance" "fisrtTest"{
ami = "ami-0bd2230cfb28832f7"
instance_type = "t2.micro"
}

Next we will create a vpc in terraform and set up subnets.


So how do we know the vpc id? We haven't launched it yet, we do aws-vpc.followed by the name of
the vpc and then a .id, this is the power of terraform you don’t need to know it, the line above is
where the vpc is specified and every resource has a id. The vpc does not need to be defined first for
the vpc-id to be referenced. So even if we subnet first and reference the vpc at the top it will still
work, it doesn't matter where you define the code in terraform unlike coding. So it knows what to
create first it knows a subnet belongs in a vpc and therefore will create the vpc first.

# Configure the AWS Provider


provider "aws" {
region = "ap-southeast-2"
access_key = "AKIAWFFCSE7KXWV4A7DU"
secret_key = "T/

resource "aws_vpc" "terraformVPC" {


cidr_block = "10.0.0.0/16"
tags = {
name = "terraformVPC"
}
}
resource "aws_subnet" "subnet-1"{
vpc_id = aws_vpc.terraformVPC.id
cidr_block = "10.0.1.0/24"
tags = {
name = "TerraformSubnet"
}
}

resource "aws_subnet" "subnet-2"{


vpc_id = aws_vpc.terraformVPC.id
cidr_block = "10.0.2.0/24"
tags = {
name = "TerraformSubnet2"
}
}

Next section what are the files created on the side. Terraform init creates the terraform file as it
initialises it and installs. Plugins etc.
Terraformtfstate tracks everything, so checks current status and what we are asking it change etc.
don’t mess around with it.

Next create instance deployed in a custom vpc on a custom subnet and assign a public ip to it for ssh
and to make changes in. also add a webserver to handle web traffic

For you to have a public ip you need to have an internet gateway, so unlike above for elastic ip
address there is a catch where you define it since it relies on the deployment of the internet
gateway. So even in the console if you assign an EIP to a device on a subnet or vpc that doesn’t have
a internet gateway it will throw an error. Hence in terraform we need to deploy the internet
gateway first. So we need to use the depends on flag and equal to internet gateway we created, and
don’t need to reference .id but whole object as you can see below.

# Configure the AWS Provider


provider "aws" {
region = "ap-southeast-2"
access_key = "AKIAWFFCSE7KXWV4A7DU"
secret_key = "T/
}
#create custom vpc
resource "aws_vpc" "terraformVPC" {
cidr_block = "10.0.0.0/16"
tags = {
name = "terraformVPC"
}
}

#creating a internet gateway


resource "aws_internet_gateway" "TF-GW" {
vpc_id = aws_vpc.terraformVPC.id
tags = {
Name = "TF-IG"
}
}
#creating a custom route table
resource "aws_route_table" "TF-RT" {
vpc_id = aws_vpc.terraformVPC.id
route {
cidr_block = "0.0.0.0/0"
gateway_id = aws_internet_gateway.TF-GW.id
}

tags = {
Name = "TF"
}
}

#create a subnet
resource "aws_subnet" "TF-subnet-1"{
vpc_id = aws_vpc.terraformVPC.id
cidr_block = "10.0.1.0/24"
availability_zone = "ap-southeast-2a"
tags = {
name = "Terraform-Subnet"
}
}
#assigning the subnet just created to the route table we just created using route table association
resource "aws_route_table_association" "a" {
subnet_id = aws_subnet.TF-subnet-1.id
route_table_id = aws_route_table.TF-RT.id
}
#create security group to allow port 22, 80 443
resource "aws_security_group" "TF-allow_web" {
name = "TF-Allow-WEbAccess"
description = "allow web traffic"
vpc_id = aws_vpc.terraformVPC.id
ingress {
description = "HTTPS"
from_port = 443
to_port = 443
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
ingress {
description = "HTTP"
from_port = 80
to_port = 80
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
ingress {
description = "HTTP"
from_port = 22
to_port = 22
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
#were allowing all ports for the egress and the -1 in protocol means all traffic
egress {
from_port =0
to_port =0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
tags = {
Name = "TF-WebAccess"
}
}

#creating a network interface with an ip in the subnet that was created in step 4
resource "aws_network_interface" "Web_server_ray" {
subnet_id = aws_subnet.TF-subnet-1.id
private_ips = ["10.0.1.50"]
security_groups = [aws_security_group.TF-allow_web.id]
}
#Assinging a elsatic ip address to the network interface created in step 7
resource "aws_eip" "TF-E-IP" {
vpc = true
network_interface = aws_network_interface.Web_server_ray.id
associate_with_private_ip = "10.0.1.50"
depends_on = [aws_internet_gateway.TF-GW]
}

#creating an lunux server and installing/ enabling apache2


resource "aws_instance" "web_server_instance"{
ami = "ami-0bd2230cfb28832f7"
instance_type = "t2.micro"
availability_zone = "ap-southeast-2a"
key_name = "Sydney-kp"
network_interface {
device_index = 0
network_interface_id = aws_network_interface.Web_server_ray.id
}

user_data = <<EOF
#!/bin/bash
yum update -y
yum install httpd -y
systemctl start httpd
systemctl enable httpd
cd /var/www/html
aws s3 cp s3://rihan97/names.csv ./
aws s3 cp s3://rihan97/index.txt ./
EC2NAME=`cat ./names.csv|sort -R|head -n 1|xargs`
sed "s/INSTANCE/$EC2NAME/" index.txt > index.html
EOF

Terraform commands
Just typing terraform and enter shows all the different commands to use;
Terraform state list > lists the resources in your state.
Terraform state show (copy the resource) shows more detailed about the resource.

Terraform Output
Another way to see information other than using the terraform state show command is using
terraform output.
When you use terraform apply you can tell terraform to print the information out using output.
So like we want to have information about the elastic ip address being created underneath it we can
have output statement to show us;

#Assinging a elsatic ip address to the network interface created in step 7


resource "aws_eip" "TF-E-IP" {
vpc = true
network_interface = aws_network_interface.Web_server_ray.id
associate_with_private_ip = "10.0.1.50"
depends_on = [aws_internet_gateway.TF-GW]
}

output "server_public_ip" {
value = "aws_eip.TF-E-IP.public_ip"
}

So from above code, when we did terraform apply it printed out the server public ip address in the
terminal.
So can do this for other things also just call it whatever but in value equal it to the resource name as
well as the property ID.

A terraform refresh refreshes all your states and runs the output so you can verify them without
actually deploying them or applying it.

Terraform resource > we can delete just one resource by using the following command;
Terraform destroy -target (followed by the resource name)
Same if you want to deploy just one resource then we can use the following target command;
Terraform apply -target (resource name)

Terraform variables
We can use variables so that we don’t have to repeat ourselves in the code,
Any variable that isn't assigned a value, when we try to apply the code terraform will prompt you to
enter the value in the terminal window. So like the example below we have not defined the subnet
value but have been prompted instead when applying the code;

variable "subnet_prefix" {
description = "cidr block for the subnet"
}

To pass in variables through the terminal is inconvenient so can instead can do it though command
line argument;
Terraform apply -var "subnet_prefix=10.0.100.0/24" so instead being prompted we added in the
variable ourselves using var for variable command.

Both methods not good; so best way to do is to create a separate file for terraform to look for it. A
.tfvars file.
So like the following save it in the same folder but as a terraform.tfvars file.

subnet_prefix = "10.0.200.0/24"

When you have too many files and it keeps building and you don’t want to have this file, you can
rename it and tell terraform to look for a specific file. Rename it and then for terraform to look for
that file you have to tell it in the terminal like;
Terraform apply -var-file example.tfvars (example being the name of the new file).

If however, the user does not input a default for the variable then terraform automatically does it
for us.

If we want the type to be only one of a kind type then we can use a type constraint, such as
Type = string will mean we will only allow string type. So if we don’t input the right input type it will
not allow the code to be applied.

How to use a list as a variable; so we can define the cidr block like this in a separate file;

subnet_prefix = ["10.0.1.0/24", "10.0.2.0/24"]

And then to assign these to the subnets we can reference it with [0] and [1] for the second one.

resource "aws_subnet" "subnet-1" {


vpc_id = aws_vpc.prod-vpc.id
cidr_block = var.subnet_prefix[0].cidr_block
availability_zone = "us-east-1a"
tags = {
Name = var.subnet_prefix[0].name
}
}
resource "aws_subnet" "subnet-2" {
vpc_id = aws_vpc.prod-vpc.id
cidr_block = var.subnet_prefix[1].cidr_block
availability_zone = "us-east-1a"
tags = {
Name = var.subnet_prefix[1].name
}
}

Like we have a list of variables above, you can also have a list of objects also, instead of assigning the
tags or hard coding it we will have a variable a cidr block and a name, and this way the cidr block will
get assigned to the cidr blocka and name to the name. so like the following way;
In .tf file you define the variables
In .tfvars file you assign the variables which you defined in the .tf file.

You might also like