Part 5— HumanGov Application — Terraform-3: Resources Attributes & Dependencies
HumanGov is a software-as-a-service (SaaS) cloud company that will create a Human Resources Management SaaS application for the Department of Education across all 50 states in the US and host the application files and databases in the cloud. Whenever a new employee is hired, a new registry will be created for this employee inside this application.
In this following project series, we are going to transition the architecture from a traditional virtual machine architecture to a modern container-based architecture using Docker containers and Kubernetes running on AWS. In addition, we will also be responsible for automating the complete software delivery process using Pipelines CI/CD using AWS services such as AWS CodeCommit, AWS CodePipeline, AWS CodeBuild, and AWS CodeDeploy. Finally, we will learn how to monitor and observe the cloud environment in real-time using tools such as Prometheus, Grafana, and automate one-off cloud tasks using Python and the AWS SDK.
In this section, we are going to introduce working with Resources Attributes & Dependencies in Terraform and practice Terraform with cloud provider AWS before using it in the implementation of the HumanGov application. This is the 5th part of a project series. Check Part 1, Part 2, Part 3 and Part 4 to follow up.
Resources Attributes in Terraform
In Terraform, resources define and provision infrastructure components in a cloud environment, such as a virtual machine, network interface, database, etc. Resources have attributes that allow you to configure their properties. These attributes vary depending on the type of resource.
Define a resource in Terraform:
resource "provider_resource-type" "resource_name" {
attribute_name = value
# Additional attributes...
}
provider_resource-type
: Specifies the provider and resource typeresource_name
: A name you give to the resource instanceattribute_name
: The attribute of the resource for configurationvalue
: The value you want to assign to the attribute.
Example:
resource "aws_vpc" "example_vpc" {
cidr_block = "10.0.0.0/16"
}
resource "aws_subnet" "example_subnet" {
vpc_id = aws_vpc.example_vpc.id
cidr_block = "10.0.1.0/24"
availability_zone = "us-east-1a"
}
resource "aws_instance" "example_instance" {
ami = "ami-12345678"
instance_type = "t2.micro"
subnet_id = aws_subnet.example_subnet.id
}
Argument References: Attribute values can be hard-coded or referenced to other resources using argument references. It establishes relationships between different parts of the infrastructure using the attributes of one resource as inputs for another. In the example above, the aws_instance
and aws_subnet
resources reference the id
attribute of the aws_subnet
and aws_vpc
respectively using their argument references.
Hands-on: Terraform Resources Attributes
We will create two resources on AWS; an EC2 instance and a security group which is a firewall for the EC2 instance. Security group ensures the security and controlled access of EC2 instances. It controls inbound and outbound traffic. This helps protect your instances from unauthorized access. Specified IP ranges, allowing or denying traffic on specific ports or port ranges (HTTP or HTTPS, SSH access, database communication, etc.) can restrict access to only authorized users. It’s a best practice to define security group rules that follow the principle of least privilege, where you only allow the minimum required traffic and deny all other traffic by default.
We are going to create an EC2 instance first and then associate a security group to this instance.
Create and provision an EC2 instance and a security group
Open AWS Cloud9 and create a resources.tf file.
Go to the Terraform documentation to use the latest instructions.
Look for aws_instance and aws_security group. We are going to use instructions in these sections.
Step 1: Define the ami
Attribute
We need an Amazon Machine Image(AMI) for the EC2 instance inside Terraform resources.tf file. An AMI is a pre-configured virtual machine image used to create EC2 instances and contains the necessary information to launch an instance, including the operating system, applications, and configurations. The ami
attribute specifies the AMI.
Go to AWS Console and search for EC2. Go to Launch Instance. Normally, if we create an EC2 instance and select an operating system, for example, Linux, AWS assigns an AMI ID to this instance. This AMI is operating system and region-specific. We are going to use this ID inside our terraform file to configure the EC2 instance using the ami attribute.
Step 2: Create EC2 Instance Resource with ami and instance_type attributes
resource "aws_instance" "example" {
ami = "ami-051f7e7f6c2f40dc1" # This is an Amazon Linux 2 AMI ID in the us-east-1 region
instance_type = "t2.micro"
}
In Terraform, the instance_type
attribute determines the virtual machine's hardware configuration, including the number of virtual CPUs, amount of memory, storage capabilities, and network performance.
Step 3: Create security_group Resource
We are going to open port 22 which allows inbound SSH traffic.
resource "aws_security_group" "example" {
name = "example"
description = "Example security group"
ingress {
from_port = 22
to_port = 22
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
}
Using the cidr_blocks
attribute to specify the IP range that is allowed to connect via SSH. Using "0.0.0.0/0"
allows SSH access from any IP address, which might not be the most secure option. You can replace it with a more specific IP range.
This is the Terraform resources.tf file on AWS Cloud9 so far:
Step 4: Link security_group and EC2 Instance Resources
The security groups you attach to an EC2 instance will dictate the rules for inbound and outbound traffic to and from that instance. In Terraform, you need to create security groups before the EC2 instance to be able to attach them.
We can specify the vpc_security_group_ids
attribute to associate the EC2 instance with the security. Using dependency such as this lets Terraform create the security group first and assign its value to the attribute. Therefore, it can associate the security group with the EC2 instance.
resource "aws_instance" "example" {
ami = "ami-051f7e7f6c2f40dc1" # This is an Amazon Linux 2 AMI ID in the us-east-1 region
instance_type = "t2.micro"
vpc_security_group_ids = [aws_security_group.example.id]
}
Step 5: Run Terraform
Now we can run terraform to create resources with defined resource attributes. First, make sure you are inside the right folder where resources.tf file is located. Then run apply to see what is planned, and apply planned changes.
cd humangov-terraform/
terraform plan
terraform apply
You can see that Terraform created the security group first and the EC2 instance later due to dependency.
Go to AWS -> Services -> EC2 -> Instances
You should be able to see the running instance that we created with Terraform.
When you go inside and check the Security, you will see the security group that we attached.
Step 6: Destroy Resources
terraform destroy
Make sure to destroy resources that you will not need and use, otherwise, you will be charged.
CONGRULATIOTIONS!!
Follow me on LinkedIn: