diff --git a/bootstrap/aws/private-cloud/config-default.sh b/bootstrap/aws/private-cloud/config-default.sh index 9e2e411d..b352cf09 100644 --- a/bootstrap/aws/private-cloud/config-default.sh +++ b/bootstrap/aws/private-cloud/config-default.sh @@ -1,14 +1,7 @@ #!/bin/bash -# Keeping atlas variable without prefix as it's been shared by consul and tf at the moment. -export ATLAS_TOKEN=${ATLAS_TOKEN:?"Need to set ATLAS_TOKEN non-empty"} -export ATLAS_INFRASTRUCTURE=${ATLAS_INFRASTRUCTURE:-capgemini/apollo} - -export TF_VAR_user=${TF_VAR_user:?"Need to set User non-empty"} export TF_VAR_access_key=${TF_VAR_access_key:?"Need to set TF_VAR_access_key non-empty"} export TF_VAR_secret_key=${TF_VAR_secret_key:?"Need to set TF_VAR_secret_key non-empty"} -export TF_VAR_key_file=${TF_VAR_key_file:-$HOME/.ssh/apollo_aws_rsa} -export TF_VAR_key_name=${TF_VAR_key_name:-apollo} # Overrides default folder in Terraform.py inventory. export TF_VAR_STATE_ROOT="${APOLLO_ROOT}/terraform/${APOLLO_PROVIDER}" @@ -16,10 +9,5 @@ export TF_VAR_STATE_ROOT="${APOLLO_ROOT}/terraform/${APOLLO_PROVIDER}" export ANSIBLE_SSH_ARGS="-F ${APOLLO_ROOT}/terraform/${APOLLO_PROVIDER}/ssh.config -q" export TF_VAR_region=${TF_VAR_region:-eu-west-1} -export TF_VAR_master_instance_type=${TF_VAR_master_instance_type:-m3.medium} -export TF_VAR_slave_instance_type=${TF_VAR_slave_instance_type:-m3.medium} -export TF_VAR_slaves=${TF_VAR_slaves:-1} -export TF_VAR_availability_zones=${TF_VAR_availability_zones:-'eu-west-1a,eu-west-1b,eu-west-1c'} -export TF_VAR_public_subnet_availability_zone=${TF_VAR_public_subnet_availability_zone:-'eu-west-1a'} export APOLLO_consul_dc=${APOLLO_consul_dc:-$TF_VAR_region} export APOLLO_mesos_cluster_name=${APOLLO_mesos_cluster_name:-$TF_VAR_region} diff --git a/bootstrap/aws/private-cloud/util.sh b/bootstrap/aws/private-cloud/util.sh index 68ff6bb9..342471bb 100644 --- a/bootstrap/aws/private-cloud/util.sh +++ b/bootstrap/aws/private-cloud/util.sh @@ -18,7 +18,7 @@ ansible_ssh_config() { export APOLLO_bastion_ip=$( terraform output bastion.ip ) # Virtual private cloud CIDR IP. - ip=$( terraform output vpc_cidr_block.ip ) + ip=$( terraform output -module=vpc vpc_cidr_block ) export APOLLO_network_identifier=$( get_network_identifier "${ip}" ) cat < ssh.config diff --git a/bootstrap/aws/public-cloud/config-default.sh b/bootstrap/aws/public-cloud/config-default.sh index e902c2d1..b352cf09 100644 --- a/bootstrap/aws/public-cloud/config-default.sh +++ b/bootstrap/aws/public-cloud/config-default.sh @@ -1,9 +1,5 @@ #!/bin/bash -# Keeping atlas variable without prefix as it's been shared by consul and tf at the moment. -export ATLAS_TOKEN=${ATLAS_TOKEN:?"Need to set ATLAS_TOKEN non-empty"} -export ATLAS_INFRASTRUCTURE=${ATLAS_INFRASTRUCTURE:-capgemini/apollo} - export TF_VAR_access_key=${TF_VAR_access_key:?"Need to set TF_VAR_access_key non-empty"} export TF_VAR_secret_key=${TF_VAR_secret_key:?"Need to set TF_VAR_secret_key non-empty"} diff --git a/terraform/aws/private-cloud/bastion-server.tf b/terraform/aws/private-cloud/bastion-server.tf index d4ae6886..44ce043b 100644 --- a/terraform/aws/private-cloud/bastion-server.tf +++ b/terraform/aws/private-cloud/bastion-server.tf @@ -9,7 +9,9 @@ module "ami_bastion" { resource "aws_instance" "bastion" { ami = "${module.ami_bastion.ami_id}" instance_type = "${var.bastion_instance_type}" - subnet_id = "${module.vpc.public_subnets}" + # Just put the bastion in the first public subnet + subnet_id = "${element(split(",", module.vpc.public_subnets), 0)}" + # @todo - this allows bastion connection on any port which is not ideal but was like this previously. security_groups = ["${module.sg-default.security_group_id}", "${aws_security_group.bastion.id}"] key_name = "${module.aws-keypair.keypair_name}" source_dest_check = false diff --git a/terraform/aws/private-cloud/cloud-config.yml.tpl b/terraform/aws/private-cloud/cloud-config.yml.tpl index 4cc6a1c2..73a6d485 100644 --- a/terraform/aws/private-cloud/cloud-config.yml.tpl +++ b/terraform/aws/private-cloud/cloud-config.yml.tpl @@ -2,18 +2,19 @@ coreos: etcd2: - # $public_ipv4 and $private_ipv4 are populated by the cloud provider - advertise-client-urls: http://$public_ipv4:2379 + # $private_ipv4 is populated by the cloud provider + # we don't have a $public_ipv4 in the private VPC + advertise-client-urls: http://$private_ipv4:2379,http://$private_ipv4:4001 initial-advertise-peer-urls: http://$private_ipv4:2380 + # listen on both the official ports and the legacy ports + # legacy ports can be omitted if your application doesn't depend on them listen-client-urls: http://0.0.0.0:2379,http://0.0.0.0:4001 listen-peer-urls: http://$private_ipv4:2380,http://$private_ipv4:7001 # Discovery is populated by Terraform discovery: ${etcd_discovery_url} - fleet: - public-ip: "$public_ipv4" units: - name: etcd2.service command: start - - name: fleet.service - command: start + update: + reboot-strategy: "reboot" manage_etc_hosts: localhost diff --git a/terraform/aws/private-cloud/main.tf b/terraform/aws/private-cloud/main.tf index 1599ec7e..62305d65 100644 --- a/terraform/aws/private-cloud/main.tf +++ b/terraform/aws/private-cloud/main.tf @@ -21,15 +21,16 @@ provider "aws" { } module "vpc" { - source = "github.com/terraform-community-modules/tf_aws_vpc" + source = "./vpc" - name = "default" + name = "default" - cidr = "${var.vpc_cidr_block}" - private_subnets = "10.0.1.0/24,10.0.2.0/24,10.0.3.0/24" - public_subnets = "10.0.101.0/24,10.0.102.0/24,10.0.103.0/24" + cidr = "${var.vpc_cidr_block}" + private_subnets = "10.0.1.0/24,10.0.2.0/24,10.0.3.0/24" + public_subnets = "10.0.101.0/24,10.0.102.0/24,10.0.103.0/24" + bastion_instance_id = "${aws_instance.bastion.id}" - azs = "${var.availability_zones}" + azs = "${var.availability_zones}" } # ssh keypair for instances @@ -79,7 +80,9 @@ output "master_ips" { output "slave_ips" { value = "${join(",", aws_instance.mesos-slave.*.private_ip)}" } -/* +output "vpc_cidr_block_ip" { + value = "${module.vpc.vpc_cidr_block}" +} output "elb.hostname" { value = "${module.elb.elb_dns_name}" -}*/ +} diff --git a/terraform/aws/private-cloud/mesos-masters.tf b/terraform/aws/private-cloud/mesos-masters.tf index dea45d85..c61d6823 100644 --- a/terraform/aws/private-cloud/mesos-masters.tf +++ b/terraform/aws/private-cloud/mesos-masters.tf @@ -25,7 +25,7 @@ resource "aws_instance" "mesos-master" { count = "${var.masters}" key_name = "${module.aws-keypair.keypair_name}" source_dest_check = false - subnet_id = "${element(aws_subnet.private.*.id, count.index)}" + subnet_id = "${element(split(",", module.vpc.private_subnets), count.index)}" security_groups = ["${module.sg-default.security_group_id}"] depends_on = ["aws_instance.bastion"] user_data = "${template_file.master_cloud_init.rendered}" diff --git a/terraform/aws/private-cloud/mesos-slaves.tf b/terraform/aws/private-cloud/mesos-slaves.tf index 8b2de1fb..69b846ca 100644 --- a/terraform/aws/private-cloud/mesos-slaves.tf +++ b/terraform/aws/private-cloud/mesos-slaves.tf @@ -19,13 +19,17 @@ resource "template_file" "slave_cloud_init" { } } +/* + @todo This should be changed to be an autoscaling slave with launch config + */ resource "aws_instance" "mesos-slave" { instance_type = "${var.slave_instance_type}" ami = "${module.slave_ami.ami_id}" count = "${var.slaves}" key_name = "${module.aws-keypair.keypair_name}" source_dest_check = false - subnet_id = "${element(aws_subnet.private.*.id, count.index)}" + # @todo - fix this as this only allows 3 slaves maximum (due to splittingo on the count variable) + subnet_id = "${element(split(",", module.vpc.private_subnets), count.index)}" security_groups = ["${module.sg-default.security_group_id}"] depends_on = ["aws_instance.bastion", "aws_instance.mesos-master"] user_data = "${template_file.master_cloud_init.rendered}" diff --git a/terraform/aws/private-cloud/private-subnet.tf b/terraform/aws/private-cloud/private-subnet.tf deleted file mode 100644 index 671e277d..00000000 --- a/terraform/aws/private-cloud/private-subnet.tf +++ /dev/null @@ -1,29 +0,0 @@ -# Private subnet -resource "aws_subnet" "private" { - vpc_id = "${module.vpc.vpc_id}" - count = "${length(split(",", var.availability_zones))}" - availability_zone = "${element(split(",", var.availability_zones), count.index)}" - cidr_block = "10.0.${count.index+1}.0/24" - map_public_ip_on_launch = false - depends_on = ["aws_instance.bastion"] - tags { - Name = "private" - } -} - -resource "aws_route_table" "private" { - vpc_id = "${module.vpc.vpc_id}" - route { - cidr_block = "0.0.0.0/0" - instance_id = "${aws_instance.bastion.id}" - } - tags { - Name = "private" - } -} - -resource "aws_route_table_association" "private" { - count = "${length(split(",", var.availability_zones))}" - subnet_id = "${element(aws_subnet.private.*.id, count.index)}" - route_table_id = "${aws_route_table.private.id}" -} diff --git a/terraform/aws/private-cloud/security_groups.tf b/terraform/aws/private-cloud/security_groups.tf index eb02a46f..d30d0488 100644 --- a/terraform/aws/private-cloud/security_groups.tf +++ b/terraform/aws/private-cloud/security_groups.tf @@ -1,8 +1,24 @@ resource "aws_security_group" "bastion" { - name = "bastion-apollo-mesos" + name = "bastion-apollo" description = "Security group for bastion instances that allows SSH and VPN traffic from internet" vpc_id = "${module.vpc.vpc_id}" + # inbound http/https traffic from the private subnets to allow them to talk with the internet + ingress { + from_port = 80 + to_port = 80 + protocol = "tcp" + cidr_blocks = ["10.0.1.0/24", "10.0.2.0/24", "10.0.3.0/24"] + } + + ingress { + from_port = 443 + to_port = 443 + protocol = "tcp" + cidr_blocks = ["10.0.1.0/24", "10.0.2.0/24", "10.0.3.0/24"] + } + + # ssh ingress { from_port = 22 to_port = 22 @@ -10,6 +26,7 @@ resource "aws_security_group" "bastion" { cidr_blocks = ["0.0.0.0/0"] } + # openvpn ingress { from_port = 1194 to_port = 1194 @@ -17,6 +34,7 @@ resource "aws_security_group" "bastion" { cidr_blocks = ["0.0.0.0/0"] } + # outbound access to the inernet egress { from_port = 80 to_port = 80 @@ -32,23 +50,6 @@ resource "aws_security_group" "bastion" { } tags { - Name = "bastion-apollo-mesos" - } -} - -resource "aws_security_group" "web" { - name = "web-apollo-mesos" - description = "Security group that allows web traffic from the internet" - vpc_id = "${module.vpc.vpc_id}" - - ingress { - from_port = 80 - to_port = 80 - protocol = "tcp" - cidr_blocks = ["0.0.0.0/0"] - } - - tags { - Name = "web-apollo-mesos" + Name = "bastion-apollo-sg" } } diff --git a/terraform/aws/private-cloud/vpc/main.tf b/terraform/aws/private-cloud/vpc/main.tf new file mode 100644 index 00000000..47bf1f64 --- /dev/null +++ b/terraform/aws/private-cloud/vpc/main.tf @@ -0,0 +1,98 @@ +variable "name" { } +variable "cidr" { } +variable "public_subnets" { default = "" } +variable "private_subnets" { default = "" } +variable "bastion_instance_id" { } +variable "azs" { } +variable "enable_dns_hostnames" { + description = "should be true if you want to use private DNS within the VPC" + default = false +} +variable "enable_dns_support" { + description = "should be true if you want to use private DNS within the VPC" + default = false +} + +# resources +resource "aws_vpc" "mod" { + cidr_block = "${var.cidr}" + enable_dns_hostnames = "${var.enable_dns_hostnames}" + enable_dns_support = "${var.enable_dns_support}" + tags { + Name = "${var.name}" + } +} + +resource "aws_internet_gateway" "mod" { + vpc_id = "${aws_vpc.mod.id}" +} + +resource "aws_route_table" "public" { + vpc_id = "${aws_vpc.mod.id}" + route { + cidr_block = "0.0.0.0/0" + gateway_id = "${aws_internet_gateway.mod.id}" + } + tags { + Name = "${var.name}-public" + } +} + +resource "aws_route_table" "private" { + vpc_id = "${aws_vpc.mod.id}" + route { + cidr_block = "0.0.0.0/0" + instance_id = "${var.bastion_instance_id}" + } + tags { + Name = "${var.name}-private" + } +} + +resource "aws_subnet" "private" { + vpc_id = "${aws_vpc.mod.id}" + cidr_block = "${element(split(",", var.private_subnets), count.index)}" + availability_zone = "${element(split(",", var.azs), count.index)}" + count = "${length(compact(split(",", var.private_subnets)))}" + tags { + Name = "${var.name}-private" + } +} + +resource "aws_subnet" "public" { + vpc_id = "${aws_vpc.mod.id}" + cidr_block = "${element(split(",", var.public_subnets), count.index)}" + availability_zone = "${element(split(",", var.azs), count.index)}" + count = "${length(compact(split(",", var.public_subnets)))}" + tags { + Name = "${var.name}-public" + } + + map_public_ip_on_launch = true +} + +resource "aws_route_table_association" "private" { + count = "${length(compact(split(",", var.private_subnets)))}" + subnet_id = "${element(aws_subnet.private.*.id, count.index)}" + route_table_id = "${aws_route_table.private.id}" +} + +resource "aws_route_table_association" "public" { + count = "${length(compact(split(",", var.public_subnets)))}" + subnet_id = "${element(aws_subnet.public.*.id, count.index)}" + route_table_id = "${aws_route_table.public.id}" +} + +# outputs +output "private_subnets" { + value = "${join(",", aws_subnet.private.*.id)}" +} +output "public_subnets" { + value = "${join(",", aws_subnet.public.*.id)}" +} +output "vpc_id" { + value = "${aws_vpc.mod.id}" +} +output "vpc_cidr_block" { + value = "${aws_vpc.mod.cidr_block}" +} diff --git a/terraform/aws/public-cloud/cloud-config.yml.tpl b/terraform/aws/public-cloud/cloud-config.yml.tpl index 4cc6a1c2..a9a1aa35 100644 --- a/terraform/aws/public-cloud/cloud-config.yml.tpl +++ b/terraform/aws/public-cloud/cloud-config.yml.tpl @@ -16,4 +16,6 @@ coreos: command: start - name: fleet.service command: start + update: + reboot-strategy: "reboot" manage_etc_hosts: localhost diff --git a/terraform/aws/sg-all-traffic/main.tf b/terraform/aws/sg-all-traffic/main.tf index 03f6c17a..d31e6762 100644 --- a/terraform/aws/sg-all-traffic/main.tf +++ b/terraform/aws/sg-all-traffic/main.tf @@ -32,7 +32,7 @@ resource "aws_security_group" "default" { cidr_blocks = ["${var.source_cidr_block}"] } tags { - Name = "apollo-mesos-default-security-group" + Name = "apollo-default-sg" } } diff --git a/user-data b/user-data index 71e93ac1..951eacf0 100755 --- a/user-data +++ b/user-data @@ -15,4 +15,6 @@ coreos: command: start - name: fleet.service command: start + update: + reboot-strategy: "reboot" manage_etc_hosts: localhost