diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 474d8d6de719bc11b2749c7d75b07a8434506492..dbb2c98571d0f7bdcb06e00c42cb385928dacd20 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,5 +1,10 @@ +variables: + 2019_CONTAINER_IMAGE=asia.gcr.io/linuxconfsydney/symposion_app_2019 + DOCKER_DRIVER: overlay2 + build_image: image: docker:git + stage: build services: - docker:dind script: @@ -30,21 +35,36 @@ k8s-prod-deploy: only: - master environment: - name: prod + name: 2019/prod url: https://rego.linux.conf.au +build_review_deployment: + image: sparkprime/jsonnet + services: + - docker:dind + stage: build + script: + - docker run -v ${PWD}/k8s:/src sparkprime/jsonnet /src/deployment_template.jsonnet --tla-str slug="${CI_COMMIT_REF_SLUG}" > ${CI_COMMIT_REF_SLUG}.json + artifacts: + paths: + - ${CI_COMMIT_REF_SLUG}.json + build_2019_dev_image: image: docker:git + stage: build services: - docker:dind script: - - docker build -f docker/Dockerfile -t asia.gcr.io/linuxconfsydney/symposion_app_2019:$CI_COMMIT_SHA . - - docker build --build-arg CI_COMMIT_SHA=$CI_COMMIT_SHA -f docker/Dockerfile.dev -t asia.gcr.io/linuxconfsydney/symposion_app_2019_dev:$CI_COMMIT_SHA . - docker login -u _json_key -p "$GOOGLE_KEY" https://asia.gcr.io - - docker push asia.gcr.io/linuxconfsydney/symposion_app_2019:$CI_COMMIT_SHA - - docker push asia.gcr.io/linuxconfsydney/symposion_app_2019_dev:$CI_COMMIT_SHA - - docker tag asia.gcr.io/linuxconfsydney/symposion_app_2019_dev:$CI_COMMIT_SHA asia.gcr.io/linuxconfsydney/symposion_app_2019_dev:latest - - docker push asia.gcr.io/linuxconfsydney/symposion_app_2019_dev:latest + - docker pull "${2019_CONTAINER_IMAGE}"_dev:latest || true + - docker build --cache-from "${2019_CONTAINER_IMAGE}"_dev:latest -f docker/Dockerfile -t "${2019_CONTAINER_IMAGE}":$CI_COMMIT_SHA . + - docker build --build-arg CI_COMMIT_SHA=$CI_COMMIT_SHA -f docker/Dockerfile.dev -t "${2019_CONTAINER_IMAGE}"_dev:$CI_COMMIT_SHA . + - docker push "${2019_CONTAINER_IMAGE}":$CI_COMMIT_SHA + - docker push "${2019_CONTAINER_IMAGE}"_dev:$CI_COMMIT_SHA + - docker tag "${2019_CONTAINER_IMAGE}"_dev:$CI_COMMIT_SHA "${2019_CONTAINER_IMAGE}"_dev:latest + - docker tag "${2019_CONTAINER_IMAGE}"_dev:$CI_COMMIT_SHA "${2019_CONTAINER_IMAGE}"_dev:$CI_COMMIT_REF_SLUG + - docker push "${2019_CONTAINER_IMAGE}"_dev:latest + - docker push "${2019_CONTAINER_IMAGE}"_dev:${CI_COMMIT_REF_SLUG} except: - master @@ -56,14 +76,46 @@ k8s-2019_dev-deploy: - kubectl config set-cluster cluster --server="${KUBE_SERVER}" --embed-certs=true --certificate-authority=cert.crt - kubectl config set-context cluster --cluster=cluster --namespace=rego-dev --user=gitlab-sa - kubectl config use-context cluster - - kubectl --token "${GL_KUBE_TOKEN}" set image deployment/symposion-app symposion-app=asia.gcr.io/linuxconfsydney/symposion_app_2019_dev:$CI_COMMIT_SHA + - kubectl --token "${GL_KUBE_TOKEN}" set image deployment/symposion-app symposion-app="${2019_CONTAINER_IMAGE}"_dev:$CI_COMMIT_SHA only: - dev/2019 - - dev/* environment: - name: dev_2019 + name: 2019/dev url: https://dev.lca2019.org +k8s-2019_dev_review-deploy: + image: google/cloud-sdk + stage: deploy + script: + - echo "${CA_CERT}" > cert.crt + - kubectl config set-cluster cluster --server="${KUBE_SERVER}" --embed-certs=true --certificate-authority=cert.crt + - kubectl config set-context cluster --cluster=cluster --namespace=rego-dev --user=gitlab-sa + - kubectl config use-context cluster + - kubectl --token "${GL_KUBE_TOKEN}" apply -f ${CI_COMMIT_REF_SLUG}.json + only: + - /^dev\/.*$/ + environment: + name: 2019/dev/${CI_COMMIT_REF_SLUG} + url: https://${CI_COMMIT_REF_SLUG}.dev.lca2019.org + on_stop: k8s-2019_dev_review-stop-deploy + +k8s-2019_dev_review-stop-deploy: + image: google/cloud-sdk + stage: deploy + script: + - echo "${CA_CERT}" > cert.crt + - kubectl config set-cluster cluster --server="${KUBE_SERVER}" --embed-certs=true --certificate-authority=cert.crt + - kubectl config set-context cluster --cluster=cluster --namespace=rego-dev --user=gitlab-sa + - kubectl config use-context cluster + - kubectl --token "${GL_KUBE_TOKEN}" delete -f ${CI_COMMIT_REF_SLUG}.json + only: + - /^dev\/.*$/ + when: manual + environment: + name: 2019/dev/${CI_COMMIT_REF_SLUG} + url: https://${CI_COMMIT_REF_SLUG}.dev.lca2019.org + action: stop + k8s-2019_staging-deploy: image: google/cloud-sdk stage: deploy @@ -72,12 +124,12 @@ k8s-2019_staging-deploy: - kubectl config set-cluster cluster --server="${KUBE_SERVER}" --embed-certs=true --certificate-authority=cert.crt - kubectl config set-context cluster --cluster=cluster --namespace=lca2019-staging --user=gitlab-ci - kubectl config use-context cluster - - kubectl --token "${GL_KUBE_TOKEN}" set image deployment/symposion-app symposion-app=asia.gcr.io/linuxconfsydney/symposion_app_2019_dev:$CI_COMMIT_SHA + - kubectl --token "${GL_KUBE_TOKEN}" set image deployment/symposion-app symposion-app="${2019_CONTAINER_IMAGE}"_dev:$CI_COMMIT_SHA when: manual only: - dev/2019 environment: - name: staging + name: 2019/staging url: https://staging.lca2019.org .docs_template: &sphinx @@ -101,6 +153,6 @@ pages: name: docs url: https://laconfdev.gitlab.io/symposion_app/ -test_sphinx: +build_sphinx: <<: *sphinx - stage: test + stage: build diff --git a/k8s/deployment_template.jsonnet b/k8s/deployment_template.jsonnet new file mode 100644 index 0000000000000000000000000000000000000000..61f35ba591f8eb4ce2498ca910d4ae34af43e47a --- /dev/null +++ b/k8s/deployment_template.jsonnet @@ -0,0 +1,237 @@ +function (slug) { + + local namespace = slug + "-rego-dev", + local domain = slug + ".dev.lca2019.org", + local tls_certname = slug + "-dev-lca2019-org", + local tls_secret = tls_certname + "-tls", + + "apiVersion": "v1", + "items": [ + { + "apiVersion": "v1", + "kind": "Namespace", + "metadata": { + "name": namespace, + "namespace": "", + }, + "spec": { + "finalizers": [ + "kubernetes" + ] + } + }, + { + "apiVersion": "certmanager.k8s.io/v1alpha1", + "kind": "Certificate", + "metadata": { + "name": tls_certname, + "namespace": namespace + }, + "spec": { + "acme": { + "config": [ + { + "domains": [ + domain + ], + "http01": { + "ingress": "", + "ingressClass": "nginx" + } + } + ] + }, + "commonName": domain, + "issuerRef": { + "kind": "ClusterIssuer", + "name": "letsencrypt-prod" + }, + "secretName": tls_secret + } + }, + { + "apiVersion": "extensions/v1beta1", + "kind": "Ingress", + "metadata": { + "name": "symposion-app-ingress", + "namespace": namespace + }, + "spec": { + "backend": { + "serviceName": "symposion-app", + "servicePort": 80 + }, + "rules": [ + { + "host": domain, + "http": { + "paths": [ + { + "backend": { + "serviceName": "symposion-app", + "servicePort": 8000 + }, + "path": "/" + } + ] + } + } + ], + "tls": [ + { + "hosts": [ + domain + ], + "secretName": tls_secret + } + ] + }, + "status": { + "loadBalancer": { + "ingress": [ + { + "ip": "127.0.0.1" + } + ] + } + } + }, + { + "apiVersion": "v1", + "kind": "Service", + "metadata": { + "labels": { + "app": "symposion-app" + }, + "name": "symposion-app", + "namespace": namespace + }, + "spec": { + "ports": [ + { + "port": 8000, + "protocol": "TCP", + "targetPort": 8000 + } + ], + "selector": { + "app": "symposion-app" + }, + "sessionAffinity": "None", + "type": "ClusterIP" + }, + "status": { + "loadBalancer": {} + } + }, + { + "apiVersion": "extensions/v1beta1", + "kind": "Deployment", + "metadata": { + "labels": { + "app": "symposion-app" + }, + "name": "symposion-app", + "namespace": namespace + }, + "spec": { + "replicas": 1, + "revisionHistoryLimit": 1, + "selector": { + "matchLabels": { + "app": "symposion-app" + } + }, + "strategy": { + "rollingUpdate": { + "maxSurge": 1, + "maxUnavailable": 1 + }, + "type": "RollingUpdate" + }, + "template": { + "metadata": { + "labels": { + "app": "symposion-app" + } + }, + "spec": { + "containers": [ + { + "env": [ + { + "name": "SYMPOSION_APP_DEBUG", + "value": "1" + }, + { + "name": "DJANGO_SECRET_KEY", + "value": "paGhahQuain5ohYoh0moorai" + }, + { + "name": "DATABASE_URL", + "value": "sqlite:////tmp/symposion.sqlite" + }, + { + "name": "GCS_BUCKET", + "value": "CEA51A5-A613-4AEF-A9FB-D0A57D77C13B" + }, + { + "name": "GOOGLE_APPLICATION_CREDENTIALS", + "value": "/dev/null" + }, + { + "name": "STRIPE_PUBLIC_KEY", + "value": "5CEA51A5-A613-4AEF-A9FB-D0A57D77C13B" + }, + { + "name": "STRIPE_SECRET_KEY", + "value": "5CEA51A5-A613-4AEF-A9FB-D0A57D77C13B" + }, + ], + "image": "asia.gcr.io/linuxconfsydney/symposion_app_2019_dev:" + slug, + "imagePullPolicy": "Always", + "livenessProbe": { + "failureThreshold": 3, + "httpGet": { + "path": "/admin/login/", + "port": 8000, + "scheme": "HTTP" + }, + "initialDelaySeconds": 120, + "periodSeconds": 10, + "successThreshold": 1, + "timeoutSeconds": 2 + }, + "name": "symposion-app", + "ports": [ + { + "containerPort": 8000, + "protocol": "TCP" + } + ], + "resources": {}, + "terminationMessagePath": "/dev/termination-log", + "terminationMessagePolicy": "File" + } + ], + "dnsPolicy": "ClusterFirst", + "restartPolicy": "Always", + "schedulerName": "default-scheduler", + "securityContext": {}, + "terminationGracePeriodSeconds": 30, + "volumes": [ + { + "hostPath": { + "path": "/etc/ssl/certs", + "type": "" + }, + "name": "ssl-certs" + } + ] + } + } + } + } + ], + "kind": "List" +}