From 44500f14a3e2e5094575e40ed6c92543fc3ba9b6 Mon Sep 17 00:00:00 2001 From: Scott Lowe Date: Thu, 16 Mar 2017 11:15:14 -0600 Subject: [PATCH 1/2] 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" +} From b115a5c624b57a26af167e117a7bde7ca715b011 Mon Sep 17 00:00:00 2001 From: Scott Lowe Date: Tue, 23 May 2017 16:19:56 -0600 Subject: [PATCH 2/2] Commit finalized Terraform configuration Commit finalized Terraform configuration using CentOS and CentOS Atomic Host images for working with an SSH bastion host Signed-off-by: Scott Lowe --- terraform/aws/bastion-aws/data.tf | 16 ++++++++++++++-- terraform/aws/bastion-aws/instances.tf | 12 +++++++----- terraform/aws/bastion-aws/networking.tf | 18 +++++++++++++++--- terraform/aws/bastion-aws/output.tf | 2 +- terraform/aws/bastion-aws/security.tf | 22 +++++----------------- terraform/aws/bastion-aws/vars.tf | 2 -- 6 files changed, 42 insertions(+), 30 deletions(-) diff --git a/terraform/aws/bastion-aws/data.tf b/terraform/aws/bastion-aws/data.tf index 9130a42..8fc86d9 100644 --- a/terraform/aws/bastion-aws/data.tf +++ b/terraform/aws/bastion-aws/data.tf @@ -1,13 +1,25 @@ data "aws_ami" "atomic_ami" { + most_recent = true + owners = ["410186602215"] filter { name = "name" - values = ["*CentOS Atomic*1701*"] + values = ["CentOS Atomic Host 7*"] + } + filter { + name = "virtualization-type" + values = ["hvm"] } } data "aws_ami" "centos_ami" { + most_recent = true + owners = ["410186602215"] filter { name = "name" - values = ["*CentOS 7.3.1611*"] + values = ["CentOS Linux 7*"] + } + filter { + name = "virtualization-type" + values = ["hvm"] } } diff --git a/terraform/aws/bastion-aws/instances.tf b/terraform/aws/bastion-aws/instances.tf index c395b4d..bf8180f 100644 --- a/terraform/aws/bastion-aws/instances.tf +++ b/terraform/aws/bastion-aws/instances.tf @@ -7,22 +7,24 @@ resource "aws_instance" "bastion" { subnet_id = "${aws_subnet.bastion_net.id}" depends_on = ["aws_internet_gateway.bastion_gw"] tags { + Name = "bastion" 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}" +# Launch a CentOS Atomic Host instance to serve as a private host +resource "aws_instance" "private" { + ami = "${data.aws_ami.atomic_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}" + vpc_security_group_ids = ["${aws_security_group.private_sg.id}"] + subnet_id = "${aws_subnet.private_net.id}" depends_on = ["aws_internet_gateway.bastion_gw"] associate_public_ip_address = false tags { + Name = "private" tool = "terraform" demo = "bastion-aws" area = "instances" diff --git a/terraform/aws/bastion-aws/networking.tf b/terraform/aws/bastion-aws/networking.tf index e6af9cc..f2d2813 100644 --- a/terraform/aws/bastion-aws/networking.tf +++ b/terraform/aws/bastion-aws/networking.tf @@ -1,8 +1,8 @@ # Create a new VPC resource "aws_vpc" "bastion_vpc" { cidr_block = "10.2.0.0/16" - enable_dns_hostnames = "true" - enable_dns_support = "true" + enable_dns_hostnames = true + enable_dns_support = true tags { tool = "terraform" demo = "bastion-aws" @@ -14,7 +14,19 @@ resource "aws_vpc" "bastion_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" + map_public_ip_on_launch = true + tags { + tool = "terraform" + demo = "bastion-aws" + area = "networking" + } +} + +# Create a private subnet in the new VPC +resource "aws_subnet" "private_net" { + vpc_id = "${aws_vpc.bastion_vpc.id}" + cidr_block = "10.2.2.0/24" + map_public_ip_on_launch = false tags { tool = "terraform" demo = "bastion-aws" diff --git a/terraform/aws/bastion-aws/output.tf b/terraform/aws/bastion-aws/output.tf index 77da05e..36cad07 100644 --- a/terraform/aws/bastion-aws/output.tf +++ b/terraform/aws/bastion-aws/output.tf @@ -7,5 +7,5 @@ output "bastion_priv_ip" { } output "remote_priv_ip" { - value = ["${aws_instance.remote.private_ip}"] + value = ["${aws_instance.private.private_ip}"] } diff --git a/terraform/aws/bastion-aws/security.tf b/terraform/aws/bastion-aws/security.tf index 36ea47f..e1871fe 100644 --- a/terraform/aws/bastion-aws/security.tf +++ b/terraform/aws/bastion-aws/security.tf @@ -1,25 +1,13 @@ -# Create a security group to allow web traffic to remote host -resource "aws_security_group" "remote_sg" { +# Create a security group to allow SSH traffic to private host(s) only from bastion +resource "aws_security_group" "private_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"] - } + name = "private-sg" + description = "Security group for web traffic to private hosts" ingress { from_port = "22" to_port = "22" protocol = "tcp" - cidr_blocks = ["${aws_vpc.bastion_vpc.cidr_block}"] + cidr_blocks = ["10.2.1.0/24"] } egress { from_port = "0" diff --git a/terraform/aws/bastion-aws/vars.tf b/terraform/aws/bastion-aws/vars.tf index a1984a6..2a32f6e 100644 --- a/terraform/aws/bastion-aws/vars.tf +++ b/terraform/aws/bastion-aws/vars.tf @@ -1,11 +1,9 @@ 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" }