Post date: 19/06/24

Current Update: Complete VPC Infrastructure

Next: undecided
EC2 Instance in Existing Subnet

Pre-req

  • Ensure installation of Terraform and AWS Cli
  • "terrafoam version" "aws --version"
  • Used aws single sign on(sso) for credentials instead of access-keys
  • aws recommends sso over access-key

Setting Up

  • creates project directory as terraform project folder
  • creates main.tf file as the entry point
  • creates variables.tf files for declaring variables
  • creates terraform.tfvars file for assigning variables

main.tf

 provider "aws" {
                            region = "eu-west-2"
                        }
                        resource "aws_instance" "paymentServer" {
                            ami                         = var.ami_id
                            instance_type               = var.instance
                            subnet_id                   = var.subnetID
                            security_groups             = [var.securityGroup]
                            associate_public_ip_address = true
                            key_name                    = var.serverConnectKey
                            tags                        = { Name = "paymentServer" }
                        }
            

Description: Not using requirement block hera, by default provider aws will use the latest version

variables.tf

 variable "ami_id" {
                          description = "paymentServer ami"
                          type = string
                        }
                        variable "instance" {
                          description = "paymentServer instance type"
                          type = string
                        }
                        variable "subnetID" {
                          description = "paymentServer subnet"
                          type = string
                        }
                        variable "securityGroup" {
                          description = "paymentServer instance type"
                          type = string
                        }
                        variable "serverConnectKey" {
                          description = "paymentServer instance type"
                          type = string
                        }
            

terraform.tfvars

 ami_id = "actual ami id"
                        instance = "t2.micro"
                        subnetID = "actual subnet id attached to a existing vpc"
                        securityGroup = ["actual id attached to a vpc"]
                        serverConnectKey = "ssh key-pair name to connect to instance"
                

Execution

In terminal ;
  • running terraform init
  • downloads the provider to use to connect to the cloud with LICENSE into .terraform directory

  • running terraform fmt
  • formats the contents to meet structural standard

  • running terraform validate
  • checks the code for error

  • running terraform plan
  • SCREENSHOT image

    Description: Showing what is to be executed to create the resource (ec2 instance).



  • running terraform apply
  • SCREENSHOT image

    Description Applies the plan by creating the resource in the cloud. An existing resource needed to be destroyed, it destroys that and creates the new one.

Connecting To Instance via ssh

SCREENSHOT image

Description: Using the public IP address of the created instance to connect via ssh. terraform state show "instance ADDRESS" provides info on instance including public IP.

Complete VPC Infrastructure

Implemented Resources

  • aws_vpc
  • aws_subnets in 2 AZs
  • aws_instance per subnet
  • aws_internet_gateway
  • aws_route_table
  • aws_s3_bucket
  • aws_security_group

Code


                                    provider "aws" {
                      region = "eu-west-2"
                    }

                    resource "aws_vpc" "NOPAK_Infrastructure" {

                      cidr_block       = "10.0.0.0/16"
                      instance_tenancy = "default"

                      tags = { Name = "NOPAK_Infrastructure" }
                    }

                    resource "aws_subnet" "public_azA" {
                      vpc_id            = aws_vpc.NOPAK_Infrastructure.id
                      cidr_block        = "10.0.0.0/24"
                      availability_zone = "eu-west-2a"

                      tags = { Name = "public_azA" }
                    }
                    resource "aws_subnet" "public_azB" {
                      vpc_id            = aws_vpc.NOPAK_Infrastructure.id
                      cidr_block        = "10.0.1.0/24"
                      availability_zone = "eu-west-2b"

                      tags = { Name = "public_azB" }
                    }

                    resource "aws_instance" "ec2-pub_az1" {
                      ami           = var.ami_id
                      instance_type = var.instance
                      subnet_id     = aws_subnet.public_azA.id
                      key_name = "xxxxxx"
                      associate_public_ip_address = true
                      security_groups = [aws_security_group.conn.id]
                      tags = {
                        Name = "pub_az1"
                      }
                    }

                    resource "aws_instance" "ec2-pub_az2" {
                    ami           = var.ami_id
                    instance_type = var.instance
                    subnet_id     = aws_subnet.public_azB.id
                    key_name = "xxxxx"
                    associate_public_ip_address = true
                    security_groups = [aws_security_group.conn.id]
                    tags = {
                      Name = "pub_az2"
                    }
                    }

                    resource "aws_instance" "ec2-pri" {
                    ami           = var.ami_id
                    instance_type = var.instance
                    subnet_id     = aws_subnet.public_azB.id
                    security_groups = [aws_security_group.conn.id]
                    key_name = "xxxxxx"
                    tags = {
                      Name = "pri"
                    }
                    }

                    resource "aws_internet_gateway" "main_gateway" {
                      vpc_id = aws_vpc.NOPAK_Infrastructure.id
                    }

                    resource "aws_route_table" "main_route" {
                      vpc_id = aws_vpc.NOPAK_Infrastructure.id

                      route {
                        cidr_block = "10.0.0.0/16"
                        gateway_id = "local"
                      }

                      route {
                        cidr_block = "0.0.0.0/0"
                        gateway_id = aws_internet_gateway.main_gateway.id
                      }

                    }

                    resource "aws_route_table_association" "main_route_association_pub_azA" {
                      subnet_id      = aws_subnet.public_azA.id
                      route_table_id = aws_route_table.main_route.id
                    }

                    resource "aws_route_table_association" "main_route_association_pub_azB" {
                      subnet_id      = aws_subnet.public_azB.id
                      route_table_id = aws_route_table.main_route.id
                    }

                    resource "aws_s3_bucket" "NOPAK_storage" {
                      bucket = "nopak-storage"
                    }

                    resource "aws_vpc_endpoint" "nopak-s3" {
                      vpc_id            = aws_vpc.NOPAK_Infrastructure.id
                      service_name      = "com.amazonaws.eu-west-2.s3"
                      vpc_endpoint_type = "Gateway"

                      route_table_ids = [
                        aws_route_table.main_route.id
                      ]

                    }
                    resource "aws_security_group" "conn" {
                      name = "ssh_connection"
                      vpc_id = aws_vpc.NOPAK_Infrastructure.id
                      tags = { Name = "ssh-connect"}
                    }

                    resource "aws_vpc_security_group_ingress_rule" "ssh" {
                      security_group_id = aws_security_group.conn.id
                      cidr_ipv4 = "31.49.113.86/32"
                      from_port = 22
                      ip_protocol = "tcp"
                      to_port = 22
                    }

                    resource "aws_vpc_security_group_ingress_rule" "icmp" {
                      security_group_id = aws_security_group.conn.id
                      cidr_ipv4 = "10.0.1.0/24"
                      ip_protocol = "icmp"
                      from_port = -1
                      to_port =  -1
                    }

                    resource "aws_vpc_security_group_egress_rule" "icmp" {
                      security_group_id = aws_security_group.conn.id
                      cidr_ipv4 = "10.0.1.0/24"
                      ip_protocol = "icmp"
                      from_port = -1
                      to_port =  -1
                    }
            

Results

  • Each instance in each subnet is accessible by it public

  • A third instance in subnet B has no public IP and is accessible only via the public instance in same subnet for security.
  • SCREENSHOT image

    Description: Showing ssh access to the public instance and a ping to the private instance.


  • S3 bucket is accessible via aws cli by authorised user
  • SCREENSHOT image

    Description: Access S3 bucket via cli