welcome at SebWalak.com

Base, custom VPC stack, provisioned with Terraform in AWS

categories: /dev-ops
tags: #aws   #cloud   #terraform

This post shows Terraform configuration files I have used to create base AWS stack for my projects. It is a minimal configuration for new VPC with public/private subnets and autoscaling bastion.

Following is my best attempt at illustrating it.

Diagram showing AWS VPC with public and private subnets, routing table entries and a bastion in ASG

Diagram showing AWS VPC with public and private subnets, routing table entries and a bastion in ASG

The stack consists of var.az_count (declared in variables.tf) subnets with route via NAT (here referred to as private) and equal number of subnets with route via Internet Gateway (aka public). The maximum value of var.az_count in this template is the number of availability zones in given var.region. This limitation comes from the fact that this template iterates with simple array index selector [count.index] rather than with Terraform’s built-in function element(). Element() function would return modulo by array length.

Exactly one bastion is launched by autoscaling group in any of the defined and available (as in functioning) public subnets (so using ASG for availability, not scalability). The bastion only allows traffic on port 22 from single IP address declared as var.op_ip (as in operator’s IP and not a CIDR format) and outbound traffic from bastion is allowed to go anywhere.

There is no other security groups (very restrictive by default, good) or ACLs defined (not so good to leave it like that).

I recommend extensive tagging as it makes identification of AWS resources easier in the console. If you use configuration management platforms such as Ansible, tagging becomes more than just a convenience. This snippet does not really stand for what I preach as it uses single var.tag_name to create tag called “Name” (with a suffix) on whichever resources allow it. In more usable case you could consider additional tagging without any suffixes for Environment (e.g. dev/test/prod) at the least. You can also tag by function (backoffice, web, datalayer, etc.). That allows you to cross cut your resources within your configuration management tool by a range of aspects.

I only use eu-west-1 and eu-west-2 regions so make sure you add appropriate image ids for your region and system of choice in variables.tf. You will find images for AMI and Ubuntu for the above two regions are prepopulated in that file.

If you like pretty pictures like the one above… It took some experimenting to find a suitable tool for creating AWS diagrams. I really like draw.io for this purpose. Open draw.io in AWS mode first. Then menu File / Open From / URL and point it to

Right click and copy this url

Note: This stack may incur charge for the resources used.

If you find something wrong (minding the aforementioned limitations) with this stack please let me know. Also, can you see any opportunity to improve the stack or diagram?

Gist for this module.

Thumbnail