aboutsummaryrefslogtreecommitdiff
path: root/terraform/aws_using_ami
diff options
context:
space:
mode:
Diffstat (limited to 'terraform/aws_using_ami')
-rw-r--r--terraform/aws_using_ami/backend/guix-daemon.service.tpl17
-rw-r--r--terraform/aws_using_ami/backend/main.tf340
-rw-r--r--terraform/aws_using_ami/deploy/main.tf7
-rw-r--r--terraform/aws_using_ami/mini_environment/govuk.service.tpl12
-rw-r--r--terraform/aws_using_ami/mini_environment/main.tf164
5 files changed, 540 insertions, 0 deletions
diff --git a/terraform/aws_using_ami/backend/guix-daemon.service.tpl b/terraform/aws_using_ami/backend/guix-daemon.service.tpl
new file mode 100644
index 0000000..c2e8310
--- /dev/null
+++ b/terraform/aws_using_ami/backend/guix-daemon.service.tpl
@@ -0,0 +1,17 @@
+[Unit]
+Description=Build daemon for GNU Guix
+
+[Service]
+ExecStart=/var/guix/profiles/per-user/root/current-guix/bin/guix-daemon --build-users-group=guixbuild --substitute-urls="${substitute_servers}" --listen=0.0.0.0 --listen=/var/guix/daemon-socket/socket --max-jobs=2
+Environment=GUIX_LOCPATH='/var/guix/profiles/per-user-root/guix-profile/lib/locale' LC_ALL=en_US.utf8
+RemainAfterExit=yes
+StandardOutput=syslog
+StandardError=syslog
+
+# See <https://lists.gnu.org/archive/html/guix-devel/2016-04/msg00608.html>.
+# Some package builds (for example, go@1.8.1) may require even more than
+# 1024 tasks.
+TasksMax=8192
+
+[Install]
+WantedBy=multi-user.target
diff --git a/terraform/aws_using_ami/backend/main.tf b/terraform/aws_using_ami/backend/main.tf
new file mode 100644
index 0000000..8dfb078
--- /dev/null
+++ b/terraform/aws_using_ami/backend/main.tf
@@ -0,0 +1,340 @@
+terraform {
+ backend "http" {}
+}
+
+variable "aws_access_key" {
+ type = "string"
+}
+
+variable "aws_secret_key" {
+ type = "string"
+}
+
+variable "aws_region" {
+ type = "string"
+}
+
+variable "aws_vpc_id" {
+ type = "string"
+}
+
+variable "aws_route_53_zone_id" {
+ type = "string"
+}
+
+variable "ssh_public_key" {
+ type = "string"
+}
+
+variable "ssh_private_key" {
+ type = "string"
+}
+
+variable "guix_substitute_servers" {
+ type = "map"
+ default = {
+ "https://ci.guix.gnu.org" = <<EOF
+(entry
+ (public-key
+ (ecc
+ (curve Ed25519)
+ (q #8D156F295D24B0D9A86FA5741A840FF2D24F60F7B6C4134814AD55625971B394#)
+ )
+ )
+ (tag
+ (guix import)
+ )
+)
+EOF
+ }
+}
+
+variable "mini_environment_admin_guix_public_key" {
+ type = "string"
+}
+
+variable "mini_environment_admin_egress_cidr_blocks" {
+ type = "list"
+}
+
+variable "backend_slug" {
+ type = "string"
+}
+
+locals {
+ guix_daemon_substitute_servers = "${join(" ", keys(var.guix_substitute_servers))}"
+}
+
+provider "aws" {
+ access_key = "${var.aws_access_key}"
+ secret_key = "${var.aws_secret_key}"
+ region = "${var.aws_region}"
+}
+
+data "aws_route53_zone" "main" {
+ zone_id = "${var.aws_route_53_zone_id}"
+}
+
+data "template_file" "guix_daemon_service" {
+ template = "${file("${path.module}/guix-daemon.service.tpl")}"
+
+ vars {
+ substitute_servers = "${local.guix_daemon_substitute_servers}"
+ }
+}
+
+data "aws_availability_zones" "available" {}
+
+resource "aws_key_pair" "deployer" {
+ key_name = "govuk_mini_environment_admin/${var.backend_slug}/deployer"
+ public_key = "${var.ssh_public_key}"
+}
+
+resource "aws_security_group" "public_webserver" {
+ name = "govuk_mini_environment_admin/${var.backend_slug}/public_webserver"
+ description = "For instances running public facing web servers"
+ vpc_id = "${var.aws_vpc_id}"
+
+ ingress {
+ from_port = 0
+ to_port = 80
+ protocol = "tcp"
+ cidr_blocks = ["0.0.0.0/0"]
+ }
+
+ ingress {
+ from_port = 0
+ to_port = 443
+ protocol = "tcp"
+ cidr_blocks = ["0.0.0.0/0"]
+ }
+
+ ingress {
+ from_port = 0
+ to_port = 8080
+ protocol = "tcp"
+ cidr_blocks = ["0.0.0.0/0"]
+ }
+
+ ingress {
+ from_port = 0
+ to_port = 8443
+ protocol = "tcp"
+ cidr_blocks = ["0.0.0.0/0"]
+ }
+}
+
+resource "aws_security_group" "ssh_access_from_mini_environment_admin" {
+ name = "govuk_mini_environment_admin/${var.backend_slug}/ssh_access_from_mini_environment_admin"
+ description = "For instances that need SSH access for Terraform and Guix builds"
+ vpc_id = "${var.aws_vpc_id}"
+
+ ingress {
+ from_port = 0
+ to_port = 22
+ protocol = "tcp"
+ cidr_blocks = [
+ "${var.mini_environment_admin_egress_cidr_blocks}"
+ ]
+ }
+}
+
+resource "aws_security_group" "guix_client" {
+ name = "govuk_mini_environment_admin/${var.backend_slug}/guix_client"
+ description = "For instances with access to the guix_daemon instance"
+ vpc_id = "${var.aws_vpc_id}"
+
+ egress {
+ from_port = 0
+ to_port = 0
+ protocol = "-1"
+ cidr_blocks = ["0.0.0.0/0"]
+ }
+}
+
+resource "aws_security_group" "guix_daemon" {
+ name = "govuk_mini_environment_admin/${var.backend_slug}/guix_daemon"
+ description = "For the guix_daemon instance."
+ vpc_id = "${var.aws_vpc_id}"
+
+ ingress {
+ from_port = 44146
+ to_port = 44146
+ protocol = "tcp"
+ security_groups = ["${aws_security_group.guix_client.id}"]
+ }
+
+ egress {
+ from_port = 0
+ to_port = 0
+ protocol = "-1"
+ cidr_blocks = ["0.0.0.0/0"]
+ }
+}
+
+resource "aws_spot_instance_request" "main" {
+ ami = "ami-0b2a4d260c54e8d3d"
+ instance_type = "i3.xlarge"
+ key_name = "${aws_key_pair.deployer.key_name}"
+ security_groups = [
+ "${aws_security_group.guix_daemon.name}",
+ "${aws_security_group.ssh_access_from_mini_environment_admin.name}"
+ ]
+
+ wait_for_fulfillment = true
+ spot_price = "0.172"
+ spot_type = "one-time"
+ availability_zone = "${data.aws_availability_zones.available.names[1]}"
+
+ root_block_device {
+ volume_size = "50"
+ }
+
+ provisioner "file" {
+ content = "${data.template_file.guix_daemon_service.rendered}"
+ destination = "/home/ubuntu/guix-daemon.service"
+
+ connection {
+ type = "ssh"
+ user = "ubuntu"
+ private_key = "${var.ssh_private_key}"
+ }
+ }
+
+ provisioner "file" {
+ content = "(acl\n ${join("\n", values(var.guix_substitute_servers))}\n${var.mini_environment_admin_guix_public_key}\n)\n"
+ destination = "/home/ubuntu/acl"
+
+ connection {
+ type = "ssh"
+ user = "ubuntu"
+ private_key = "${var.ssh_private_key}"
+ }
+ }
+
+ provisioner "remote-exec" {
+ inline = [
+ <<EOF
+sudo sgdisk --largest-new=0 /dev/nvme0n1
+
+sudo mkfs.ext4 -m 0 /dev/nvme0n1p1
+
+echo "/dev/nvme0n1p1 /gnu/store ext4 defaults,discard 0 0" | sudo tee -a /etc/fstab
+
+sudo cat /etc/fstab
+
+sudo mkdir -p /gnu/store
+sudo mount -a
+EOF
+ ,
+ <<EOF
+set -e
+
+FILENAME="guix-binary-1.0.0.x86_64-linux.tar.xz"
+
+wget https://ftp.gnu.org/gnu/guix/$FILENAME
+
+cd /
+sudo tar --warning=no-timestamp -xf /home/ubuntu/$FILENAME
+cd -
+
+rm "$FILENAME"
+
+sudo mkdir -p ~root/.config/guix
+sudo ln -sf /var/guix/profiles/per-user/root/current-guix ~root/.config/guix/current
+
+sudo mkdir -p /usr/local/bin
+sudo ln --symbolic --no-target-directory /var/guix/profiles/per-user/root/current-guix/bin/guix /usr/local/bin/guix
+EOF
+ ,
+ "sudo mv /home/ubuntu/guix-daemon.service /etc/systemd/system/guix-daemon.service",
+ "sudo mkdir /etc/guix",
+ "sudo mv /home/ubuntu/acl /etc/guix/acl",
+ "sudo groupadd --system guixbuild",
+ <<EOF
+for i in `seq -w 1 32`;
+do
+ sudo useradd -g guixbuild -G guixbuild \
+ -d /var/empty -s `which nologin` \
+ -c "Guix build user $i" --system \
+ guix$i;
+done
+EOF
+ ,
+ # Disable apparmor, as it seems to cause guile to segfault
+ # sometimes
+ "sudo systemctl stop apparmor",
+ "sudo service apparmor teardown",
+ "sudo systemctl disable apparmor",
+ "sudo systemctl daemon-reload",
+ "sudo systemctl enable guix-daemon.service",
+ "sudo systemctl start guix-daemon.service",
+ "sudo mkdir -p /var/guix/gcroots/govuk-development-data /var/guix/gcroots/govuk-mini-environment-admin",
+ "sudo chown ubuntu:ubuntu /var/guix/gcroots/govuk-development-data /var/guix/gcroots/govuk-mini-environment-admin",
+ "mkdir -p ~/.config", # Make the ~/.config directory, to ensure it's owned by ubuntu
+ # Setup the profile for the ubuntu user
+ <<EOF
+if [ ! -d "/var/guix/profiles/per-user/ubuntu" ]; then
+ # Install openssl and nss-certs so that downloads work for custom
+ # package versions, and guile-sqlite3
+ /var/guix/profiles/per-user/root/current-guix/bin/guix package --fallback -i glibc-locales guile bash openssl nss-certs guile-sqlite3
+fi
+EOF
+ ,
+ # This is needed for things like guix copy to work
+ <<EOF
+echo 'export GUIX_LOCPATH="$HOME/.guix-profile/lib/locale"
+
+GUIX_PROFILE=/home/ubuntu/.guix-profile; source /home/ubuntu/.guix-profile/etc/profile
+GUIX_PROFILE=/home/ubuntu/.config/guix/current; source /home/ubuntu/.config/guix/current/etc/profile
+' | cat - .bashrc > temp && mv temp .bashrc
+EOF
+ ]
+
+ connection {
+ type = "ssh"
+ user = "ubuntu"
+ private_key = "${var.ssh_private_key}"
+ }
+ }
+}
+
+resource "aws_route53_record" "main" {
+ zone_id = "${data.aws_route53_zone.main.zone_id}"
+ name = "builder.${var.backend_slug}"
+ type = "A"
+ ttl = "60"
+ records = ["${aws_spot_instance_request.main.public_ip}"]
+
+ depends_on = ["aws_spot_instance_request.main"]
+}
+
+# Outputs
+
+output "backend_up" {
+ value = "${length(aws_spot_instance_request.main.public_ip) != 0}"
+}
+
+output "deployer_key_pair_name" {
+ value = "${aws_key_pair.deployer.key_name}"
+}
+
+output "guix_client_security_group_name" {
+ value = "${aws_security_group.guix_client.name}"
+}
+
+output "public_webserver_security_group_name" {
+ value = "${aws_security_group.public_webserver.name}"
+}
+
+output "ssh_access_from_mini_environment_admin_security_group_name" {
+ value = "${aws_security_group.ssh_access_from_mini_environment_admin.name}"
+}
+
+output "guix_daemon_private_dns" {
+ value = "${aws_spot_instance_request.main.private_dns}"
+}
+
+output "guix_daemon_public_dns" {
+ value = "${aws_spot_instance_request.main.public_dns}"
+}
diff --git a/terraform/aws_using_ami/deploy/main.tf b/terraform/aws_using_ami/deploy/main.tf
new file mode 100644
index 0000000..6c39f9c
--- /dev/null
+++ b/terraform/aws_using_ami/deploy/main.tf
@@ -0,0 +1,7 @@
+
+
+# RDS instance running PostgreSQL
+
+# GuixSD server running the GOV.UK Mini Environment Admin
+
+
diff --git a/terraform/aws_using_ami/mini_environment/govuk.service.tpl b/terraform/aws_using_ami/mini_environment/govuk.service.tpl
new file mode 100644
index 0000000..5c65267
--- /dev/null
+++ b/terraform/aws_using_ami/mini_environment/govuk.service.tpl
@@ -0,0 +1,12 @@
+[Unit]
+Description=GOV.UK
+After=network.target
+
+[Service]
+Type=simple
+User=root
+WorkingDirectory=/home/ubuntu
+ExecStart=${start_command}
+
+[Install]
+WantedBy=multi-user.target
diff --git a/terraform/aws_using_ami/mini_environment/main.tf b/terraform/aws_using_ami/mini_environment/main.tf
new file mode 100644
index 0000000..40a8148
--- /dev/null
+++ b/terraform/aws_using_ami/mini_environment/main.tf
@@ -0,0 +1,164 @@
+terraform {
+ backend "http" {}
+}
+
+variable "slug" {
+ type = "string"
+}
+
+variable "aws_access_key" {
+ type = "string"
+}
+
+variable "aws_secret_key" {
+ type = "string"
+}
+
+variable "aws_region" {
+ type = "string"
+}
+
+variable "aws_route_53_zone_id" {
+ type = "string"
+}
+
+variable "start_command" {
+ type = "string"
+}
+
+variable "backend_remote_state_address" {
+ type = "string"
+}
+
+variable "backend_remote_state_username" {
+ type = "string"
+}
+
+variable "backend_remote_state_password" {
+ type = "string"
+}
+
+variable "ssh_private_key" {
+ type = "string"
+}
+
+provider "aws" {
+ access_key = "${var.aws_access_key}"
+ secret_key = "${var.aws_secret_key}"
+ region = "${var.aws_region}"
+}
+
+
+data "terraform_remote_state" "backend" {
+ backend = "http"
+ config {
+ address = "${var.backend_remote_state_address}"
+ username = "${var.backend_remote_state_username}"
+ password = "${var.backend_remote_state_password}"
+ }
+}
+
+data "aws_route53_zone" "main" {
+ zone_id = "${var.aws_route_53_zone_id}"
+}
+
+data "template_file" "govuk_service" {
+ template = "${file("${path.module}/govuk.service.tpl")}"
+
+ vars {
+ start_command = "${var.start_command}"
+ }
+}
+
+
+resource "aws_spot_instance_request" "main" {
+ ami = "ami-8fd760f6"
+ instance_type = "t2.xlarge"
+ key_name = "${data.terraform_remote_state.backend.deployer_key_pair_name}"
+ security_groups = [
+ "${data.terraform_remote_state.backend.guix_client_security_group_name}",
+ "${data.terraform_remote_state.backend.public_webserver_security_group_name}",
+ "${data.terraform_remote_state.backend.ssh_access_from_mini_environment_admin_security_group_name}"
+ ]
+
+ wait_for_fulfillment = true
+ spot_price = "0.21"
+ spot_type = "one-time"
+
+ root_block_device {
+ volume_size = "150"
+ }
+
+ provisioner "file" {
+ content = "${data.template_file.govuk_service.rendered}"
+ destination = "/home/ubuntu/govuk.service"
+
+ connection {
+ type = "ssh"
+ user = "ubuntu"
+ private_key = "${var.ssh_private_key}"
+ }
+ }
+
+ provisioner "remote-exec" {
+ inline = [
+ "sudo apt-get update",
+ "sudo apt-get update",
+ "sudo apt-get -y install nfs-common cachefilesd",
+ "sudo tune2fs -o user_xattr /dev/xvda1",
+ "sudo sed 's/#RUN/RUN/' -i /etc/default/cachefilesd",
+ "sudo mkdir -p /gnu/store",
+ "sudo mount -t nfs4 -o ro,nfsvers=4.1,rsize=1048576,wsize=1048576,hard,timeo=600,actimeo=600,fsc,nocto,retrans=2 ${data.terraform_remote_state.backend.efs_file_system_dns_name}:gnu/store /gnu/store",
+ "sudo mkdir -p /var/guix",
+ "sudo mount -t nfs4 -o nfsvers=4.1,rsize=1048576,wsize=1048576,hard,timeo=600,retrans=2 ${data.terraform_remote_state.backend.efs_file_system_dns_name}:var/guix /var/guix",
+ "echo \"export GUIX_DAEMON_SOCKET=guix://${data.terraform_remote_state.backend.guix_daemon_private_dns}\" | sudo tee /etc/profile.d/guix-daemon-socket.sh",
+ #"sudo systemctl restart cachefilesd",
+ "sudo iptables -A PREROUTING -t nat -i eth0 -p tcp --dport 80 -j REDIRECT --to-port 8080",
+ "sudo iptables -A PREROUTING -t nat -i eth0 -p tcp --dport 443 -j REDIRECT --to-port 8443",
+ "sudo iptables -A OUTPUT -t nat -o lo -p tcp --dport 80 -j REDIRECT --to-port 8080",
+ "sudo iptables -A OUTPUT -t nat -o lo -p tcp --dport 443 -j REDIRECT --to-port 8443",
+ "sudo mkdir -p /var/cache/govuk-mini-environment-admin /var/lib/govuk-mini-environment-admin /var/log/govuk-mini-environment-admin",
+ "sudo mv /home/ubuntu/govuk.service /etc/systemd/system/govuk.service",
+ "sudo systemctl daemon-reload",
+ "sudo systemctl enable govuk.service",
+ "sudo systemctl start govuk.service"
+ ]
+
+ connection {
+ type = "ssh"
+ user = "ubuntu"
+ private_key = "${var.ssh_private_key}"
+ }
+ }
+}
+
+resource "aws_route53_record" "main" {
+ zone_id = "${data.aws_route53_zone.main.zone_id}"
+ name = "${var.slug}"
+ type = "A"
+ ttl = "60"
+ records = ["${aws_spot_instance_request.main.public_ip}"]
+}
+
+resource "aws_route53_record" "wildcard" {
+ zone_id = "${data.aws_route53_zone.main.zone_id}"
+ name = "*.${var.slug}"
+ type = "A"
+ ttl = "60"
+ records = ["${aws_spot_instance_request.main.public_ip}"]
+}
+
+# Outputs
+
+output "spot_bid_status" {
+ value = "${aws_spot_instance_request.main.spot_bid_status}"
+}
+
+output "spot_request_status" {
+ value = "${aws_spot_instance_request.main.spot_request_state}"
+}
+
+output "mini_environment_up" {
+ value = "${aws_spot_instance_request.main.spot_bid_status == "fulfilled"}"
+}
+