My first Take on Terraform – Part 02

On my previous blog post, I started looking at Terraform and AWS. I’ve learned how to write a *.tf file, how to pass values to it, some core AWS concepts and I was able to provision an EC2 instance with NGINX and to obtain its public DNS, but I’ve struggled with the security part of it, it was necessary to manually set some rules in the default security group.

In this blog post, I hope to overcome that issue.

The starting point is the *.ts file from part one and you can get it here.

To provision our EC2 instance into a new security group with our rules configured we need to add these items

So let’s add these “sections” to our *.ts file

# VARIABLES
...
variable "network_address_space" {
default="10.1.0.0/16"
}
variable "subnet1_address_space" {
  default = "10.1.0.0/24"
}
...
# DATA
data "aws_availability_zones" "available" }

# RESOURCES
resource "aws_vpc" "vpc" {
  cidr_block = "${var.network_address_space}"
  enable_dns_hostnames = "true"
}
resource "aws_internet_gateway" "igw" {
  vpc_id = "${aws_vpc.vpc.id}"
}
resource "aws_subnet" "subnet1" {
  cidr_block        = "${var.subnet1_address_space}"
  vpc_id            = "${aws_vpc.vpc.id}"
  map_public_ip_on_launch = "true"
  availability_zone = "${data.aws_availability_zones.available.names[0]}"

}
resource "aws_route_table" "rtb" {
  vpc_id = "${aws_vpc.vpc.id}"

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

resource "aws_route_table_association" "rta-subnet1" {
  subnet_id      = "${aws_subnet.subnet1.id}"
  route_table_id = "${aws_route_table.rtb.id}"
}

resource "aws_security_group" "nginx-sg" {
  name        = "nginx_sg"
  vpc_id      = "${aws_vpc.vpc.id}"

  # SSH access from anywhere
  ingress {
    from_port   = 22
    to_port     = 22
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"] # not ready for production, should be your IP address
  }

  # HTTP access from anywhere
  ingress {
    from_port   = 80
    to_port     = 80
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
  }

  # outbound internet access
  egress {
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = ["0.0.0.0/0"]
  }
}

resource "aws_instance" "nginx1" {
  ami           = "ami-c58c1dd3"
  instance_type = "t2.micro"
  subnet_id     = "${aws_subnet.subnet1.id}"
  vpc_security_group_ids = ["${aws_security_group.nginx-sg.id}"]
  key_name        = "${var.key_name}"
...

A brief explanation …
Two new variables network_address_space and subnet1_address_space. A new DATA section to query aws for availability zones and some new resources : aws_vpc ( a new vpc to hold our new instances); aws_internet_gateway (for instances within our vpc to be able to communicate to the outside world) ; aws_subnet (placed in [0] availability zone for the region); aws_route_table & aws_route_table_association (to tell the vpc what to do with traffic ); aws_security_group ( with the rules for ingress and egress we want to define );
You can find the full file on GitHub
We can now do
terraform apply -var-file=terraform.tfvars
And there you go… EC2 Instance created in a custom security group.
and to remove the prompt
terraform apply -var-file=terraform.tfvars -auto-approve

Hope you find it useful … here is the GitHub repo

 

Cheers!

This entry was posted in continuous delivery, devops, Tools. Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.