Explorar el Código

Initial Commit - Working with ubuntu

Fred Damstra hace 8 años
commit
08f6741c95

+ 29 - 0
SingleWeb/AWS_AMI_MAPS.j

@@ -0,0 +1,29 @@
+{% import 'variables.include' as var %}
+#############
+# New method: Search for it!
+data "aws_ami" "ubuntu" {
+  most_recent = true
+  filter {
+    name = "name"
+    values = ["ubuntu/images/hvm-ssd/ubuntu-xenial-16.04-amd64-server-*"]
+  }
+  filter {
+    name = "virtualization-type"
+    values = ["hvm"]
+  }
+  owners = ["099720109477"] # Canonical
+}
+# Use via: ami = "${data.aws_ami.ubuntu.id}"
+
+
+#############
+# Old fashioned method, manual mapping:
+variable "ubuntu_amis" {
+  type = "map"
+  default = {
+    us-east-1 = "ami-40d28157"
+    us-east-2 = "ami-153e6470"
+  }
+}
+# Use with: ami = "${lookup(var.ubuntu_amis, var.region)}"
+

+ 36 - 0
SingleWeb/AWS_AMI_MAPS.tf

@@ -0,0 +1,36 @@
+###############################################
+# DO NOT EDIT THIS FILE
+#
+# This file is generated through 'make all'. 
+# If you need to make changes, make your changes
+# to the corresponding .j file and then rerun
+# make all
+###############################################
+
+#############
+# New method: Search for it!
+data "aws_ami" "ubuntu" {
+  most_recent = true
+  filter {
+    name = "name"
+    values = ["ubuntu/images/hvm-ssd/ubuntu-xenial-16.04-amd64-server-*"]
+  }
+  filter {
+    name = "virtualization-type"
+    values = ["hvm"]
+  }
+  owners = ["099720109477"] # Canonical
+}
+# Use via: ami = "${data.aws_ami.ubuntu.id}"
+
+
+#############
+# Old fashioned method, manual mapping:
+variable "ubuntu_amis" {
+  type = "map"
+  default = {
+    us-east-1 = "ami-40d28157"
+    us-east-2 = "ami-153e6470"
+  }
+}
+# Use with: ami = "${lookup(var.ubuntu_amis, var.region)}"

+ 29 - 0
SingleWeb/Makefile

@@ -0,0 +1,29 @@
+######
+# Jinja Compiler
+#   Should specify a filename, and output processed text
+#J2=j2
+J2=python ../bin/jj2.py
+
+# Additional j2 flags
+J2FLAGS=
+
+# Targets
+TFTARGETS=variables.tf vpcs_and_subnets.tf z_nextsteps.tf security.tf webserver.tf provider.tf network_acl.tf AWS_AMI_MAPS.tf
+SHTARGETS=
+SOURCES=$(TFTARGETS:.tf=.j)
+
+all: $(TFTARGETS) $(SHTARGETS)
+
+%.tf: %.j ../banner.txt variables.include
+	$(J2) $(J2FLAGS) $< -o $@.tmp
+	cat ../banner.txt $@.tmp > $@
+	rm $@.tmp
+
+%.sh: %.j variables.include
+	$(J2) $(J2FLAGS) $< -o $@
+	chmod 755 $@
+
+clean:
+	-terraform destroy
+	-rm $(TFTARGETS)  $(SHTARGETS)
+	-rm *.tmp

+ 90 - 0
SingleWeb/network_acl.j

@@ -0,0 +1,90 @@
+{% import 'variables.include' as var %}
+##########
+# Network ACLs enforce the basic rules of the topology, and are
+# further refined by security groups on instances.
+#
+# Topology has two "public" subnets (in different AZs) for 
+# servers such as searchheads and HECs that are accessible publicly.
+#
+# It was two "private" subnets (in different AZs) for
+# servers such as indexers that aren't publicly available.
+#
+# The two AZ's can talk to each other.
+# The public subnets can be accessed by any service/source
+#   allowed by the security group.
+# The private subnets are only accessible by the public
+#   subnets, and port 22 from anywhere.
+#
+# Network ACLs allow all outbound. This should be restricted
+# via security groups to only those ports needed.
+resource "aws_network_acl" "acl_public" {
+    vpc_id = "${aws_vpc.vpc_primary.id}"
+    subnet_ids = ["${aws_subnet.subnet_public_a.id}"]
+    egress {
+        protocol = "-1"
+        rule_no = 10
+        action = "allow"
+        cidr_block =  "0.0.0.0/0"
+        from_port = 0
+        to_port = 0
+    }
+
+    ingress {
+        protocol = "-1"
+        rule_no = 10
+        action = "allow"
+        cidr_block =  "0.0.0.0/0"
+        from_port = 0
+        to_port = 0
+    }
+
+    tags {
+        Name = "Public Subnets"
+    }
+}
+
+#resource "aws_network_acl" "acl_private" {
+#    vpc_id = "${aws_vpc.vpc_primary.id}"
+#    subnet_ids = ["${aws_subnet.subnet_private_a.id}", "${aws_subnet.subnet_private_b.id}"]
+#    egress {
+#        protocol = "-1"
+#        rule_no = 10
+#        action = "allow"
+#        cidr_block =  "0.0.0.0/0"
+#        from_port = 0
+#        to_port = 0
+#    }
+#
+#    ingress {
+#        protocol = "-1"
+#        rule_no = 10
+#        action = "allow"
+#        cidr_block =  "${var.VPC-Subnet}"
+#        from_port = 0
+#        to_port = 0
+#    }
+#
+#    ingress {
+#        protocol = "icmp"
+#        rule_no = 20
+#        action = "allow"
+#        cidr_block =  "0.0.0.0/0"
+#        icmp_type = 8
+#        from_port = 0
+#        to_port = 0
+#    }
+#
+#    ingress {
+#        protocol = "tcp"
+#        rule_no = 30
+#        action = "allow"
+#        cidr_block =  "0.0.0.0/0"
+#        from_port = 22
+#        to_port = 22
+#    }
+#
+#    tags {
+#        Name = "Private Subnets"
+#    }
+#}
+#

+ 98 - 0
SingleWeb/network_acl.tf

