diff --git a/terraform/aws/bastion-aws/data.tf b/terraform/aws/bastion-aws/data.tf new file mode 100644 index 0000000..8fc86d9 --- /dev/null +++ b/terraform/aws/bastion-aws/data.tf @@ -0,0 +1,25 @@ +data "aws_ami" "atomic_ami" { + most_recent = true + owners = ["410186602215"] + filter { + name = "name" + 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 Linux 7*"] + } + filter { + name = "virtualization-type" + values = ["hvm"] + } +} diff --git a/terraform/aws/bastion-aws/instances.tf b/terraform/aws/bastion-aws/instances.tf new file mode 100644 index 0000000..bf8180f --- /dev/null +++ b/terraform/aws/bastion-aws/instances.tf @@ -0,0 +1,32 @@ +# 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 { + Name = "bastion" + tool = "terraform" + demo = "bastion-aws" + area = "instances" + } +} + +# 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.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 new file mode 100644 index 0000000..f2d2813 --- /dev/null +++ b/terraform/aws/bastion-aws/networking.tf @@ -0,0 +1,65 @@ +# 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 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" + 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..36cad07 --- /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.private.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..e1871fe --- /dev/null +++ b/terraform/aws/bastion-aws/security.tf @@ -0,0 +1,47 @@ +# 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 = "private-sg" + description = "Security group for web traffic to private hosts" + ingress { + from_port = "22" + to_port = "22" + protocol = "tcp" + cidr_blocks = ["10.2.1.0/24"] + } + 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..2a32f6e --- /dev/null +++ b/terraform/aws/bastion-aws/vars.tf @@ -0,0 +1,9 @@ +variable "keypair" { + type = "string" + description = "AWS SSH keypair to use to connect to instances" +} + +variable "flavor" { + type = "string" + description = "AWS type to use when creating instances" +}