From 44500f14a3e2e5094575e40ed6c92543fc3ba9b6 Mon Sep 17 00:00:00 2001 From: Scott Lowe Date: Thu, 16 Mar 2017 11:15:14 -0600 Subject: [PATCH] Add Terraform configurations for SSH bastion host on AWS Add Terraform configurations to build an SSH bastion host (and remote host for testing) on AWS. Uses CentOS and CentOS Atomic Host images (change search parameters in data.tf to change images). Signed-off-by: Scott Lowe --- terraform/aws/bastion-aws/data.tf | 13 ++++++ terraform/aws/bastion-aws/instances.tf | 30 +++++++++++++ terraform/aws/bastion-aws/networking.tf | 53 ++++++++++++++++++++++ terraform/aws/bastion-aws/output.tf | 11 +++++ terraform/aws/bastion-aws/provider.tf | 3 ++ terraform/aws/bastion-aws/security.tf | 59 +++++++++++++++++++++++++ terraform/aws/bastion-aws/ssh.cfg | 12 +++++ terraform/aws/bastion-aws/vars.tf | 11 +++++ 8 files changed, 192 insertions(+) create mode 100644 terraform/aws/bastion-aws/data.tf create mode 100644 terraform/aws/bastion-aws/instances.tf create mode 100644 terraform/aws/bastion-aws/networking.tf create mode 100644 terraform/aws/bastion-aws/output.tf create mode 100644 terraform/aws/bastion-aws/provider.tf create mode 100644 terraform/aws/bastion-aws/security.tf create mode 100644 terraform/aws/bastion-aws/ssh.cfg create mode 100644 terraform/aws/bastion-aws/vars.tf diff --git a/terraform/aws/bastion-aws/data.tf b/terraform/aws/bastion-aws/data.tf new file mode 100644 index 0000000..9130a42 --- /dev/null +++ b/terraform/aws/bastion-aws/data.tf @@ -0,0 +1,13 @@ +data "aws_ami" "atomic_ami" { + filter { + name = "name" + values = ["*CentOS Atomic*1701*"] + } +} + +data "aws_ami" "centos_ami" { + filter { + name = "name" + values = ["*CentOS 7.3.1611*"] + } +} diff --git a/terraform/aws/bastion-aws/instances.tf b/terraform/aws/bastion-aws/instances.tf new file mode 100644 index 0000000..c395b4d --- /dev/null +++ b/terraform/aws/bastion-aws/instances.tf @@ -0,0 +1,30 @@ +# Launch a CentOS 7 instance to serve as bastion host +resource "aws_instance" "bastion" { + ami = "${data.aws_ami.centos_ami.id}" + instance_type = "${var.flavor}" + key_name = "${var.keypair}" + vpc_security_group_ids = ["${aws_security_group.bastion_sg.id}"] + subnet_id = "${aws_subnet.bastion_net.id}" + depends_on = ["aws_internet_gateway.bastion_gw"] + tags { + tool = "terraform" + demo = "bastion-aws" + area = "instances" + } +} + +# Launch a second CentOS instance to serve as a remote host +resource "aws_instance" "remote" { + ami = "${data.aws_ami.centos_ami.id}" + instance_type = "${var.flavor}" + key_name = "${var.keypair}" + vpc_security_group_ids = ["${aws_security_group.remote_sg.id}"] + subnet_id = "${aws_subnet.bastion_net.id}" + depends_on = ["aws_internet_gateway.bastion_gw"] + associate_public_ip_address = false + tags { + tool = "terraform" + demo = "bastion-aws" + area = "instances" + } +} diff --git a/terraform/aws/bastion-aws/networking.tf b/terraform/aws/bastion-aws/networking.tf new file mode 100644 index 0000000..e6af9cc --- /dev/null +++ b/terraform/aws/bastion-aws/networking.tf @@ -0,0 +1,53 @@ +# Create a new VPC +resource "aws_vpc" "bastion_vpc" { + cidr_block = "10.2.0.0/16" + enable_dns_hostnames = "true" + enable_dns_support = "true" + tags { + tool = "terraform" + demo = "bastion-aws" + area = "networking" + } +} + +# Create a public subnet in the new VPC +resource "aws_subnet" "bastion_net" { + vpc_id = "${aws_vpc.bastion_vpc.id}" + cidr_block = "10.2.1.0/24" + map_public_ip_on_launch = "true" + tags { + tool = "terraform" + demo = "bastion-aws" + area = "networking" + } +} + +# Create a new Internet gateway +resource "aws_internet_gateway" "bastion_gw" { + vpc_id = "${aws_vpc.bastion_vpc.id}" + tags { + tool = "terraform" + demo = "bastion-aws" + area = "networking" + } +} + +# Create a route table for the new VPC +resource "aws_route_table" "bastion_routes" { + vpc_id = "${aws_vpc.bastion_vpc.id}" + route { + cidr_block = "0.0.0.0/0" + gateway_id = "${aws_internet_gateway.bastion_gw.id}" + } + tags { + tool = "terraform" + demo = "bastion-aws" + area = "networking" + } +} + +# Associate route table with subnet in VPC +resource "aws_route_table_association" "bastion_rt_assoc" { + subnet_id = "${aws_subnet.bastion_net.id}" + route_table_id = "${aws_route_table.bastion_routes.id}" +} diff --git a/terraform/aws/bastion-aws/output.tf b/terraform/aws/bastion-aws/output.tf new file mode 100644 index 0000000..77da05e --- /dev/null +++ b/terraform/aws/bastion-aws/output.tf @@ -0,0 +1,11 @@ +output "bastion_pub_ip" { + value = ["${aws_instance.bastion.public_ip}"] +} + +output "bastion_priv_ip" { + value = ["${aws_instance.bastion.private_ip}"] +} + +output "remote_priv_ip" { + value = ["${aws_instance.remote.private_ip}"] +} diff --git a/terraform/aws/bastion-aws/provider.tf b/terraform/aws/bastion-aws/provider.tf new file mode 100644 index 0000000..0c28776 --- /dev/null +++ b/terraform/aws/bastion-aws/provider.tf @@ -0,0 +1,3 @@ +provider "aws" { + region = "us-west-2" +} diff --git a/terraform/aws/bastion-aws/security.tf b/terraform/aws/bastion-aws/security.tf new file mode 100644 index 0000000..36ea47f --- /dev/null +++ b/terraform/aws/bastion-aws/security.tf @@ -0,0 +1,59 @@ +# Create a security group to allow web traffic to remote host +resource "aws_security_group" "remote_sg" { + vpc_id = "${aws_vpc.bastion_vpc.id}" + name = "remote-sg" + description = "Security group for web traffic to remote hosts" + ingress { + from_port = "80" + to_port = "80" + protocol = "tcp" + cidr_blocks = ["0.0.0.0/0"] + } + ingress { + from_port = "443" + to_port = "443" + protocol = "tcp" + cidr_blocks = ["0.0.0.0/0"] + } + ingress { + from_port = "22" + to_port = "22" + protocol = "tcp" + cidr_blocks = ["${aws_vpc.bastion_vpc.cidr_block}"] + } + egress { + from_port = "0" + to_port = "0" + protocol = "-1" + cidr_blocks = ["0.0.0.0/0"] + } + tags { + tool = "terraform" + demo = "bastion-aws" + area = "security" + } +} + +# Create a security group to allow inbound SSH (for bastion only) +resource "aws_security_group" "bastion_sg" { + vpc_id = "${aws_vpc.bastion_vpc.id}" + name = "bastion-sg" + description = "Security group for SSH bastion host" + ingress { + from_port = "22" + to_port = "22" + protocol = "tcp" + cidr_blocks = ["0.0.0.0/0"] + } + egress { + from_port = "0" + to_port = "0" + protocol = "-1" + cidr_blocks = ["0.0.0.0/0"] + } + tags { + tool = "terraform" + demo = "bastion-aws" + area = "security" + } +} diff --git a/terraform/aws/bastion-aws/ssh.cfg b/terraform/aws/bastion-aws/ssh.cfg new file mode 100644 index 0000000..4b64dc1 --- /dev/null +++ b/terraform/aws/bastion-aws/ssh.cfg @@ -0,0 +1,12 @@ +Host * + PubkeyAuthentication yes + +Host bastion + Hostname 54.70.95.123 + User ec2-user + IdentityFile ~/.ssh/aws_rsa + +Host 10.2.1.* + User ec2-user + IdentityFile ~/.ssh/aws_rsa + ProxyCommand ssh bastion -W %h:%p diff --git a/terraform/aws/bastion-aws/vars.tf b/terraform/aws/bastion-aws/vars.tf new file mode 100644 index 0000000..a1984a6 --- /dev/null +++ b/terraform/aws/bastion-aws/vars.tf @@ -0,0 +1,11 @@ +variable "keypair" { + type = "string" + description = "AWS SSH keypair to use to connect to instances" + default = "aws_rsa" +} + +variable "flavor" { + type = "string" + description = "AWS type to use when creating instances" + default = "t2.micro" +}