Merge pull request #75 from lowescott/aws-bastion

Add learning environment to show Terraform building an SSH bastion host on AWS
This commit is contained in:
Scott S. Lowe 2017-05-23 16:21:09 -06:00 committed by GitHub
commit 287dee3f1a
8 changed files with 204 additions and 0 deletions

View file

@ -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"]
}
}

View file

@ -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"
}
}

View file

@ -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}"
}

View file

@ -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}"]
}

View file

@ -0,0 +1,3 @@
provider "aws" {
region = "us-west-2"
}

View file

@ -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"
}
}

View file

@ -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

View file

@ -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"
}