Fast and Simple Guide to Setting Up EC2 and S3 with Terraform Modules

Quick and Easy Steps to Configure EC2 and S3 Using Terraform Modules

ยท

5 min read

Fast and Simple Guide to Setting Up EC2 and S3 with Terraform Modules

Let's understand what Terraform is.

Terraform, an open-source infrastructure as code (IaC) tool by HashiCorp, enables users to define and provision infrastructure resources like virtual machines, networks, and storage with a declarative language, managing their lifecycle across cloud providers, on-premises environments, and software services.

Terraform provides a wide range of features for infrastructure as code (IaC) management, including modules for configuration reuse, remote state management for team collaboration, workspaces for managing multiple environments, state management tools like locking and versioning, dynamic configuration through interpolation functions, selective infrastructure management with resource targeting, extensive support for various providers and provisioners, dependency management for resource relationship handling, and advanced collaboration, governance, and automation with Terraform Cloud and Enterprise, all while allowing customization through HCL's extensibility for integration with third-party tools.

Before we dive into the implementation, make sure you have the following prerequisites installed:

  1. Terraform installed: Make sure you have Terraform installed on your local machine. You can download it from the official Terraform website and follow the installation instructions.

  2. Understand the basics of AWS EC2 & S3.

  3. AWS Account: You'll need an AWS account. Obtain your AWS access key ID and secret access key.

  4. AWS CLI configured: Configure the AWS CLI with your access key ID and secret access key using aws configure.

Let's learn the basic syntax of Terraform.

// Some basic syntax need to learn
provider "aws" {
    region = "ap-south-1"
    profile = "suraj-terraform"
}

//this is the string that will be variable
variable "firststring" {
    type = string
    default = "this is the first string"
}

output "myfirtstoutput" {
    value = "${var.firststring}"
}

//this is my maps
variable "mapexample" {
    type = map
    default = {
        "useast" = "ami1"
        "useast" = "ami1"
    }
}

output "mapoutput" {
    value = "${var.mapexample["useast"]}"

}

//this is my array 
variable "myarr" {
    type = list
    default = ["sg1", "sg2", "sg3"]
}

output "sgoutput" {
    value = "${var.myarr[0]}"
}

//this is my boolen
variable "myboolen" {
    default = true
}

output "outputboolean" {
    value = "${var.myboolen}"
}

//testing input and output
variable "myinput" {
    type = string
}

output "myoutput" {
  sensitive = true
  value = "${var.myinput}"
}

Now, let's dive into how to create an EC2 instance using Terraform.

//ec2.tf - .tf extension should be there
//All the details related to this value can be accessed through the AWS panel.
provider "aws" {
    region = "ap-south-1"
    profile = "suraj-terraform"
}

variable "vcpid" {
    type = string
    default = "vpc-04d00b3f0aabe06c0"
}

resource "aws_security_group" "terraform_ec2_test" {
  name        = "terraform_ec2_test"
  description = "Terraform test ec2 security"
  vpc_id      = "${var.vcpid}"

  ingress {
    from_port        = 22
    to_port          = 22
    protocol         = "tcp"
    cidr_blocks      = ["0.0.0.0/0"]
  }

  egress {
    from_port        = 22
    to_port          = 22
    protocol         = "tcp"
    cidr_blocks      = ["0.0.0.0/0"]
  }

  tags = {
    Name = "terraform_ec2_test"
  }
}

variable "amid" {
  default = "ami-0c768662cc797cd75"
}

resource "aws_instance" "terraform_ec2_test" {
  ami = "${var.amid}"
  instance_type = "t2.micro"
  key_name = "terraform"
  vpc_security_group_ids = ["${aws_security_group.terraform_ec2_test.id}"]

  tags = {
    Name = "Terraform Ec2 Instance"
  }
}

Now, let's explore how to create an S3 Storage using Terraform.