@@ -0,0 +1,98 @@
+###############################################
+# DO NOT EDIT THIS FILE
+#
+# This file is generated through 'make all'. 
+# If you need to make changes, make your changes
+# to the corresponding .j file and then rerun
+# make all
+###############################################
+
+##########
+# Network ACLs enforce the basic rules of the topology, and are
+# further refined by security groups on instances.
+#
+# Topology has two "public" subnets (in different AZs) for 
+# servers such as searchheads and HECs that are accessible publicly.
+#
+# It was two "private" subnets (in different AZs) for
+# servers such as indexers that aren't publicly available.
+#
+# The two AZ's can talk to each other.
+# The public subnets can be accessed by any service/source
+#   allowed by the security group.
+# The private subnets are only accessible by the public
+#   subnets, and port 22 from anywhere.
+#
+# Network ACLs allow all outbound. This should be restricted
+# via security groups to only those ports needed.
+resource "aws_network_acl" "acl_public" {
+    vpc_id = "${aws_vpc.vpc_primary.id}"
+    subnet_ids = ["${aws_subnet.subnet_public_a.id}"]
+    egress {
+        protocol = "-1"
+        rule_no = 10
+        action = "allow"
+        cidr_block =  "0.0.0.0/0"
+        from_port = 0
+        to_port = 0
+    }
+
+    ingress {
+        protocol = "-1"
+        rule_no = 10
+        action = "allow"
+        cidr_block =  "0.0.0.0/0"
+        from_port = 0
+        to_port = 0
+    }
+
+    tags {
+        Name = "Public Subnets"
+    }
+}
+
+#resource "aws_network_acl" "acl_private" {
+#    vpc_id = "${aws_vpc.vpc_primary.id}"
+#    subnet_ids = ["${aws_subnet.subnet_private_a.id}", "${aws_subnet.subnet_private_b.id}"]
+#    egress {
+#        protocol = "-1"
+#        rule_no = 10
+#        action = "allow"
+#        cidr_block =  "0.0.0.0/0"
+#        from_port = 0
+#        to_port = 0
+#    }
+#
+#    ingress {
+#        protocol = "-1"
+#        rule_no = 10
+#        action = "allow"
+#        cidr_block =  "${var.VPC-Subnet}"
+#        from_port = 0
+#        to_port = 0
+#    }
+#
+#    ingress {
+#        protocol = "icmp"
+#        rule_no = 20
+#        action = "allow"
+#        cidr_block =  "0.0.0.0/0"
+#        icmp_type = 8
+#        from_port = 0
+#        to_port = 0
+#    }
+#
+#    ingress {
+#        protocol = "tcp"
+#        rule_no = 30
+#        action = "allow"
+#        cidr_block =  "0.0.0.0/0"
+#        from_port = 22
+#        to_port = 22
+#    }
+#
+#    tags {
+#        Name = "Private Subnets"
+#    }
+#}
+#

+ 9 - 0
SingleWeb/provider.j

@@ -0,0 +1,9 @@
+{% import 'variables.include' as var %}
+# Set a provider for the region
+provider "aws" {
+# Provided by shared crednentials file
+#  access_key = "${var.access_key}"
+#  secret_key = "${var.secret_key}"
+  region     = "${var.region}"
+}
+

+ 16 - 0
SingleWeb/provider.tf

@@ -0,0 +1,16 @@
+###############################################
+# DO NOT EDIT THIS FILE
+#
+# This file is generated through 'make all'. 
+# If you need to make changes, make your changes
+# to the corresponding .j file and then rerun
+# make all
+###############################################
+
+# Set a provider for the region
+provider "aws" {
+# Provided by shared crednentials file
+#  access_key = "${var.access_key}"
+#  secret_key = "${var.secret_key}"
+  region     = "${var.region}"
+}

+ 67 - 0
SingleWeb/security.j

@@ -0,0 +1,67 @@
+{% import 'variables.include' as var %}
+#######
+# A security group for the ELB so it is accessible via the web
+resource "aws_security_group" "sg_instance_access" {
+  name        = "sg_instance_access"
+  description = "Allows ssh/http/https in from me. Allows outbound on select ports."
+  vpc_id      = "${aws_vpc.vpc_primary.id}"
+
+  # SSH, HTTP, and HTTPS inbound from me
+  ingress {
+    from_port = 22
+    to_port = 22
+    protocol = "tcp"
+    cidr_blocks = "${var.Trusted-CIDR}"
+  }
+  ingress {
+    from_port = 80
+    to_port = 80
+    protocol = "tcp"
+    cidr_blocks = "${var.Trusted-CIDR}"
+  }
+  ingress {
+    from_port = 443
+    to_port = 443
+    protocol = "tcp"
+    cidr_blocks = "${var.Trusted-CIDR}"
+  }
+
+  # Outbound Access
+  egress {
+    from_port = 20
+    to_port = 21
+    protocol = "tcp"
+    cidr_blocks = ["0.0.0.0/0"]
+  }
+  egress {
+    from_port = 22
+    to_port = 22
+    protocol = "tcp"
+    cidr_blocks = ["0.0.0.0/0"]
+  }
+  egress {
+    from_port = 53
+    to_port = 53
+    protocol = "tcp"
+    cidr_blocks = ["0.0.0.0/0"]
+  }
+  egress {
+    from_port = 53
+    to_port = 53
+    protocol = "udp"
+    cidr_blocks = ["0.0.0.0/0"]
+  }
+  egress {
+    from_port = 80
+    to_port = 80
+    protocol = "tcp"
+    cidr_blocks = ["0.0.0.0/0"]
+  }
+  egress {
+    from_port = 443
+    to_port = 443
+    protocol = "tcp"
+    cidr_blocks = ["0.0.0.0/0"]
+  }
+}
+

+ 74 - 0
SingleWeb/security.tf

@@ -0,0 +1,74 @@
+###############################################
+# DO NOT EDIT THIS FILE
+#
+# This file is generated through 'make all'. 
+# If you need to make changes, make your changes
+# to the corresponding .j file and then rerun
+# make all
+###############################################
+
+#######
+# A security group for the ELB so it is accessible via the web
+resource "aws_security_group" "sg_instance_access" {
+  name        = "sg_instance_access"
+  description = "Allows ssh/http/https in from me. Allows outbound on select ports."
+  vpc_id      = "${aws_vpc.vpc_primary.id}"
+
+  # SSH, HTTP, and HTTPS inbound from me
+  ingress {
+    from_port = 22
+    to_port = 22
+    protocol = "tcp"
+    cidr_blocks = "${var.Trusted-CIDR}"
+  }
+  ingress {
+    from_port = 80
+    to_port = 80
+    protocol = "tcp"
+    cidr_blocks = "${var.Trusted-CIDR}"
+  }
+  ingress {
+    from_port = 443
+    to_port = 443
+    protocol = "tcp"
+    cidr_blocks = "${var.Trusted-CIDR}"
+  }
+
+  # Outbound Access
+  egress {
+    from_port = 20
+    to_port = 21
+    protocol = "tcp"
+    cidr_blocks = ["0.0.0.0/0"]
+  }
+  egress {
+    from_port = 22
+    to_port = 22
+    protocol = "tcp"
+    cidr_blocks = ["0.0.0.0/0"]
+  }
+  egress {
+    from_port = 53
+    to_port = 53
+    protocol = "tcp"
+    cidr_blocks = ["0.0.0.0/0"]
+  }
+  egress {
+    from_port = 53
+    to_port = 53
+    protocol = "udp"
+    cidr_blocks = ["0.0.0.0/0"]
+  }
+  egress {
+    from_port = 80
+    to_port = 80
+    protocol = "tcp"
+    cidr_blocks = ["0.0.0.0/0"]
+  }
+  egress {
+    from_port = 443
+    to_port = 443
+    protocol = "tcp"
+    cidr_blocks = ["0.0.0.0/0"]
+  }
+}

+ 22 - 0
SingleWeb/terraform.tfstate

@@ -0,0 +1,22 @@
+{
+    "version": 3,
+    "terraform_version": "0.7.11",
+    "serial": 1,
+    "lineage": "8872a594-44c9-4a47-9fbb-0fe7eedba393",
+    "modules": [
+        {
+            "path": [
+                "root"
+            ],
+            "outputs": {
+                "NEXT-STEPS": {
+                    "sensitive": false,
+                    "type": "string",
+                    "value": "Enjoy!\n"
+                }
+            },
+            "resources": {},
+            "depends_on": []
+        }
+    ]
+}

+ 477 - 0
SingleWeb/terraform.tfstate.backup

@@ -0,0 +1,477 @@
+{
+    "version": 3,
+    "terraform_version": "0.7.11",
+    "serial": 0,
+    "lineage": "8872a594-44c9-4a47-9fbb-0fe7eedba393",
+    "modules": [
+        {
+            "path": [
+                "root"
+            ],
+            "outputs": {
+                "NEXT-STEPS": {
+                    "sensitive": false,
+                    "type": "string",
+                    "value": "Enjoy!\n"
+                },
+                "webserver_dns": {
+                    "sensitive": false,
+                    "type": "string",
+                    "value": "webserver.lab.monkeybox.org"
+                },
+                "webserver_ip": {
+                    "sensitive": false,
+                    "type": "string",
+                    "value": "52.14.198.57"
+                }
+            },
+            "resources": {
+                "aws_instance.webserver": {
+                    "type": "aws_instance",
+                    "depends_on": [
+                        "aws_internet_gateway.gw_primary",
+                        "aws_security_group.sg_instance_access",
+                        "aws_subnet.subnet_public_a",
+                        "data.aws_ami.ubuntu",
+                        "data.aws_availability_zones.available"
+                    ],
+                    "primary": {
+                        "id": "i-02893fac410d02c03",
+                        "attributes": {
+                            "ami": "ami-17745072",
+                            "associate_public_ip_address": "true",
+                            "availability_zone": "us-east-2a",
+                            "disable_api_termination": "false",
+                            "ebs_block_device.#": "1",
+                            "ebs_block_device.2634515331.delete_on_termination": "true",
+                            "ebs_block_device.2634515331.device_name": "/dev/sdd",
+                            "ebs_block_device.2634515331.encrypted": "false",
+                            "ebs_block_device.2634515331.iops": "100",
+                            "ebs_block_device.2634515331.snapshot_id": "",
+                            "ebs_block_device.2634515331.volume_size": "2",
+                            "ebs_block_device.2634515331.volume_type": "gp2",
+                            "ebs_optimized": "false",
+                            "ephemeral_block_device.#": "0",
+                            "iam_instance_profile": "",
+                            "id": "i-02893fac410d02c03",
+                            "instance_initiated_shutdown_behavior": "terminate",
+                            "instance_state": "running",
+                            "instance_type": "t2.micro",
+                            "key_name": "Fred-IO",
+                            "monitoring": "false",
+                            "network_interface_id": "eni-186bc870",
+                            "private_dns": "ip-10-45-0-247.us-east-2.compute.internal",
+                            "private_ip": "10.45.0.247",
+                            "public_dns": "ec2-52-14-198-57.us-east-2.compute.amazonaws.com",
+                            "public_ip": "52.14.198.57",
+                            "root_block_device.#": "1",
+                            "root_block_device.0.delete_on_termination": "true",
+                            "root_block_device.0.iops": "0",
+                            "root_block_device.0.volume_size": "20",
+                            "root_block_device.0.volume_type": "standard",
+                            "security_groups.#": "0",
+                            "source_dest_check": "true",
+                            "subnet_id": "subnet-cd6be5a4",
+                            "tags.%": "1",
+                            "tags.Name": "webserver",
+                            "tenancy": "default",
+                            "user_data": "93a4fa92ca68fd32558a63738d772c9c424129fe",
+                            "vpc_security_group_ids.#": "1",
+                            "vpc_security_group_ids.3524806094": "sg-4dabc124"
+                        },
+                        "meta": {
+                            "schema_version": "1"
+                        },
+                        "tainted": false
+                    },
+                    "deposed": [],
+                    "provider": ""
+                },
+                "aws_internet_gateway.gw_primary": {
+                    "type": "aws_internet_gateway",
+                    "depends_on": [
+                        "aws_vpc.vpc_primary"
+                    ],
+                    "primary": {
+                        "id": "igw-b7a204de",
+                        "attributes": {
+                            "id": "igw-b7a204de",
+                            "tags.%": "1",
+                            "tags.Name": "Primary Gateway",
+                            "vpc_id": "vpc-9b3089f2"
+                        },
+                        "meta": {},
+                        "tainted": false
+                    },
+                    "deposed": [],
+                    "provider": ""
+                },
+                "aws_network_acl.acl_public": {
+                    "type": "aws_network_acl",
+                    "depends_on": [
+                        "aws_subnet.subnet_public_a",
+                        "aws_vpc.vpc_primary"
+                    ],
+                    "primary": {
+                        "id": "acl-4532b52c",
+                        "attributes": {
+                            "egress.#": "1",
+                            "egress.57423372.action": "allow",
+                            "egress.57423372.cidr_block": "0.0.0.0/0",
+                            "egress.57423372.from_port": "0",
+                            "egress.57423372.icmp_code": "0",
+                            "egress.57423372.icmp_type": "0",
+                            "egress.57423372.protocol": "-1",
+                            "egress.57423372.rule_no": "10",
+                            "egress.57423372.to_port": "0",
+                            "id": "acl-4532b52c",
+                            "ingress.#": "1",
+                            "ingress.57423372.action": "allow",
+                            "ingress.57423372.cidr_block": "0.0.0.0/0",
+                            "ingress.57423372.from_port": "0",
+                            "ingress.57423372.icmp_code": "0",
+                            "ingress.57423372.icmp_type": "0",
+                            "ingress.57423372.protocol": "-1",
+                            "ingress.57423372.rule_no": "10",
+                            "ingress.57423372.to_port": "0",
+                            "subnet_ids.#": "1",
+                            "subnet_ids.3475719519": "subnet-cd6be5a4",
+                            "tags.%": "1",
+                            "tags.Name": "Public Subnets",
+                            "vpc_id": "vpc-9b3089f2"
+                        },
+                        "meta": {},
+                        "tainted": false
+                    },
+                    "deposed": [],
+                    "provider": ""
+                },
+                "aws_route53_record.webserver": {
+                    "type": "aws_route53_record",
+                    "depends_on": [
+                        "aws_instance.webserver"
+                    ],
+                    "primary": {
+                        "id": "Z49JKEQC08KW8_webserver.lab.monkeybox.org_A",
+                        "attributes": {
+                            "fqdn": "webserver.lab.monkeybox.org",
+                            "health_check_id": "",
+                            "id": "Z49JKEQC08KW8_webserver.lab.monkeybox.org_A",
+                            "name": "webserver.lab.monkeybox.org",
+                            "records.#": "1",
+                            "records.257253360": "52.14.198.57",
+                            "set_identifier": "",
+                            "ttl": "300",
+                            "type": "A",
+                            "zone_id": "Z49JKEQC08KW8"
+                        },
+                        "meta": {
+                            "schema_version": "2"
+                        },
+                        "tainted": false
+                    },
+                    "deposed": [],
+                    "provider": ""
+                },
+                "aws_route53_record.webserver_pvt": {
+                    "type": "aws_route53_record",
+                    "depends_on": [
+                        "aws_instance.webserver"
+                    ],
+                    "primary": {
+                        "id": "Z49JKEQC08KW8_webserver_pvt.lab.monkeybox.org_A",
+                        "attributes": {
+                            "fqdn": "webserver_pvt.lab.monkeybox.org",
+                            "health_check_id": "",
+                            "id": "Z49JKEQC08KW8_webserver_pvt.lab.monkeybox.org_A",
+                            "name": "webserver_pvt.lab.monkeybox.org",
+                            "records.#": "1",
+                            "records.2741848704": "10.45.0.247",
+                            "set_identifier": "",
+                            "ttl": "300",
+                            "type": "A",
+                            "zone_id": "Z49JKEQC08KW8"
+                        },
+                        "meta": {
+                            "schema_version": "2"
+                        },
+                        "tainted": false
+                    },
+                    "deposed": [],
+                    "provider": ""
+                },
+                "aws_route_table.r": {
+                    "type": "aws_route_table",
+                    "depends_on": [
+                        "aws_internet_gateway.gw_primary",
+                        "aws_vpc.vpc_primary"
+                    ],
+                    "primary": {
+                        "id": "rtb-61159508",
+                        "attributes": {
+                            "id": "rtb-61159508",
+                            "propagating_vgws.#": "0",
+                            "route.#": "1",
+                            "route.4239502296.cidr_block": "0.0.0.0/0",
+                            "route.4239502296.gateway_id": "igw-b7a204de",
+                            "route.4239502296.instance_id": "",
+                            "route.4239502296.nat_gateway_id": "",
+                            "route.4239502296.network_interface_id": "",
+                            "route.4239502296.vpc_peering_connection_id": "",
+                            "tags.%": "1",
+                            "tags.Name": "Primary Route Table",
+                            "vpc_id": "vpc-9b3089f2"
+                        },
+                        "meta": {},
+                        "tainted": false
+                    },
+                    "deposed": [],
+                    "provider": ""
+                },
+                "aws_route_table_association.rt_public_a": {
+                    "type": "aws_route_table_association",
+                    "depends_on": [
+                        "aws_route_table.r",
+                        "aws_subnet.subnet_public_a"
+                    ],
+                    "primary": {
+                        "id": "rtbassoc-de1c7cb7",
+                        "attributes": {
+                            "id": "rtbassoc-de1c7cb7",
+                            "route_table_id": "rtb-61159508",
+                            "subnet_id": "subnet-cd6be5a4"
+                        },
+                        "meta": {},
+                        "tainted": false
+                    },
+                    "deposed": [],
+                    "provider": ""
+                },
+                "aws_security_group.sg_instance_access": {
+                    "type": "aws_security_group",
+                    "depends_on": [
+                        "aws_vpc.vpc_primary"
+                    ],
+                    "primary": {
+                        "id": "sg-4dabc124",
+                        "attributes": {
+                            "description": "Allows ssh/http/https in from me. Allows outbound on select ports.",
+                            "egress.#": "6",
+                            "egress.1046858579.cidr_blocks.#": "1",
+                            "egress.1046858579.cidr_blocks.0": "0.0.0.0/0",
+                            "egress.1046858579.from_port": "20",
+                            "egress.1046858579.prefix_list_ids.#": "0",
+                            "egress.1046858579.protocol": "tcp",
+                            "egress.1046858579.security_groups.#": "0",
+                            "egress.1046858579.self": "false",
+                            "egress.1046858579.to_port": "21",
+                            "egress.2214680975.cidr_blocks.#": "1",
+                            "egress.2214680975.cidr_blocks.0": "0.0.0.0/0",
+                            "egress.2214680975.from_port": "80",
+                            "egress.2214680975.prefix_list_ids.#": "0",
+                            "egress.2214680975.protocol": "tcp",
+                            "egress.2214680975.security_groups.#": "0",
+                            "egress.2214680975.self": "false",
+                            "egress.2214680975.to_port": "80",
+                            "egress.2342672136.cidr_blocks.#": "1",
+                            "egress.2342672136.cidr_blocks.0": "0.0.0.0/0",
+                            "egress.2342672136.from_port": "53",
+                            "egress.2342672136.prefix_list_ids.#": "0",
+                            "egress.2342672136.protocol": "tcp",
+                            "egress.2342672136.security_groups.#": "0",
+                            "egress.2342672136.self": "false",
+                            "egress.2342672136.to_port": "53",
+                            "egress.2541437006.cidr_blocks.#": "1",
+                            "egress.2541437006.cidr_blocks.0": "0.0.0.0/0",
+                            "egress.2541437006.from_port": "22",
+                            "egress.2541437006.prefix_list_ids.#": "0",
+                            "egress.2541437006.protocol": "tcp",
+                            "egress.2541437006.security_groups.#": "0",
+                            "egress.2541437006.self": "false",
+                            "egress.2541437006.to_port": "22",
+                            "egress.2617001939.cidr_blocks.#": "1",
+                            "egress.2617001939.cidr_blocks.0": "0.0.0.0/0",
+                            "egress.2617001939.from_port": "443",
+                            "egress.2617001939.prefix_list_ids.#": "0",
+                            "egress.2617001939.protocol": "tcp",
+                            "egress.2617001939.security_groups.#": "0",
+                            "egress.2617001939.self": "false",
+                            "egress.2617001939.to_port": "443",
+                            "egress.2767972101.cidr_blocks.#": "1",
+                            "egress.2767972101.cidr_blocks.0": "0.0.0.0/0",
+                            "egress.2767972101.from_port": "53",
+                            "egress.2767972101.prefix_list_ids.#": "0",
+                            "egress.2767972101.protocol": "udp",
+                            "egress.2767972101.security_groups.#": "0",
+                            "egress.2767972101.self": "false",
+                            "egress.2767972101.to_port": "53",
+                            "id": "sg-4dabc124",
+                            "ingress.#": "3",
+                            "ingress.1232989320.cidr_blocks.#": "2",
+                            "ingress.1232989320.cidr_blocks.0": "98.243.254.99/32",
+                            "ingress.1232989320.cidr_blocks.1": "107.135.34.113/32",
+                            "ingress.1232989320.from_port": "443",
+                            "ingress.1232989320.protocol": "tcp",
+                            "ingress.1232989320.security_groups.#": "0",
+                            "ingress.1232989320.self": "false",
+                            "ingress.1232989320.to_port": "443",
+                            "ingress.1739234222.cidr_blocks.#": "2",
+                            "ingress.1739234222.cidr_blocks.0": "98.243.254.99/32",
+                            "ingress.1739234222.cidr_blocks.1": "107.135.34.113/32",
+                            "ingress.1739234222.from_port": "22",
+                            "ingress.1739234222.protocol": "tcp",
+                            "ingress.1739234222.security_groups.#": "0",
+                            "ingress.1739234222.self": "false",
+                            "ingress.1739234222.to_port": "22",
+                            "ingress.2207802212.cidr_blocks.#": "2",
+                            "ingress.2207802212.cidr_blocks.0": "98.243.254.99/32",
+                            "ingress.2207802212.cidr_blocks.1": "107.135.34.113/32",
+                            "ingress.2207802212.from_port": "80",
+                            "ingress.2207802212.protocol": "tcp",
+                            "ingress.2207802212.security_groups.#": "0",
+                            "ingress.2207802212.self": "false",
+                            "ingress.2207802212.to_port": "80",
+                            "name": "sg_instance_access",
+                            "owner_id": "082012130604",
+                            "tags.%": "0",
+                            "vpc_id": "vpc-9b3089f2"
+                        },
+                        "meta": {},
+                        "tainted": false
+                    },
+                    "deposed": [],
+                    "provider": ""
+                },
+                "aws_subnet.subnet_public_a": {
+                    "type": "aws_subnet",
+                    "depends_on": [
+                        "aws_vpc.vpc_primary",
+                        "data.aws_availability_zones.available"
+                    ],
+                    "primary": {
+                        "id": "subnet-cd6be5a4",
+                        "attributes": {
+                            "availability_zone": "us-east-2a",
+                            "cidr_block": "10.45.0.0/24",
+                            "id": "subnet-cd6be5a4",
+                            "map_public_ip_on_launch": "true",
+                            "tags.%": "1",
+                            "tags.Name": "Public Subnet A",
+                            "vpc_id": "vpc-9b3089f2"
+                        },
+                        "meta": {},
+                        "tainted": false
+                    },
+                    "deposed": [],
+                    "provider": ""
+                },
+                "aws_vpc.vpc_primary": {
+                    "type": "aws_vpc",
+                    "depends_on": [],
+                    "primary": {
+                        "id": "vpc-9b3089f2",
+                        "attributes": {
+                            "cidr_block": "10.45.0.0/16",
+                            "default_network_acl_id": "acl-9132b5f8",
+                            "default_route_table_id": "rtb-811696e8",
+                            "default_security_group_id": "sg-91513bf8",
+                            "dhcp_options_id": "dopt-50af4539",
+                            "enable_dns_hostnames": "true",
+                            "enable_dns_support": "true",
+                            "id": "vpc-9b3089f2",
+                            "instance_tenancy": "default",
+                            "main_route_table_id": "rtb-811696e8",
+                            "tags.%": "1",
+                            "tags.Name": "Primary VPC"
+                        },
+                        "meta": {},
+                        "tainted": false
+                    },
+                    "deposed": [],
+                    "provider": ""
+                },
+                "data.aws_ami.ubuntu": {
+                    "type": "aws_ami",
+                    "depends_on": [],
+                    "primary": {
+                        "id": "ami-17745072",
+                        "attributes": {
+                            "architecture": "x86_64",
+                            "block_device_mappings.#": "3",
+                            "block_device_mappings.1634610537.device_name": "/dev/sdb",
+                            "block_device_mappings.1634610537.ebs.%": "0",
+                            "block_device_mappings.1634610537.no_device": "",
+                            "block_device_mappings.1634610537.virtual_name": "ephemeral0",
+                            "block_device_mappings.2547816212.device_name": "/dev/sda1",
+                            "block_device_mappings.2547816212.ebs.%": "6",
+                            "block_device_mappings.2547816212.ebs.delete_on_termination": "true",
+                            "block_device_mappings.2547816212.ebs.encrypted": "false",
+                            "block_device_mappings.2547816212.ebs.iops": "0",
+                            "block_device_mappings.2547816212.ebs.snapshot_id": "snap-cb4f9d3a",
+                            "block_device_mappings.2547816212.ebs.volume_size": "8",
+                            "block_device_mappings.2547816212.ebs.volume_type": "gp2",
+                            "block_device_mappings.2547816212.no_device": "",
+                            "block_device_mappings.2547816212.virtual_name": "",
+                            "block_device_mappings.3850042718.device_name": "/dev/sdc",
+                            "block_device_mappings.3850042718.ebs.%": "0",
+                            "block_device_mappings.3850042718.no_device": "",
+                            "block_device_mappings.3850042718.virtual_name": "ephemeral1",
+                            "creation_date": "2017-03-09T08:54:19.000Z",
+                            "filter.#": "2",
+                            "filter.1585153008.name": "name",
+                            "filter.1585153008.values.#": "1",
+                            "filter.1585153008.values.0": "ubuntu/images/hvm-ssd/ubuntu-xenial-16.04-amd64-server-*",
+                            "filter.490168357.name": "virtualization-type",
+                            "filter.490168357.values.#": "1",
+                            "filter.490168357.values.0": "hvm",
+                            "hypervisor": "xen",
+                            "id": "ami-17745072",
+                            "image_id": "ami-17745072",
+                            "image_location": "099720109477/ubuntu/images/hvm-ssd/ubuntu-xenial-16.04-amd64-server-20170224",
+                            "image_type": "machine",
+                            "most_recent": "true",
+                            "name": "ubuntu/images/hvm-ssd/ubuntu-xenial-16.04-amd64-server-20170224",
+                            "owner_id": "099720109477",
+                            "owners.#": "1",
+                            "owners.0": "099720109477",
+                            "product_codes.#": "0",
+                            "public": "true",
+                            "root_device_name": "/dev/sda1",
+                            "root_device_type": "ebs",
+                            "sriov_net_support": "simple",
+                            "state": "available",
+                            "state_reason.%": "2",
+                            "state_reason.code": "UNSET",
+                            "state_reason.message": "UNSET",
+                            "tags.#": "0",
+                            "virtualization_type": "hvm"
+                        },
+                        "meta": {},
+                        "tainted": false
+                    },
+                    "deposed": [],
+                    "provider": ""
+                },
+                "data.aws_availability_zones.available": {
+                    "type": "aws_availability_zones",
+                    "depends_on": [],
+                    "primary": {
+                        "id": "2017-03-27 17:28:32.670455577 +0000 UTC",
+                        "attributes": {
+                            "id": "2017-03-27 17:28:32.670455577 +0000 UTC",
+                            "names.#": "3",
+                            "names.0": "us-east-2a",
+                            "names.1": "us-east-2b",
+                            "names.2": "us-east-2c"
+                        },
+                        "meta": {},
+                        "tainted": false
+                    },
+                    "deposed": [],
+                    "provider": ""
+                }
+            },
+            "depends_on": []
+        }
+    ]
+}

+ 1 - 0
SingleWeb/variables.include

@@ -0,0 +1 @@
+../variables.include

+ 109 - 0
SingleWeb/variables.j

@@ -0,0 +1,109 @@
+{% import 'variables.include' as var %}
+# User Settings
+# -------------
+# These MUST be configured
+variable "AWS-Key-Pair-Name" {
+  description = "Name of the keypair in AWS"
+  type = "string"
+  default = "{{ var.AWS_Key_Pair_Name }}"
+}
+
+variable "Private-Key-File" {
+  description = "The name of the file containing your private key"
+  type = "string"
+  default = "{{ var.Private_Key_File }}"
+}
+
+variable "Domain-Name" {
+  description = "Your domain name (hosted in Route53)"
+  type = "string"
+  default = "{{ var.Domain_Name }}"
+}
+
+variable "Domain-Zone-ID" {
+  description = "The Zone ID of the Domain-Name in Route53"
+  type = "string"
+  default = "{{ var.Domain_Zone_ID }}"
+}
+
+variable "Trusted-CIDR" {
+  description = "Trusted source addresses in CIDR notation."
+  type = "list"
+  default =  {{ var.Trusted_CIDR }}
+}
+
+# Common Settings
+# ---------------
+# You may wish to customize these, but defaults
+# will usually work.
+variable "region" {
+  description = "Which AWS region do you wish to deploy to?"
+  type = "string"
+  default = "{{ var.AWS_Region }}"
+}
+
+variable "VPC-Subnet" {
+  description = "The full subnet for your VPC (to be split into 4 subnets)"
+  type = "string"
+  default = "10.45.0.0/16"
+}
+
+variable "Public-Subnet-A" {
+  description = "The CIDR for the PubA subnet. Must be a subnet of VPC-Subnet"
+  type = "string"
+  default = "10.45.0.0/24"
+}
+
+variable "Public-Subnet-B" {
+  description = "The CIDR for the PubA subnet. Must be a subnet of VPC-Subnet"
+  type = "string"
+  default = "10.45.1.0/24"
+}
+
+variable "Private-Subnet-A" {
+  description = "The CIDR for the PubA subnet. Must be a subnet of VPC-Subnet"
+  type = "string"
+  default = "10.45.128.0/24"
+}
+
+variable "Private-Subnet-B" {
+  description = "The CIDR for the PubA subnet. Must be a subnet of VPC-Subnet"
+  type = "string"
+  default = "10.45.129.0/24"
+}
+
+# Performance Settings
+# --------------------
+# Defaults are probably fine, but if you want to change
+# your performance, here's where you can tune.
+variable "Instance-Type" {
+  description = "What size instances do you want to deploy?"
+  type = "string"
+  default = "t2.micro"
+}
+
+variable "EBS-Optimized" {
+  description = "Should instances be deployed as EBS optimized?"
+  type = "string"
+  default = false
+}
+
+variable "Swap-Volume-Size" {
+  description = "How much swap do you need?"
+  type = "string"
+  default = 2
+}
+
+variable "Swap-Volume-Type" {
+  description = "Type of storage for the swap volume."
+  type = "string"
+  default = "gp2"
+}
+
+variable "Default-Volume-Type" {
+  description = "Type of storage for the default volumes."
+  type = "string"
+  default = "gp2"
+}
+
+

+ 116 - 0
SingleWeb/variables.tf

@@ -0,0 +1,116 @@
+###############################################
+# DO NOT EDIT THIS FILE
+#
+# This file is generated through 'make all'. 
+# If you need to make changes, make your changes
+# to the corresponding .j file and then rerun
+# make all
+###############################################
+
+# User Settings
+# -------------
+# These MUST be configured
+variable "AWS-Key-Pair-Name" {
+  description = "Name of the keypair in AWS"
+  type = "string"
+  default = "Fred-IO"
+}
+
+variable "Private-Key-File" {
+  description = "The name of the file containing your private key"
+  type = "string"
+  default = "~/.ssh/id_rsa"
+}
+
+variable "Domain-Name" {
+  description = "Your domain name (hosted in Route53)"
+  type = "string"
+  default = "monkeybox.org"
+}
+
+variable "Domain-Zone-ID" {
+  description = "The Zone ID of the Domain-Name in Route53"
+  type = "string"
+  default = "Z49JKEQC08KW8"
+}
+
+variable "Trusted-CIDR" {
+  description = "Trusted source addresses in CIDR notation."
+  type = "list"
+  default =  ["98.243.254.99/32", "107.135.34.113/32"]
+}
+
+# Common Settings
+# ---------------
+# You may wish to customize these, but defaults
+# will usually work.
+variable "region" {
+  description = "Which AWS region do you wish to deploy to?"
+  type = "string"
+  default = "us-east-2"
+}
+
+variable "VPC-Subnet" {
+  description = "The full subnet for your VPC (to be split into 4 subnets)"
+  type = "string"
+  default = "10.45.0.0/16"
+}
+
+variable "Public-Subnet-A" {
+  description = "The CIDR for the PubA subnet. Must be a subnet of VPC-Subnet"
+  type = "string"
+  default = "10.45.0.0/24"
+}
+
+variable "Public-Subnet-B" {
+  description = "The CIDR for the PubA subnet. Must be a subnet of VPC-Subnet"
+  type = "string"
+  default = "10.45.1.0/24"
+}
+
+variable "Private-Subnet-A" {
+  description = "The CIDR for the PubA subnet. Must be a subnet of VPC-Subnet"
+  type = "string"
+  default = "10.45.128.0/24"
+}
+
+variable "Private-Subnet-B" {
+  description = "The CIDR for the PubA subnet. Must be a subnet of VPC-Subnet"
+  type = "string"
+  default = "10.45.129.0/24"
+}
+
+# Performance Settings
+# --------------------
+# Defaults are probably fine, but if you want to change
+# your performance, here's where you can tune.
+variable "Instance-Type" {
+  description = "What size instances do you want to deploy?"
+  type = "string"
+  default = "t2.micro"
+}
+
+variable "EBS-Optimized" {
+  description = "Should instances be deployed as EBS optimized?"
+  type = "string"
+  default = false
+}
+
+variable "Swap-Volume-Size" {
+  description = "How much swap do you need?"
+  type = "string"
+  default = 2
+}
+
+variable "Swap-Volume-Type" {
+  description = "Type of storage for the swap volume."
+  type = "string"
+  default = "gp2"
+}
+
+variable "Default-Volume-Type" {
+  description = "Type of storage for the default volumes."
+  type = "string"
+  default = "gp2"
+}
+

+ 86 - 0
SingleWeb/vpcs_and_subnets.j

@@ -0,0 +1,86 @@
+{% import 'variables.include' as var %}
+###########
+# Create a VPC with an Internet gateway for everybody to play in
+resource "aws_vpc" "vpc_primary" {
+  cidr_block = "${var.VPC-Subnet}"
+  enable_dns_support = true
+  enable_dns_hostnames = true
+  tags {
+    Name = "Primary VPC"
+  }
+}
+resource "aws_internet_gateway" "gw_primary" {
+  vpc_id = "${aws_vpc.vpc_primary.id}"
+  tags {
+    Name = "Primary Gateway"
+  }
+}
+
+###########
+# Create public and private subnets in two different az's
+data "aws_availability_zones" "available" {}
+resource "aws_subnet" "subnet_public_a" {
+  vpc_id = "${aws_vpc.vpc_primary.id}"
+  cidr_block = "${var.Public-Subnet-A}"
+  availability_zone = "${data.aws_availability_zones.available.names[0]}"
+  map_public_ip_on_launch = true
+  tags {
+    Name = "Public Subnet A"
+  }
+}
+#resource "aws_subnet" "subnet_public_b" {
+#  vpc_id = "${aws_vpc.vpc_primary.id}"
+#  cidr_block = "${var.Public-Subnet-B}"
+#  availability_zone = "${data.aws_availability_zones.available.names[1]}"
+#  map_public_ip_on_launch = true
+#  tags {
+#    Name = "Public Subnet B"
+#  }
+#}
+#resource "aws_subnet" "subnet_private_a" {
+#  vpc_id = "${aws_vpc.vpc_primary.id}"
+#  cidr_block = "${var.Private-Subnet-A}"
+#  availability_zone = "${data.aws_availability_zones.available.names[0]}"
+#  map_public_ip_on_launch = true
+#  tags {
+#    Name = "Private Subnet A"
+#  }
+#}
+#resource "aws_subnet" "subnet_private_b" {
+#  vpc_id = "${aws_vpc.vpc_primary.id}"
+#  cidr_block = "${var.Private-Subnet-B}"
+#  availability_zone = "${data.aws_availability_zones.available.names[1]}"
+#  map_public_ip_on_launch = true
+#  tags {
+#    Name = "Private Subnet B"
+#  }
+#}
+
+##########
+# Routing
+resource "aws_route_table" "r" {
+    vpc_id = "${aws_vpc.vpc_primary.id}"
+    route {
+        cidr_block = "0.0.0.0/0"
+        gateway_id = "${aws_internet_gateway.gw_primary.id}"
+    }
+  tags {
+    Name = "Primary Route Table"
+  }
+}
+resource "aws_route_table_association" "rt_public_a" {
+  subnet_id = "${aws_subnet.subnet_public_a.id}"
+  route_table_id = "${aws_route_table.r.id}"
+}
+#resource "aws_route_table_association" "rt_public_b" {
+#  subnet_id = "${aws_subnet.subnet_public_b.id}"
+#  route_table_id = "${aws_route_table.r.id}"
+#}
+#resource "aws_route_table_association" "rt_private_a" {
+#  subnet_id = "${aws_subnet.subnet_private_a.id}"
+#  route_table_id = "${aws_route_table.r.id}"
+#}
+#resource "aws_route_table_association" "rt_private_b" {
+#  subnet_id = "${aws_subnet.subnet_private_b.id}"
+#  route_table_id = "${aws_route_table.r.id}"
+#}

+ 94 - 0
SingleWeb/vpcs_and_subnets.tf

@@ -0,0 +1,94 @@
+###############################################
+# DO NOT EDIT THIS FILE
+#
+# This file is generated through 'make all'. 
+# If you need to make changes, make your changes
+# to the corresponding .j file and then rerun
+# make all
+###############################################
+
+###########
+# Create a VPC with an Internet gateway for everybody to play in
+resource "aws_vpc" "vpc_primary" {
+  cidr_block = "${var.VPC-Subnet}"
+  enable_dns_support = true
+  enable_dns_hostnames = true
+  tags {
+    Name = "Primary VPC"
+  }
+}
+resource "aws_internet_gateway" "gw_primary" {
+  vpc_id = "${aws_vpc.vpc_primary.id}"
+  tags {
+    Name = "Primary Gateway"
+  }
+}
+
+###########
+# Create public and private subnets in two different az's
+data "aws_availability_zones" "available" {}
+resource "aws_subnet" "subnet_public_a" {
+  vpc_id = "${aws_vpc.vpc_primary.id}"
+  cidr_block = "${var.Public-Subnet-A}"
+  availability_zone = "${data.aws_availability_zones.available.names[0]}"
+  map_public_ip_on_launch = true
+  tags {
+    Name = "Public Subnet A"
+  }
+}
+#resource "aws_subnet" "subnet_public_b" {
+#  vpc_id = "${aws_vpc.vpc_primary.id}"
+#  cidr_block = "${var.Public-Subnet-B}"
+#  availability_zone = "${data.aws_availability_zones.available.names[1]}"
+#  map_public_ip_on_launch = true
+#  tags {
+#    Name = "Public Subnet B"
+#  }
+#}
+#resource "aws_subnet" "subnet_private_a" {
+#  vpc_id = "${aws_vpc.vpc_primary.id}"
+#  cidr_block = "${var.Private-Subnet-A}"
+#  availability_zone = "${data.aws_availability_zones.available.names[0]}"
+#  map_public_ip_on_launch = true
+#  tags {
+#    Name = "Private Subnet A"
+#  }
+#}
+#resource "aws_subnet" "subnet_private_b" {
+#  vpc_id = "${aws_vpc.vpc_primary.id}"
+#  cidr_block = "${var.Private-Subnet-B}"
+#  availability_zone = "${data.aws_availability_zones.available.names[1]}"
+#  map_public_ip_on_launch = true
+#  tags {
+#    Name = "Private Subnet B"
+#  }
+#}
+
+##########
+# Routing
+resource "aws_route_table" "r" {
+    vpc_id = "${aws_vpc.vpc_primary.id}"
+    route {
+        cidr_block = "0.0.0.0/0"
+        gateway_id = "${aws_internet_gateway.gw_primary.id}"
+    }
+  tags {
+    Name = "Primary Route Table"
+  }
+}
+resource "aws_route_table_association" "rt_public_a" {
+  subnet_id = "${aws_subnet.subnet_public_a.id}"
+  route_table_id = "${aws_route_table.r.id}"
+}
+#resource "aws_route_table_association" "rt_public_b" {
+#  subnet_id = "${aws_subnet.subnet_public_b.id}"
+#  route_table_id = "${aws_route_table.r.id}"
+#}
+#resource "aws_route_table_association" "rt_private_a" {
+#  subnet_id = "${aws_subnet.subnet_private_a.id}"
+#  route_table_id = "${aws_route_table.r.id}"
+#}
+#resource "aws_route_table_association" "rt_private_b" {
+#  subnet_id = "${aws_subnet.subnet_private_b.id}"
+#  route_table_id = "${aws_route_table.r.id}"
+#}

+ 71 - 0
SingleWeb/webserver.j

@@ -0,0 +1,71 @@
+{% import 'variables.include' as var %}
+###################
+# Web Server Instance
+resource "aws_instance" "webserver" {
+  ami = "${data.aws_ami.ubuntu.id}"
+  instance_type = "${var.Instance-Type}"
+  availability_zone = "${data.aws_availability_zones.available.names[0]}"
+  subnet_id = "${aws_subnet.subnet_public_a.id}"
+  ebs_optimized = "${var.EBS-Optimized}"
+  disable_api_termination = false
+  associate_public_ip_address = true
+  instance_initiated_shutdown_behavior = "terminate"
+  key_name = "${var.AWS-Key-Pair-Name}"
+  vpc_security_group_ids = ["${aws_security_group.sg_instance_access.id}"]
+  depends_on    = ["aws_internet_gateway.gw_primary"]
+
+  tags {
+    Name = "webserver"
+  }
+
+  root_block_device {
+    volume_type = "standard"
+    volume_size = "{{ var.Web_Volume_Size }}" # Gigabytes
+    delete_on_termination = true
+  }
+  ebs_block_device {
+    device_name = "/dev/sdd"
+    volume_size = "${var.Swap-Volume-Size}"
+    volume_type = "${var.Swap-Volume-Type}"
+    delete_on_termination = true
+  }
+
+  user_data = <<EOF
+#cloud-config
+runcmd:
+  - [ mkswap, /dev/xvdd ]
+  - [ swapon, -a ]
+mounts:
+  - [ xvdd, none, swap, sw, 0, 0 ]
+EOF
+
+  # Fix issues with cached keys. Arguably less secure, but also way less annoying
+  provisioner "local-exec" {
+    command = "ssh-keygen -f ~/.ssh/known_hosts -R webserver.lab.${var.Domain-Name}"
+  }
+}
+
+# Give me the IP Addresses
+output "webserver_ip" {
+    value = "${aws_instance.webserver.public_ip}"
+}
+
+# Give me DNS entries
+resource "aws_route53_record" "webserver" {
+  zone_id = "${var.Domain-Zone-ID}"
+  name = "webserver.lab.${var.Domain-Name}"
+  type = "A"
+  ttl = "300"
+  records = ["${aws_instance.webserver.public_ip}"]
+}
+resource "aws_route53_record" "webserver_pvt" {
+  zone_id = "${var.Domain-Zone-ID}"
+  name = "webserver_pvt.lab.${var.Domain-Name}"
+  type = "A"
+  ttl = "300"
+  records = ["${aws_instance.webserver.private_ip}"]
+}
+output "webserver_dns" {
+  value = "${aws_route53_record.webserver.name}"
+}
+

+ 78 - 0
SingleWeb/webserver.tf

@@ -0,0 +1,78 @@
+###############################################
+# DO NOT EDIT THIS FILE
+#
+# This file is generated through 'make all'. 
+# If you need to make changes, make your changes
+# to the corresponding .j file and then rerun
+# make all
+###############################################
+
+###################
+# Web Server Instance
+resource "aws_instance" "webserver" {
+  ami = "${data.aws_ami.ubuntu.id}"
+  instance_type = "${var.Instance-Type}"
+  availability_zone = "${data.aws_availability_zones.available.names[0]}"
+  subnet_id = "${aws_subnet.subnet_public_a.id}"
+  ebs_optimized = "${var.EBS-Optimized}"
+  disable_api_termination = false
+  associate_public_ip_address = true
+  instance_initiated_shutdown_behavior = "terminate"
+  key_name = "${var.AWS-Key-Pair-Name}"
+  vpc_security_group_ids = ["${aws_security_group.sg_instance_access.id}"]
+  depends_on    = ["aws_internet_gateway.gw_primary"]
+
+  tags {
+    Name = "webserver"
+  }
+
+  root_block_device {
+    volume_type = "standard"
+    volume_size = "20" # Gigabytes
+    delete_on_termination = true
+  }
+  ebs_block_device {
+    device_name = "/dev/sdd"
+    volume_size = "${var.Swap-Volume-Size}"
+    volume_type = "${var.Swap-Volume-Type}"
+    delete_on_termination = true
+  }
+
+  user_data = <<EOF
+#cloud-config
+runcmd:
+  - [ mkswap, /dev/xvdd ]
+  - [ swapon, -a ]
+mounts:
+  - [ xvdd, none, swap, sw, 0, 0 ]
+EOF
+
+  # Fix issues with cached keys. Arguably less secure, but also way less annoying
+  provisioner "local-exec" {
+    command = "ssh-keygen -f ~/.ssh/known_hosts -R webserver.lab.${var.Domain-Name}"
+  }
+}
+
+# Give me the IP Addresses
+output "webserver_ip" {
+    value = "${aws_instance.webserver.public_ip}"
+}
+
+# Give me DNS entries
+resource "aws_route53_record" "webserver" {
+  zone_id = "${var.Domain-Zone-ID}"
+  name = "webserver.lab.${var.Domain-Name}"
+  type = "A"
+  ttl = "300"
+  records = ["${aws_instance.webserver.public_ip}"]
+}
+resource "aws_route53_record" "webserver_pvt" {
+  zone_id = "${var.Domain-Zone-ID}"
+  name = "webserver_pvt.lab.${var.Domain-Name}"
+  type = "A"
+  ttl = "300"
+  records = ["${aws_instance.webserver.private_ip}"]
+}
+output "webserver_dns" {
+  value = "${aws_route53_record.webserver.name}"
+}

+ 6 - 0
SingleWeb/z_nextsteps.j

@@ -0,0 +1,6 @@
+{% import "variables.include" as var %}
+output "NEXT-STEPS" {
+  value = <<EOF
+Enjoy!
+EOF
+}

+ 14 - 0
SingleWeb/z_nextsteps.tf

@@ -0,0 +1,14 @@
+###############################################
+# DO NOT EDIT THIS FILE
+#
+# This file is generated through 'make all'. 
+# If you need to make changes, make your changes
+# to the corresponding .j file and then rerun
+# make all
+###############################################
+
+output "NEXT-STEPS" {
+  value = <<EOF
+Enjoy!
+EOF
+}

+ 8 - 0
banner.txt

@@ -0,0 +1,8 @@
+###############################################
+# DO NOT EDIT THIS FILE
+#
+# This file is generated through 'make all'. 
+# If you need to make changes, make your changes
+# to the corresponding .j file and then rerun
+# make all
+###############################################

+ 91 - 0
bin/jj2.py

@@ -0,0 +1,91 @@
+#!/usr/bin/env python
+#
+# Copyright (c) 2008-2014 Miki Tebeka <miki@mikitebeka.com>
+# All rights reserved.
+# 
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+# 
+# * Redistributions of source code must retain the above copyright notice, this
+#   list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above copyright notice,
+#   this list of conditions and the following disclaimer in the documentation
+#   and/or other materials provided with the distribution.
+# * Neither the name of the "PythonWise" blog nor the names of its contributors
+#   may be used to endorse or promote products derived from this software without
+#   specific prior written permission.
+# 
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+# ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+'''Command line for expanding Jinja2 templates.
+Template variables can be passed either via the command line (using -vX=Y) or
+via a JSON/YAML configuration file (using -i /path/to/vars.json)
+Example:
+    $ echo 'Hello {{name}}' > template.txt
+    $ jj2.py -v name=Bugs template.txt
+    Hello Bugs
+    $
+'''
+
+import jinja2
+import json
+
+
+def load_vars(filename):
+    with open(filename) as fo:
+        if filename.lower().endswith('.json'):
+            return json.load(fo)
+        elif filename.lower().endswith('.yaml'):
+            import yaml  # Lazy import
+            return yaml.load(fo)
+        else:
+            raise ValueError('unknown file type: {}'.format(filename))
+
+
+def parse_cmdline_vars(cmdline_vars):
+    return dict(var.split('=', 1) for var in cmdline_vars)
+
+
+def main(argv=None):
+    import sys
+    from argparse import ArgumentParser, FileType
+
+    argv = argv or sys.argv
+
+    parser = ArgumentParser(description='Expand Jinja2 template')
+    parser.add_argument('template', help='template file to expand',
+                        type=FileType('r'), nargs='?', default=sys.stdin)
+    parser.add_argument('--var', '-v', action='append',
+                        help='template variables (in X=Y format)')
+    parser.add_argument('--output', '-o', help='output file',
+                        type=FileType('w'), nargs='?', default=sys.stdout)
+    parser.add_argument('--vars-file', '-i', help='vars files (YAML or JSON)',
+                        nargs='?')
+
+    args = parser.parse_args(argv[1:])
+
+    tvars = {}
+    if args.vars_file:
+        tvars.update(load_vars(args.vars_file))
+
+    tvars.update(parse_cmdline_vars(args.var or []))
+
+    # Fail on undefined
+    env = jinja2.Environment(undefined=jinja2.StrictUndefined, loader=jinja2.FileSystemLoader('.'))
+
+    template = env.from_string(args.template.read())
+
+    args.output.write(template.render(tvars))
+
+
+if __name__ == '__main__':
+    main()

+ 38 - 0
variables.include

@@ -0,0 +1,38 @@
+{###################################################}
+{# Required Variables                              #}
+{# Most users will need to customize these values. #}
+{###################################################}
+
+{# AWS Key Pair Name #
+{# The name of the AWS Key Pair as identified in AWS IAM #}
+{% set AWS_Key_Pair_Name = "Fred-IO" %}
+
+{# Private Key File #
+{# The private key paired with the above IAM keyname #}
+{% set Private_Key_File = "~/.ssh/id_rsa" %}
+
+{# Domain Name #}
+{# The domain name. Must be hosted in Route53. #}
+{% set Domain_Name = "monkeybox.org" %}
+
+{# Domain Zone ID (Route53) #}
+{# The Route53 Zone ID #}
+{% set Domain_Zone_ID = "Z49JKEQC08KW8" %}
+
+{# Trust Source IPs in CIDR #}
+{# These IPs will have direct access to instances. Should include  #}
+{# the terraform master's IP address, as well as your workstation  #}
+{# or home IP. Can contain multiple entries.                       #}
+{% set Trusted_CIDR = '["98.243.254.99/32", "107.135.34.113/32"]'  %}
+
+{###########################################}
+{# Optional Variables                      #}
+{# Default values are fine for most users. #}
+{###########################################}
+{# AWS Region #}
+{% set AWS_Region = "us-east-2" %}
+
+{# Web Server Volume Size #}
+{# Size of / on web servers #}
+{% set Web_Volume_Size = 20 %}
+