Terraform Discovery¶
HashiCorp’s Terraform is a tool to help you to define infrastructure either locally, in a private cloud or to different public cloud providers. Infrastructure-as-a-code or IaC allows to manage your infrastructure configuration as you would do for regular code. You can have one source of truth and to use every automation concepts that were introduced by software developpers (CI/CD, git…), track changes, prevent accidental misconfiguration and the ability to deploy/redeploy and scale at will.
Terraform is an immutable and declarative language. Meaning that you can describe the desired state and Terraform will figure out how to achieve this state.
In this lab you will use the command line from your computer or from the one provided.
Export your AWS API Key ID and Secret¶
Open the terminal and enter paste the following commands. Add your Access Key ID and your Secret Access Key:
export AWS_ACCESS_KEY_ID=your-access-key-here
export AWS_SECRET_ACCESS_KEY=your-secret-key-here
Create your main.tf¶
Then go to the following directory to create your first terraform file.
cd ~/utd-automation/terraform
And create a main.tf file:
code main.tf
# or
subl main.tf
Add the provider¶
First you need to declare a provider in Terraform. The provider state what type of deployment you want. Is can be a solution like Palo Alto Networks’ NGFW or Prisma Cloud, Kubernetes, or a public Cloud provider like AWS, GCP and Azure. HashiCorp provides a list of provider and third party providers can developp their own integrations. You can find a list of providers on HashiCorp website.
For AWS we will declare it as a provider and select the region (eu-west-3 or Paris here):
provider "aws" {
region = "eu-west-3"
}
You can find more details on AWS provider here
Add a first instance¶
resource "aws_instance" "aws_instance_discovery" {
ami = "ami-078db6d55a16afc82"
instance_type = "t2.micro"
}
https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/instance
Use terraform to deploy your instance¶
Terraform will check the provider or providers used and download all the up to date resources to be able to deploy
terraform init
terraform plan
You can review the operations about to be performed by Terrafom.
terraform apply
Review your changes and when asked, enter yes
Use terraform to deploy your instance¶
Some changes wont affect your infrastructure and some will require an instance to be destroyed and re-created.
For example adding a name wont change your instance, add this tag to your resource aws_instance:guilabel:.
tags = {
Name = "tf-disc-web1"
}
Your resource should look like this:
resource "aws_instance" "web1" {
ami = "ami-078db6d55a16afc82"
instance_type = "t2.micro"
tags = {
Name = "tf-disc-web1"
}
}
Enter the terraform apply command:
terraform apply
Enter yes in the terminal when asked.
Adding or changing the content of the user-data field will require your instance to be destroyed. A new one will be spawned by terraform. Add the following snippet to your aws_instance:guilabel::
user_data = <<-EOF
#!/bin/bash
echo "Pew Pew Pew" > index.html
nohup python3 -m http.server 8080 &
EOF
The aws_instance web1 shoulw now look like this:
resource "aws_instance" "web1" {
ami = "ami-078db6d55a16afc82"
instance_type = "t2.micro"
# cinquième étape
vpc_security_group_ids = [aws_security_group.sg1.id]
user_data = <<-EOF
#!/bin/bash
echo "Pew Pew Pew" > index.html
nohup python3 -m http.server 8080 &
EOF
tags = {
Name = "tf-disc-web1"
}
}
Enter the terraform apply command:
terraform apply
Enter yes in the terminal when asked.
Add a security group¶
resource "aws_security_group" "sg1" {
name = "tf-disc-sg1"
ingress {
from_port = 8080
to_port = 8080
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
}
Do not forget to add the link to this security group in your resource. We can link the object that will be tracked by terraform as the object type.object name.id in the aws instance web1. All the resources will be created in the right order and tracked by terraform.
vpc_security_group_ids = [aws_security_group.sg1.id]
The thow objects will now be linked.
terraform apply
Enter yes in the terminal when asked.
Open your browser and enter the following address: http://<your-ip>:8080 or
curl http://<your-ip>:8080
We encourage you to read more on Terraform by reading the blog post from Yevgeniy Brikman from Gruntwork.
provider "aws" {
region = "eu-west-3"
}
resource "aws_instance" "web1" {
ami = "ami-078db6d55a16afc82"
instance_type = "t2.micro"
vpc_security_group_ids = [aws_security_group.sg1.id]
user_data = <<-EOF
#!/bin/bash
echo "Pew Pew Pew" > index.html
nohup python3 -m http.server 8080 &
EOF
tags = {
Name = "tf-disc-web1"
}
}
resource "aws_security_group" "sg1" {
name = "tf-disc-sg1"
ingress {
from_port = 8080
to_port = 8080
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
}
with variables
provider "aws" {
region = "eu-west-3"
}
resource "aws_instance" "web1" {
ami = "ami-078db6d55a16afc82"
instance_type = "t2.micro"
vpc_security_group_ids = [aws_security_group.sg1.id]
user_data = <<-EOF
#!/bin/bash
echo "Pew Pew Pew" > index.html
nohup python3 -m http.server "${var.server_port}" &
EOF
tags = {
Name = "tf-disc-web1"
}
}
resource "aws_security_group" "sg1" {
name = "tf-disc-sg1"
ingress {
from_port = var.server_port
to_port = var.server_port
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
}
variable "server_port" {
description = "The port the server will use for HTTP requests"
type = number
default = 8080
}
Log into the AWS console¶
Predeployed Pod¶
Users
Ethernet1/2
configure
set mgt-config users admin password
Note
While it is a security best practice to use SSH keys to authenticate to VM instances in the cloud, we have defined a static password for the firewall’s admin account in this lab (specifically, in the bootstrap package). This is because the PAN-OS XML API cannot utilize SSH keys and requires a username/password or API key for authentication.