about summary refs log tree commit diff
path: root/infra
diff options
context:
space:
mode:
Diffstat (limited to 'infra')
-rwxr-xr-xinfra/dns/import11
-rw-r--r--infra/dns/kontemplate-works15
-rw-r--r--infra/dns/oslo-pub8
-rw-r--r--infra/dns/root-tazj-in28
-rw-r--r--infra/gcp/.gitignore3
-rw-r--r--infra/gcp/default.tf103
-rw-r--r--infra/kubernetes/gemma/config.lisp19
-rw-r--r--infra/kubernetes/https-cert/cert.yaml8
-rw-r--r--infra/kubernetes/https-lb/ingress.yaml24
-rw-r--r--infra/kubernetes/nginx/nginx.conf43
-rw-r--r--infra/kubernetes/nginx/nginx.yaml55
-rw-r--r--infra/kubernetes/nixery/config.yaml67
-rw-r--r--infra/kubernetes/nixery/id_nixery.pub1
-rw-r--r--infra/kubernetes/nixery/known_hosts2
-rw-r--r--infra/kubernetes/nixery/secrets.yaml18
-rw-r--r--infra/kubernetes/nixery/ssh_config4
-rw-r--r--infra/kubernetes/primary-cluster.yaml33
-rw-r--r--infra/kubernetes/tazblog/config.yaml34
18 files changed, 476 insertions, 0 deletions
diff --git a/infra/dns/import b/infra/dns/import
new file mode 100755
index 000000000000..e79e426b5553
--- /dev/null
+++ b/infra/dns/import
@@ -0,0 +1,11 @@
+#!/bin/sh
+set -ue
+
+# Imports a zone file into a Google Cloud DNS zone of the same name
+readonly ZONE="${1}"
+
+gcloud dns record-sets import "${ZONE}" \
+       --project composite-watch-759 \
+       --zone-file-format \
+       --delete-all-existing \
+       --zone "${ZONE}"
diff --git a/infra/dns/kontemplate-works b/infra/dns/kontemplate-works
new file mode 100644
index 000000000000..326a129d2105
--- /dev/null
+++ b/infra/dns/kontemplate-works
@@ -0,0 +1,15 @@
+;;  -*- mode: zone; -*-
+;; Do not delete these
+kontemplate.works. 21600 IN NS ns-cloud-d1.googledomains.com.
+kontemplate.works. 21600 IN NS ns-cloud-d2.googledomains.com.
+kontemplate.works. 21600 IN NS ns-cloud-d3.googledomains.com.
+kontemplate.works. 21600 IN NS ns-cloud-d4.googledomains.com.
+kontemplate.works. 21600 IN SOA ns-cloud-d1.googledomains.com. cloud-dns-hostmaster.google.com. 4 21600 3600 259200 300
+
+;; Github site setup
+kontemplate.works. 60 IN A 185.199.108.153
+kontemplate.works. 60 IN A 185.199.109.153
+kontemplate.works. 60 IN A 185.199.110.153
+kontemplate.works. 60 IN A 185.199.111.153
+
+www.kontemplate.works. 60 IN CNAME tazjin.github.io.
diff --git a/infra/dns/oslo-pub b/infra/dns/oslo-pub
new file mode 100644
index 000000000000..674687484b90
--- /dev/null
+++ b/infra/dns/oslo-pub
@@ -0,0 +1,8 @@
+;; Do not delete these
+oslo.pub. 21600 IN NS ns-cloud-c1.googledomains.com.
+oslo.pub. 21600 IN NS ns-cloud-c2.googledomains.com.
+oslo.pub. 21600 IN NS ns-cloud-c3.googledomains.com.
+oslo.pub. 21600 IN NS ns-cloud-c4.googledomains.com.
+oslo.pub. 21600 IN SOA ns-cloud-c1.googledomains.com. cloud-dns-hostmaster.google.com. 4 21600 3600 1209600 300
+
+oslo.pub. 60 IN A 46.21.106.241
diff --git a/infra/dns/root-tazj-in b/infra/dns/root-tazj-in
new file mode 100644
index 000000000000..80ea9e298e70
--- /dev/null
+++ b/infra/dns/root-tazj-in
@@ -0,0 +1,28 @@
+;; Do not delete these
+tazj.in. 21600 IN NS ns-cloud-a1.googledomains.com.
+tazj.in. 21600 IN NS ns-cloud-a2.googledomains.com.
+tazj.in. 21600 IN NS ns-cloud-a3.googledomains.com.
+tazj.in. 21600 IN NS ns-cloud-a4.googledomains.com.
+tazj.in. 21600 IN SOA ns-cloud-a1.googledomains.com. cloud-dns-hostmaster.google.com. 109 21600 3600 1209600 300
+
+;; Email setup
+tazj.in. 300 IN MX 10 mx.runbox.com.
+tazj.in. 300 IN TXT "v=spf1 redirect=spf.runbox.com"
+
+;; Site verifications
+tazj.in. 3600 IN TXT "keybase-site-verification=gC4kzEmnLzY7F669PjN-pw2Cf__xHqcxQ08Gb-W9dhE"
+tazj.in. 3600 IN TXT "google-site-verification=8ila9SmLtwSOlciHpmst-RG_Z-peiV5PevEVyaeL0Z0"
+tazj.in. 3600 IN TXT "detectify-verification=b2eab87b05e615c13d8907d47eddfcad"
+www.tazj.in. 3600 IN TXT "keybase-site-verification=ER8m_byyqAhzeIy9TyzkAU1H2p2yHtpvImuB_XrRF2U"
+
+;; Webpage records setup
+tazj.in. 300 IN A 46.21.106.241
+www.tazj.in. 300 IN A 46.21.106.241
+git.tazj.in. 300 IN A 46.21.106.241
+gemma.tazj.in. 300 IN A 46.21.106.241
+
+files.tazj.in. 300 IN CNAME c.storage.googleapis.com.
+ip.tazj.in. 300 IN A 104.155.119.229
+
+;; GleSYS machines
+sto-tazserve-1.tazj.in. 300 IN A 46.21.106.241
diff --git a/infra/gcp/.gitignore b/infra/gcp/.gitignore
new file mode 100644
index 000000000000..96c7538dda8a
--- /dev/null
+++ b/infra/gcp/.gitignore
@@ -0,0 +1,3 @@
+.terraform
+*.tfstate
+*.tfstate.backup
diff --git a/infra/gcp/default.tf b/infra/gcp/default.tf
new file mode 100644
index 000000000000..d13345393bd4
--- /dev/null
+++ b/infra/gcp/default.tf
@@ -0,0 +1,103 @@
+# Terraform configuration for the GCP project 'tazjins-infrastructure'
+
+provider "google" {
+  project = "tazjins-infrastructure"
+  region  = "europe-north1"
+}
+
+# Configure a storage bucket in which to keep Terraform state and
+# other data, such as Nixery's layers.
+resource "google_storage_bucket" "tazjins-data" {
+  name     = "tazjins-data"
+  location = "EU"
+}
+
+terraform {
+  backend "gcs" {
+    bucket = "tazjins-data"
+    prefix = "terraform"
+  }
+}
+
+# Configure enabled APIs
+resource "google_project_services" "primary" {
+  project = "tazjins-infrastructure"
+  services = [
+    "bigquery-json.googleapis.com",
+    "bigquerystorage.googleapis.com",
+    "cloudapis.googleapis.com",
+    "clouddebugger.googleapis.com",
+    "cloudkms.googleapis.com",
+    "cloudtrace.googleapis.com",
+    "compute.googleapis.com",
+    "container.googleapis.com",
+    "containerregistry.googleapis.com",
+    "datastore.googleapis.com",
+    "dns.googleapis.com",
+    "iam.googleapis.com",
+    "iamcredentials.googleapis.com",
+    "logging.googleapis.com",
+    "monitoring.googleapis.com",
+    "oslogin.googleapis.com",
+    "pubsub.googleapis.com",
+    "servicemanagement.googleapis.com",
+    "serviceusage.googleapis.com",
+    "sourcerepo.googleapis.com",
+    "sql-component.googleapis.com",
+    "storage-api.googleapis.com",
+    "storage-component.googleapis.com",
+  ]
+}
+
+
+# Configure the main Kubernetes cluster in which services are deployed
+resource "google_container_cluster" "primary" {
+  name     = "tazjin-cluster"
+  location = "europe-north1"
+
+  remove_default_node_pool = true
+  initial_node_count       = 1
+}
+
+resource "google_container_node_pool" "primary_nodes" {
+  name       = "primary-nodes"
+  location   = "europe-north1"
+  cluster    = google_container_cluster.primary.name
+  node_count = 1
+
+  node_config {
+    preemptible  = true
+    machine_type = "n1-standard-2"
+
+    oauth_scopes = [
+      "storage-rw",
+      "logging-write",
+      "monitoring",
+    ]
+  }
+}
+
+# Configure a service account for which GCS URL signing keys can be created.
+resource "google_service_account" "nixery" {
+  account_id   = "nixery"
+  display_name = "Nixery service account"
+}
+
+# Configure Cloud KMS for secret encryption
+resource "google_kms_key_ring" "tazjins_keys" {
+  name     = "tazjins-keys"
+  location = "europe-north1"
+
+  lifecycle {
+    prevent_destroy = true
+  }
+}
+
+resource "google_kms_crypto_key" "kontemplate_key" {
+  name     = "kontemplate-key"
+  key_ring = google_kms_key_ring.tazjins_keys.id
+
+  lifecycle {
+    prevent_destroy = true
+  }
+}
diff --git a/infra/kubernetes/gemma/config.lisp b/infra/kubernetes/gemma/config.lisp
new file mode 100644
index 000000000000..517a658cf150
--- /dev/null
+++ b/infra/kubernetes/gemma/config.lisp
@@ -0,0 +1,19 @@
+(config :port 4242
+        :data-dir "/var/lib/gemma/")
+
+(deftask bathroom/wipe-mirror 7)
+(deftask bathroom/wipe-counter 7)
+
+;; Bedroom tasks
+(deftask bedroom/change-sheets 7)
+(deftask bedroom/vacuum 10)
+
+;; Kitchen tasks
+(deftask kitchen/normal-trash 3)
+(deftask kitchen/green-trash 5)
+(deftask kitchen/blue-trash 5)
+(deftask kitchen/wipe-counters 3)
+(deftask kitchen/vacuum 5 "Kitchen has more crumbs and such!")
+
+;; Entire place
+(deftask clean-windows 60)
diff --git a/infra/kubernetes/https-cert/cert.yaml b/infra/kubernetes/https-cert/cert.yaml
new file mode 100644
index 000000000000..c7a85275ae67
--- /dev/null
+++ b/infra/kubernetes/https-cert/cert.yaml
@@ -0,0 +1,8 @@
+---
+apiVersion: networking.gke.io/v1beta1
+kind: ManagedCertificate
+metadata:
+  name: {{ .domain | replace "." "-" }}
+spec:
+  domains:
+    - {{ .domain }}
diff --git a/infra/kubernetes/https-lb/ingress.yaml b/infra/kubernetes/https-lb/ingress.yaml
new file mode 100644
index 000000000000..f1d9fa4270b0
--- /dev/null
+++ b/infra/kubernetes/https-lb/ingress.yaml
@@ -0,0 +1,24 @@
+# This resource configures the HTTPS load balancer that is used as the
+# entrypoint to all HTTPS services running in the cluster.
+---
+apiVersion: extensions/v1beta1
+kind: Ingress
+metadata:
+  name: https-ingress
+  annotations:
+    networking.gke.io/managed-certificates: tazj-in, www-tazj-in, oslo-pub
+spec:
+  # Default traffic is routed to the blog, in case people go to
+  # peculiar hostnames.
+  backend:
+    serviceName: tazblog
+    servicePort: 8000
+  rules:
+    # Route oslo.pub to the nginx instance which serves redirects
+    - host: oslo.pub
+      http:
+        paths:
+          - path: /
+            backend:
+              serviceName: nginx
+              servicePort: 6756
diff --git a/infra/kubernetes/nginx/nginx.conf b/infra/kubernetes/nginx/nginx.conf
new file mode 100644
index 000000000000..5a008a0b953f
--- /dev/null
+++ b/infra/kubernetes/nginx/nginx.conf
@@ -0,0 +1,43 @@
+daemon off;
+worker_processes  1;
+error_log stderr;
+
+events {
+    worker_connections  1024;
+}
+
+http {
+    log_format json_combined escape=json
+    '{'
+        '"time_local":"$time_local",'
+        '"remote_addr":"$remote_addr",'
+        '"remote_user":"$remote_user",'
+        '"request":"$request",'
+        '"status": "$status",'
+        '"body_bytes_sent":"$body_bytes_sent",'
+        '"request_time":"$request_time",'
+        '"http_referrer":"$http_referer",'
+        '"http_user_agent":"$http_user_agent"'
+        '}';
+
+    access_log /dev/stdout json_combined;
+
+    sendfile        on;
+    keepalive_timeout  65;
+
+    server {
+        listen 80 default_server;
+        location / {
+            return 200 "ok";
+        }
+    }
+
+    server {
+        listen       80;
+        server_name  oslo.pub;
+
+        location / {
+            return 302 https://www.google.com/maps/d/viewer?mid=1pJIYY9cuEdt9DuMTbb4etBVq7hs;
+        }
+    }
+}
diff --git a/infra/kubernetes/nginx/nginx.yaml b/infra/kubernetes/nginx/nginx.yaml
new file mode 100644
index 000000000000..d0ee520d2734
--- /dev/null
+++ b/infra/kubernetes/nginx/nginx.yaml
@@ -0,0 +1,55 @@
+# Deploy an nginx instance which serves ... redirects.
+---
+apiVersion: v1
+kind: ConfigMap
+metadata:
+  name: nginx-conf
+data:
+  nginx.conf: {{ insertFile "nginx.conf" | toJson }}
+---
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+  name: nginx
+  labels:
+    app: nginx
+spec:
+  replicas: 2
+  selector:
+    matchLabels:
+      app: nginx
+  template:
+    metadata:
+      labels:
+        app: nginx
+        config: {{ insertFile "nginx.conf" | sha1sum }}
+    spec:
+      containers:
+        - name: tazblog
+          image: nixery.local/shell/nginx:{{ .version }}
+          command: ["/bin/bash", "-c"]
+          args:
+            - |
+              echo 'nogroup:x:30000:nobody' >> /etc/group
+              echo 'nobody:x:30000:30000:nobody:/tmp:/bin/bash' >> /etc/passwd
+              exec nginx -c /etc/nginx/nginx.conf
+          volumeMounts:
+            - name: nginx-conf
+              mountPath: /etc/nginx
+      volumes:
+        - name: nginx-conf
+          configMap:
+            name: nginx-conf
+---
+apiVersion: v1
+kind: Service
+metadata:
+  name: nginx
+spec:
+  type: NodePort
+  selector:
+    app: nginx
+  ports:
+    - protocol: TCP
+      port: 6756
+      targetPort: 80
diff --git a/infra/kubernetes/nixery/config.yaml b/infra/kubernetes/nixery/config.yaml
new file mode 100644
index 000000000000..0775e79b5843
--- /dev/null
+++ b/infra/kubernetes/nixery/config.yaml
@@ -0,0 +1,67 @@
+# Deploys an instance of Nixery into the cluster.
+#
+# The service via which Nixery is exposed has a private DNS entry
+# pointing to it, which makes it possible to resolve `nixery.local`
+# in-cluster without things getting nasty.
+---
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+  name: nixery
+  namespace: kube-public
+  labels:
+    app: nixery
+spec:
+  replicas: 1
+  selector:
+    matchLabels:
+      app: nixery
+  template:
+    metadata:
+      labels:
+        app: nixery
+    spec:
+      containers:
+      - name: nixery
+        image: eu.gcr.io/tazjins-infrastructure/nixery:{{ .version }}
+        volumeMounts:
+          - name: nixery-secrets
+            mountPath: /var/nixery
+        env:
+          - name: BUCKET
+            value: {{ .bucket}}
+          - name: PORT
+            value: "{{ .port }}"
+          - name: GOOGLE_APPLICATION_CREDENTIALS
+            value: /var/nixery/gcs-key.json
+          - name: GCS_SIGNING_KEY
+            value: /var/nixery/gcs-key.pem
+          - name: GCS_SIGNING_ACCOUNT
+            value: {{ .account }}
+          - name: GIT_SSH_COMMAND
+            value: 'ssh -F /var/nixery/ssh_config'
+          - name: NIXERY_PKGS_REPO
+            value: {{ .repo }}
+          - name: NIX_POPULARITY_URL
+            value: 'https://storage.googleapis.com/nixery-layers/popularity/{{ .popularity }}'
+      volumes:
+        - name: nixery-secrets
+          secret:
+            secretName: nixery-secrets
+            defaultMode: 256
+---
+apiVersion: v1
+kind: Service
+metadata:
+  name: nixery
+  namespace: kube-public
+  annotations:
+    cloud.google.com/load-balancer-type: "Internal"
+spec:
+  selector:
+    app: nixery
+  type: LoadBalancer
+  ports:
+  - protocol: TCP
+    port: 80
+    targetPort: 8080
diff --git a/infra/kubernetes/nixery/id_nixery.pub b/infra/kubernetes/nixery/id_nixery.pub
new file mode 100644
index 000000000000..dc3fd617d0a1
--- /dev/null
+++ b/infra/kubernetes/nixery/id_nixery.pub
@@ -0,0 +1 @@
+ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCzBM6ydst77jDHNcTFWKD9Fw4SReqyNEEp2MtQBk2wt94U4yLp8MQIuNeOEn1GaDEX4RGCxqai/2UVF1w9ZNdU+v2fXcKWfkKuGQH2XcNfXor2cVNObd40H78++iZiv3nmM/NaEdkTbTBbi925cRy9u5FgItDgsJlyKNRglCb0fr6KlgpvWjL20dp/eeZ8a/gLniHK8PnEsgERQSvJnsyFpxxVhxtoUiyLWpXDl4npf/rQr0eRDf4Q5sN/nbTwksapPHfze8dKcaoA7A2NqT3bJ6DPGrwVCzGRtGw/SXJwFwmmtAl9O6BklpeReyiknSxc+KOtrjDW6O0r6yvymD5Z nixery
diff --git a/infra/kubernetes/nixery/known_hosts b/infra/kubernetes/nixery/known_hosts
new file mode 100644
index 000000000000..6a2f84b5fb60
--- /dev/null
+++ b/infra/kubernetes/nixery/known_hosts
@@ -0,0 +1,2 @@
+github.com ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAq2A7hRGmdnm9tUDbO9IDSwBK6TbQa+PXYPCPy6rbTrTtw7PHkccKrpp0yVhp5HdEIcKr6pLlVDBfOLX9QUsyCOV0wzfjIJNlGEYsdlLJizHhbn2mUjvSAHQqZETYP81eFzLQNnPHt4EVVUh7VfDESU84KezmD5QlWpXLmvU31/yMf+Se8xhHTvKSCZIFImWwoG6mbUoWf9nzpIoaSjB+weqqUUmpaaasXVal72J+UX2B+2RPW3RcT0eOzQgqlJL3RKrTJvdsjE3JEAvGq3lGHSZXy28G3skua2SmVi/w4yCE6gbODqnTWlg7+wC604ydGXA8VJiS5ap43JXiUFFAaQ==
+140.82.118.4 ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAq2A7hRGmdnm9tUDbO9IDSwBK6TbQa+PXYPCPy6rbTrTtw7PHkccKrpp0yVhp5HdEIcKr6pLlVDBfOLX9QUsyCOV0wzfjIJNlGEYsdlLJizHhbn2mUjvSAHQqZETYP81eFzLQNnPHt4EVVUh7VfDESU84KezmD5QlWpXLmvU31/yMf+Se8xhHTvKSCZIFImWwoG6mbUoWf9nzpIoaSjB+weqqUUmpaaasXVal72J+UX2B+2RPW3RcT0eOzQgqlJL3RKrTJvdsjE3JEAvGq3lGHSZXy28G3skua2SmVi/w4yCE6gbODqnTWlg7+wC604ydGXA8VJiS5ap43JXiUFFAaQ==
diff --git a/infra/kubernetes/nixery/secrets.yaml b/infra/kubernetes/nixery/secrets.yaml
new file mode 100644
index 000000000000..d9a674d2c9fc
--- /dev/null
+++ b/infra/kubernetes/nixery/secrets.yaml
@@ -0,0 +1,18 @@
+# The secrets below are encrypted using keys stored in Cloud KMS and
+# templated in by kontemplate when deploying.
+#
+# Not all of the values are actually secret (see the matching)
+---
+apiVersion: v1
+kind: Secret
+metadata:
+  name: nixery-secrets
+  namespace: kube-public
+type: Opaque
+data:
+  gcs-key.json: {{ passLookup "nixery-gcs-json" | b64enc }}
+  gcs-key.pem: {{ passLookup "nixery-gcs-pem" | b64enc }}
+  id_nixery: {{ printf "%s\n" (passLookup "nixery-ssh-private") | b64enc }}
+  id_nixery.pub: {{ insertFile "id_nixery.pub" | b64enc }}
+  known_hosts: {{ insertFile "known_hosts" | b64enc }}
+  ssh_config: {{ insertFile "ssh_config" | b64enc }}
diff --git a/infra/kubernetes/nixery/ssh_config b/infra/kubernetes/nixery/ssh_config
new file mode 100644
index 000000000000..78afbb0b039d
--- /dev/null
+++ b/infra/kubernetes/nixery/ssh_config
@@ -0,0 +1,4 @@
+Match host *
+      User tazjin@google.com
+      IdentityFile /var/nixery/id_nixery
+      UserKnownHostsFile /var/nixery/known_hosts
diff --git a/infra/kubernetes/primary-cluster.yaml b/infra/kubernetes/primary-cluster.yaml
new file mode 100644
index 000000000000..bb1a6b2b0531
--- /dev/null
+++ b/infra/kubernetes/primary-cluster.yaml
@@ -0,0 +1,33 @@
+# Kontemplate configuration for the primary GKE cluster in the project
+# 'tazjins-infrastructure'.
+---
+context: gke_tazjins-infrastructure_europe-north1_tazjin-cluster
+include:
+  # SSL certificates (provisioned by Google)
+  - name: tazj-in-cert
+    path: https-cert
+    values:
+      domain: tazj.in
+  - name: www-tazj-in-cert
+    path: https-cert
+    values:
+      domain: www.tazj.in
+  - name: oslo-pub-cert
+    path: https-cert
+    values:
+      domain: oslo.pub
+
+  # Services
+  - name: nixery
+    values:
+      port: 8080
+      version: as6056ijn2scvzq8n1i2nlqwc5kddp1s
+      bucket: tazjins-data
+      account: nixery@tazjins-infrastructure.iam.gserviceaccount.com
+      repo: git@github.com:tazjin/depot.git
+      popularity: 'popularity-19.09.891.80b42e630b2.json'
+  - name: tazblog
+  - name: https-lb
+  - name: nginx
+    values:
+      version: 52fabe4423095f12f67be1c7dbf88b801c1bb521
diff --git a/infra/kubernetes/tazblog/config.yaml b/infra/kubernetes/tazblog/config.yaml
new file mode 100644
index 000000000000..165a30f6839b
--- /dev/null
+++ b/infra/kubernetes/tazblog/config.yaml
@@ -0,0 +1,34 @@
+---
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+  name: tazblog
+  labels:
+    app: tazblog
+spec:
+  replicas: 2
+  selector:
+    matchLabels:
+      app: tazblog
+  template:
+    metadata:
+      labels:
+        app: tazblog
+    spec:
+      containers:
+      - name: tazblog
+        image: nixery.local/shell/services.tazblog:{{ gitHEAD }}
+        command: [ "tazblog" ]
+---
+apiVersion: v1
+kind: Service
+metadata:
+  name: tazblog
+spec:
+  type: NodePort
+  selector:
+    app: tazblog
+  ports:
+    - protocol: TCP
+      port: 8000
+      targetPort: 8000