//S3.tf - .tf extension should be there
//All the details related to this value can be accessed through the AWS panel.
provider "aws" {
    region = "ap-south-1"
    profile = "suraj-terraform"
}

resource "aws_s3_bucket" "mybucket" {
    bucket = "mybucket-terraform-1010177"
    acl = "private"

    tags = {
        Environment = "Dev"
    }
}

resource "aws_s3_bucket_object" "mybucket_object" {
    bucket = aws_s3_bucket.mybucket.id
    key = "testfile.txt"
    source = "E:/server/server-setup/terraform/sampleobject.txt"
    etag = "${md5(file("E:/server/server-setup/terraform/sampleobject.txt"))}"
}

Now that you know how to create S3 and EC2 instances in AWS using separate files, let's see how to combine these operations into one by using the module technique. Here's an example:

Create a file named main.tf

provider "aws" {
    region = "ap-south-1"
    profile = "suraj-terraform"
}

module "sg_module" {
  sg_name = "sg_ec2_${local.env}"
  source = "./sg_m"
}

module "ec2_module_1" {
    sg_id = "${module.sg_module.sg_id_output}"
    ec2_name = "EC2 Instance from ${local.env}"
  source = "./ec2_m"
}

locals {
  env = "${terraform.workspace}"
}

First, create two folders based on your preference. For this example, we'll use ec2_m and sg_m. In each folder, create a file that suits the folder's purpose. For the EC2 folder, create ec_module.tf, and for the SG folder, create sg_module.tf. Then, start with the code:

//sg_module.tf
variable "vcpid" {
    type = string
    default = "vpc-04d00b3f0aabe06c0"
}

variable "sg_name" {}

resource "aws_security_group" "sg_module_creation" {
  name        = "${var.sg_name}"
  description = "Terraform test ec2 security"
  vpc_id      = "${var.vcpid}"

  ingress {
    from_port        = 22
    to_port          = 22
    protocol         = "tcp"
    cidr_blocks      = ["0.0.0.0/0"]
  }

  egress {
    from_port        = 22
    to_port          = 22
    protocol         = "tcp"
    cidr_blocks      = ["0.0.0.0/0"]
  }

  tags = {
    Name = "sg_module_creation"
  }
}

output "sg_id_output" {
    value = "${aws_security_group.sg_module_creation.id}"
}
//ec_module.tf
variable "amid" {
  default = "ami-0c768662cc797cd75"
}

variable "sg_id" {}
variable "ec2_name" {}

resource "aws_instance" "terraform_ec2_test_import" {
  ami = "${var.amid}"
  instance_type = "t2.micro"
  key_name = "terraform"
  vpc_security_group_ids = ["${var.sg_id}"]

  tags = {
    Name = "${var.ec2_name}"
  }
}

Now that we've finished coding, let's start Terraform using two commands:

Open a terminal in your Terraform directory and run the following commands:

terraform init

This command initializes Terraform and downloads the AWS provider plugin.

terraform apply

This command will prompt you to confirm the planned actions and then apply them. Type yes to confirm.

After Terraform applies the configuration successfully, you can access your EC2 instance and S3 bucket.

  • EC2 Instance: You can access your EC2 instance using the public IP or DNS provided in the output after Terraform applies the configuration.

  • S3 Bucket: You can access your S3 bucket via the AWS Management Console or programmatically using AWS SDKs or CLI.

When you're done experimenting, don't forget to clean up the resources to avoid unnecessary charges.

terraform destroy

This command will destroy all resources created by Terraform in your configuration.

Conclusion:

Once again, if you run into any issues with the above, they can be easily solved, but this requires a solid understanding of AWS EC2 & S3, as well as some networking concepts in AWS like DNS and IP addresses. In upcoming blogs, we will delve into advanced Terraform features using AWS, which will offer practical advantages.

Thanks for reading this blog.

Did you find this article valuable?

Support Suraj Shetty by becoming a sponsor. Any amount is appreciated!

ย