Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save amackiewicz/4be0792c927f60af4aaf196e4341ceeb to your computer and use it in GitHub Desktop.
Save amackiewicz/4be0792c927f60af4aaf196e4341ceeb to your computer and use it in GitHub Desktop.
gitlab pipeline for (un)deployment of gcp cloud functions using monorepo. integrated with vault
# Pipeline allows to manage gcp cloud functions deployment and undeployments via git repository
# Required gcp permissions:
# * cloudfunctions.functions.create
# * cloudfunctions.functions.delete
# * cloudfunctions.functions.get
# * cloudfunctions.functions.sourceCodeSet
# * cloudfunctions.functions.update
# * cloudfunctions.operations.get
image: "xxx"
stages:
- deploy
- admin
variables:
INTERACTIVE: "false"
VAULT_ADDR: $VAULT_ADDR
VAULT_TOKEN: $VAULT_TOKEN
GCP_PROJECT_PRODUCTION: xxx
GCP_PROJECT_LATEST: yyy
RUNTIME_SERVICE_ACCOUNT_PRODUCTION_EMAIL: xxx@xxx.iam.gserviceaccount.com
RUNTIME_SERVICE_ACCOUNT_LATEST_EMAIL: yyy@yyy.iam.gserviceaccount.com
services:
- name: docker:dind
.authenticate-gcloud:
before_script:
- export GOOGLE_CREDENTIALS=$(echo $BASE64_GCP_SERVICE_ACCOUNT | base64 -d)
- echo $GOOGLE_CREDENTIALS > gcloud-service-key.json
- gcloud auth activate-service-account --key-file gcloud-service-key.json
- gcloud auth configure-docker
.deploy-environment:
script:
- |
vault kv get -format=yaml -field=data kv/platform/${ENV}/cloud-functions > .env.${ENV}.yaml
for dir in $(git diff --name-only HEAD~ | awk -F "/*[^/]*/*$" '{ print ($1 == "" ? "." : $1); }' | sort | uniq); do
echo "Detected change in ${dir}"
if [[ "${dir}" != ${ENV}/* ]]; then
echo "Changed directory does not start with ${ENV}/, so skip"
continue
fi
function_name=$(basename "${dir}")
if [ ! -d "${dir}" ]; then
echo "🗑️ Undeploying ${function_name}.."
gcloud functions delete ${function_name} \
--region=europe-west6 \
--project ${GCP_PROJECT}
else
echo "🚀 Deploying ${function_name}.."
source "${dir}/.env.gcp"
rm -f "${dir}/.env.gcp" "${dir}/.env"
gcloud functions deploy ${function_name} \
--region=europe-west6 \
--project ${GCP_PROJECT} \
--runtime=${RUNTIME:-nodejs18} \
--entry-point=${function_name} \
--source=./${dir} \
--memory ${MEMORY:-128M} \
--timeout ${TIMEOUT:-60s} \
--min-instances ${MIN_INSTANCES:-0} \
--max-instances ${MAX_INSTANCES:-1} \
--trigger-${TRIGGER:-http} \
--service-account=${RUNTIME_SERVICE_ACCOUNT} \
--env-vars-file=.env.${ENV}.yaml
fi
done
.deploy-all:
script:
- |
vault kv get -format=yaml -field=data kv/platform/${ENV}/cloud-functions > .env.${ENV}.yaml
for dir in $(find ./${ENV} -mindepth 1 -maxdepth 1 -type d) ; do
function_name=$(basename "${dir}")
echo "🚀 Deploying ${function_name}.."
source "${dir}/.env.gcp"
rm -f "${dir}/.env.gcp" "${dir}/.env"
gcloud functions deploy ${function_name} \
--region=europe-west6 \
--project ${GCP_PROJECT} \
--runtime=${RUNTIME:-nodejs18} \
--entry-point=${function_name} \
--source=./${dir} \
--memory ${MEMORY:-128M} \
--timeout ${TIMEOUT:-60s} \
--min-instances ${MIN_INSTANCES:-0} \
--max-instances ${MAX_INSTANCES:-1} \
--trigger-${TRIGGER:-http} \
--service-account=${RUNTIME_SERVICE_ACCOUNT} \
--env-vars-file=.env.${ENV}.yaml
done
deploy-latest:
stage: deploy
environment: latest
variables:
BASE64_GCP_SERVICE_ACCOUNT: $BASE64_GOOGLE_CREDENTIALS_LATEST
GCP_PROJECT: $GCP_PROJECT_LATEST
ENV: latest
RUNTIME_SERVICE_ACCOUNT: $RUNTIME_SERVICE_ACCOUNT_LATEST_EMAIL
rules:
- if: $CI_PIPELINE_SOURCE == "pipeline"
when: never
- if: $CI_COMMIT_BRANCH == "master"
changes:
- latest/**/*
when: always
extends:
- .authenticate-gcloud
- .deploy-environment
deploy-production:
stage: deploy
environment: production
variables:
BASE64_GCP_SERVICE_ACCOUNT: $BASE64_GOOGLE_CREDENTIALS_PROD
GCP_PROJECT: $GCP_PROJECT_PRODUCTION
ENV: production
RUNTIME_SERVICE_ACCOUNT: $RUNTIME_SERVICE_ACCOUNT_PRODUCTION_EMAIL
rules:
- if: $CI_PIPELINE_SOURCE == "pipeline"
when: never
- if: $CI_COMMIT_BRANCH == "master"
changes:
- production/**/*
when: always
extends:
- .authenticate-gcloud
- .deploy-environment
deploy-all-latest:
stage: admin
when: manual
environment: latest
variables:
BASE64_GCP_SERVICE_ACCOUNT: $BASE64_GOOGLE_CREDENTIALS_LATEST
GCP_PROJECT: $GCP_PROJECT_LATEST
ENV: latest
RUNTIME_SERVICE_ACCOUNT: $RUNTIME_SERVICE_ACCOUNT_LATEST_EMAIL
extends:
- .authenticate-gcloud
- .deploy-all
deploy-all-production:
stage: admin
when: manual
environment: production
variables:
BASE64_GCP_SERVICE_ACCOUNT: $BASE64_GOOGLE_CREDENTIALS_PROD
GCP_PROJECT: $GCP_PROJECT_PRODUCTION
ENV: production
RUNTIME_SERVICE_ACCOUNT: $RUNTIME_SERVICE_ACCOUNT_PRODUCTION_EMAIL
extends:
- .authenticate-gcloud
- .deploy-all
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment