Skip to content

Commit

Permalink
Add public routiug
Browse files Browse the repository at this point in the history
In order to make an env publicily reachable we introduce the handling of
an additional zone which is part of the user input during setup.
Additionally we make the use of an acm certificate to provide proper
termination for the traffic layer.
  • Loading branch information
Alexander Simmerl committed Nov 25, 2016
1 parent bda4d52 commit f9d273d
Show file tree
Hide file tree
Showing 7 changed files with 176 additions and 102 deletions.
39 changes: 26 additions & 13 deletions cmd/terraformer/terraformer.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ const (
defaultTmpPath = "/tmp"

fmtBucket = "bucket=%s"
fmtBucketState = "%s-tapglue-snaas-state"
fmtBucketState = "%s-snaas-state"
fmtKey = "key=%s/%s.tfstate"
fmtNamespace = "%s-%s"
fmtPlan = "%s/%s.plan"
Expand All @@ -63,6 +63,7 @@ const (
tfCmdRemote = "remote"

tplTFVars = `
domain = "{{.Domain}}"
key = {
access = "{{.KeyAccess}}"
}
Expand All @@ -74,6 +75,13 @@ pg_password = "{{.PGPassword}}"
varRegion = "region"
)

// vars bundles together all generated or given input that is custom to the env.
type vars struct {
KeyAccess string
Domain string
PGPassword string
}

func main() {
var (
env = flag.String("env", "", "Environment used for isolation.")
Expand Down Expand Up @@ -188,12 +196,25 @@ func main() {
log.Fatalf("state dir creation failed: %s", err)
}

fmt.Println("\nWhat is the domain the env should be reachable at?")
fmt.Print("|> ")
domain := ""
fmt.Scanf("%s", &domain)

if domain == "" {
log.Fatal("Can't work without a domain.")
}

pubKey, err := generateKeyPair(filepath.Join(statePath, defaultKeyPath))
if err != nil {
log.Fatal(err)
}

if err = generateVarFile(varFile, pubKey, generate.RandomString(32)); err != nil {
if err = generateVarFile(varFile, vars{
Domain: domain,
KeyAccess: strings.Trim(string(pubKey), "\n"),
PGPassword: generate.RandomStringSafe(32),
}); err != nil {
log.Fatalf("var file create failed: %s", err)
}

Expand Down Expand Up @@ -298,7 +319,7 @@ func generateKeyPair(privateKeyPath string) ([]byte, error) {
return nil, err
}

privateFile, err := os.Create(privateKeyPath)
privateFile, err := os.OpenFile(privateKeyPath, os.O_CREATE|os.O_WRONLY, 0400)
if err != nil {
return nil, err
}
Expand All @@ -320,7 +341,7 @@ func generateKeyPair(privateKeyPath string) ([]byte, error) {
return ssh.MarshalAuthorizedKey(pub), nil
}

func generateVarFile(path string, accessKeyPub []byte, pgPassword string) error {
func generateVarFile(path string, vs vars) error {
f, err := os.Create(path)
if err != nil {
return err
Expand All @@ -331,15 +352,7 @@ func generateVarFile(path string, accessKeyPub []byte, pgPassword string) error
return err
}

tmpl.Execute(f, struct {
KeyAccess string
PGPassword string
}{
KeyAccess: strings.Trim(string(accessKeyPub), "\n"),
PGPassword: pgPassword,
})

return nil
return tmpl.Execute(f, vs)
}

func prepareCmd(dir string, environ []string, command string, args ...string) *exec.Cmd {
Expand Down
58 changes: 31 additions & 27 deletions infrastructure/terraform/template/network.tf
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ provider "aws" {
}

resource "aws_vpc" "env" {
cidr_block = "10.0.0.0/16"
enable_dns_support = true
enable_dns_hostnames = true
cidr_block = "10.0.0.0/16"
enable_dns_support = true
enable_dns_hostnames = true

tags {
Name = "${var.env}"
Expand All @@ -22,10 +22,12 @@ resource "aws_internet_gateway" "env" {

resource "aws_nat_gateway" "env" {
allocation_id = "${aws_eip.nat.id}"
depends_on = [

depends_on = [
"aws_internet_gateway.env",
]
subnet_id = "${aws_subnet.perimeter-a.id}"

subnet_id = "${aws_subnet.perimeter-a.id}"
}

resource "aws_eip" "nat" {
Expand Down Expand Up @@ -68,29 +70,29 @@ resource "aws_route_table" "perimeter" {
}

resource "aws_route_table_association" "perimeter-a" {
route_table_id = "${aws_route_table.perimeter.id}"
subnet_id = "${aws_subnet.perimeter-a.id}"
route_table_id = "${aws_route_table.perimeter.id}"
subnet_id = "${aws_subnet.perimeter-a.id}"
}

resource "aws_route_table_association" "perimeter-b" {
route_table_id = "${aws_route_table.perimeter.id}"
subnet_id = "${aws_subnet.perimeter-b.id}"
route_table_id = "${aws_route_table.perimeter.id}"
subnet_id = "${aws_subnet.perimeter-b.id}"
}

resource "aws_subnet" "platform-a" {
availability_zone = "${var.region}a"
cidr_block = "10.0.2.0/23"
vpc_id = "${aws_vpc.env.id}"
availability_zone = "${var.region}a"
cidr_block = "10.0.2.0/23"
vpc_id = "${aws_vpc.env.id}"

tags {
Name = "platform-a"
}
}

resource "aws_subnet" "platform-b" {
availability_zone = "${var.region}b"
cidr_block = "10.0.10.0/23"
vpc_id = "${aws_vpc.env.id}"
availability_zone = "${var.region}b"
cidr_block = "10.0.10.0/23"
vpc_id = "${aws_vpc.env.id}"

tags {
Name = "platform-b"
Expand All @@ -101,7 +103,7 @@ resource "aws_route_table" "platform" {
vpc_id = "${aws_vpc.env.id}"

route {
cidr_block = "0.0.0.0/0"
cidr_block = "0.0.0.0/0"
nat_gateway_id = "${aws_nat_gateway.env.id}"
}

Expand All @@ -111,30 +113,32 @@ resource "aws_route_table" "platform" {
}

resource "aws_route_table_association" "platform-a" {
route_table_id = "${aws_route_table.platform.id}"
subnet_id = "${aws_subnet.platform-a.id}"
route_table_id = "${aws_route_table.platform.id}"
subnet_id = "${aws_subnet.platform-a.id}"
}

resource "aws_route_table_association" "platform-b" {
route_table_id = "${aws_route_table.platform.id}"
subnet_id = "${aws_subnet.platform-b.id}"
route_table_id = "${aws_route_table.platform.id}"
subnet_id = "${aws_subnet.platform-b.id}"
}

resource "aws_instance" "bastion" {
ami = "${var.ami_minimal["${var.region}"]}"
instance_type = "t2.medium"
key_name = "${aws_key_pair.access.key_name}"
vpc_security_group_ids = [
ami = "${var.ami_minimal["${var.region}"]}"
instance_type = "t2.medium"
key_name = "${aws_key_pair.access.key_name}"

vpc_security_group_ids = [
"${aws_security_group.perimeter.id}",
]
subnet_id = "${aws_subnet.perimeter-a.id}"

subnet_id = "${aws_subnet.perimeter-a.id}"

tags {
Name = "bastion"
}
}

resource "aws_eip" "bastion" {
instance = "${aws_instance.bastion.id}"
vpc = true
instance = "${aws_instance.bastion.id}"
vpc = true
}
92 changes: 54 additions & 38 deletions infrastructure/terraform/template/platform.tf
Original file line number Diff line number Diff line change
@@ -1,52 +1,59 @@
data "aws_acm_certificate" "perimeter" {
domain = "${var.domain}"

statuses = [
"ISSUED",
]
}

resource "aws_instance" "monitoring" {
ami = "${var.ami_minimal["${var.region}"]}"
instance_type = "t2.medium"
key_name = "${aws_key_pair.access.key_name}"
ami = "${var.ami_minimal["${var.region}"]}"
instance_type = "t2.medium"
key_name = "${aws_key_pair.access.key_name}"

vpc_security_group_ids = [
"${aws_security_group.platform.id}",
]
subnet_id = "${aws_subnet.platform-a.id}"

subnet_id = "${aws_subnet.platform-a.id}"

tags {
Name = "monitoring"
}
}

resource "aws_iam_server_certificate" "monitoring" {
name = "monitoring"
certificate_body = "${file("${path.module}/../../certs/self/self.crt")}"
private_key = "${file("${path.module}/../../certs/self/self.key")}"
}

resource "aws_elb" "monitoring" {
connection_draining = true
connection_draining_timeout = 10
cross_zone_load_balancing = true
idle_timeout = 30
name = "monitoring"
security_groups = [

security_groups = [
"${aws_security_group.perimeter.id}",
]
subnets = [

subnets = [
"${aws_subnet.perimeter-a.id}",
"${aws_subnet.perimeter-b.id}",
]

access_logs = {
bucket = "${aws_s3_bucket.logs-elb.id}"
interval = 5
access_logs = {
bucket = "${aws_s3_bucket.logs-elb.id}"
bucket_prefix = "monitoring"
interval = 5
}

instances = [
"${aws_instance.monitoring.id}",
]

listener {
instance_port = 3000
instance_protocol = "http"
lb_port = 443
lb_protocol = "https"
ssl_certificate_id = "${aws_iam_server_certificate.monitoring.arn}"
instance_port = 3000
instance_protocol = "http"
lb_port = 443
lb_protocol = "https"
ssl_certificate_id = "${data.aws_acm_certificate.perimeter.arn}"
}

tags {
Expand All @@ -59,18 +66,22 @@ resource "aws_autoscaling_group" "service" {
health_check_grace_period = 60
health_check_type = "EC2"
launch_configuration = "${aws_launch_configuration.service.name}"
load_balancers = [

load_balancers = [
"${aws_elb.gateway-http.name}",
]
max_size = 30
min_size = 1
name = "service"
termination_policies = [

max_size = 30
min_size = 1
name = "service"

termination_policies = [
"OldestInstance",
"OldestLaunchConfiguration",
"ClosestToNextInstanceHour",
]
vpc_zone_identifier = [

vpc_zone_identifier = [
"${aws_subnet.platform-a.id}",
"${aws_subnet.platform-b.id}",
]
Expand All @@ -89,17 +100,18 @@ resource "aws_launch_configuration" "service" {
key_name = "${aws_key_pair.access.key_name}"
iam_instance_profile = "${aws_iam_instance_profile.ecs-agent-profile.name}"
image_id = "${var.ami_ecs_agent["${var.region}"]}"
instance_type = "m4.large"
instance_type = "m4.large"
name_prefix = "ecs-service-"
security_groups = [

security_groups = [
"${aws_security_group.platform.id}",
]

lifecycle {
create_before_destroy = true
}

user_data = <<EOF
user_data = <<EOF
#!/bin/bash
echo ECS_CLUSTER=service >> /etc/ecs/ecs.config
Expand Down Expand Up @@ -142,17 +154,20 @@ resource "aws_elb" "gateway-http" {
cross_zone_load_balancing = true
idle_timeout = 30
name = "gateway-http"
security_groups = [

security_groups = [
"${aws_security_group.perimeter.id}",
]
subnets = [

subnets = [
"${aws_subnet.perimeter-a.id}",
"${aws_subnet.perimeter-b.id}",
]

access_logs = {
bucket = "${aws_s3_bucket.logs-elb.id}"
interval = 5
access_logs = {
bucket = "${aws_s3_bucket.logs-elb.id}"
bucket_prefix = "gateway-http"
interval = 5
}

health_check {
Expand All @@ -164,10 +179,11 @@ resource "aws_elb" "gateway-http" {
}

listener {
instance_port = 8083
instance_protocol = "tcp"
lb_port = 443
lb_protocol = "tcp"
instance_port = 8083
instance_protocol = "http"
lb_port = 443
lb_protocol = "https"
ssl_certificate_id = "${data.aws_acm_certificate.perimeter.arn}"
}

tags {
Expand Down
Loading

0 comments on commit f9d273d

Please sign in to comment.