From e2f58630bbb721b374097a2a3d4f52d671e52b56 Mon Sep 17 00:00:00 2001 From: Daniele Pompa <55095241+daniele20tab@users.noreply.github.com> Date: Sun, 12 Feb 2023 12:40:55 +0100 Subject: [PATCH] Fix docker compose script and ci/cd (#46) * Fix docker compose script and ci/cd --- .../.env_template | 4 +- .../.gitlab-ci.yml | 24 +++------- {{cookiecutter.project_dirname}}/README.md | 13 ++---- .../docker-compose.yaml | 46 +++++++++++++++++++ .../{services.yaml => common.yaml} | 23 ++++++---- .../docker-compose/consumer-image.yaml | 12 ----- .../docker-compose/consumer.yaml | 14 ------ .../docker-compose/e2e-branch.yaml | 8 ++++ .../docker-compose/e2e.yaml | 24 ++++++++++ .../docker-compose/local.yaml | 10 ++++ .../docker-compose/provider.yaml | 19 -------- .../docker-compose/volumes.yaml | 8 ---- .../docker/e2e.Dockerfile | 3 ++ .../docker/local.Dockerfile | 3 +- .../docker/remote.Dockerfile | 11 +---- .../docker/test.Dockerfile | 11 ++--- {{cookiecutter.project_dirname}}/package.json | 1 + .../proxy/conf/dynamic.yaml | 11 ++--- .../scripts/ci_pact.sh | 16 ++++--- .../scripts/ci_sentry.sh | 19 ++++---- .../scripts/deploy.sh | 8 ++-- .../scripts/deploy/init.sh | 20 ++++---- .../scripts/deploy/terraform-cloud.sh | 2 +- .../scripts/deploy/terraform.sh | 12 ++--- .../scripts/deploy/vault.sh | 16 ++++--- .../scripts/entrypoint.sh | 5 +- .../scripts/pact_stub_server.sh | 4 +- .../scripts/test.sh | 3 +- 28 files changed, 185 insertions(+), 165 deletions(-) create mode 100644 {{cookiecutter.project_dirname}}/docker-compose.yaml rename {{cookiecutter.project_dirname}}/docker-compose/{services.yaml => common.yaml} (70%) delete mode 100644 {{cookiecutter.project_dirname}}/docker-compose/consumer-image.yaml delete mode 100644 {{cookiecutter.project_dirname}}/docker-compose/consumer.yaml create mode 100644 {{cookiecutter.project_dirname}}/docker-compose/e2e-branch.yaml create mode 100644 {{cookiecutter.project_dirname}}/docker-compose/e2e.yaml create mode 100644 {{cookiecutter.project_dirname}}/docker-compose/local.yaml delete mode 100644 {{cookiecutter.project_dirname}}/docker-compose/provider.yaml delete mode 100644 {{cookiecutter.project_dirname}}/docker-compose/volumes.yaml diff --git a/{{cookiecutter.project_dirname}}/.env_template b/{{cookiecutter.project_dirname}}/.env_template index c6642db..2234b1b 100644 --- a/{{cookiecutter.project_dirname}}/.env_template +++ b/{{cookiecutter.project_dirname}}/.env_template @@ -1,4 +1,6 @@ -COMPOSE_FILE=docker-compose/consumer.yaml:docker-compose/volumes.yaml:docker-compose/services.yaml:docker-compose/provider.yaml +COMPOSE_FILE=docker-compose.yaml:docker-compose/local.yaml +COMPOSE_PROFILES=pact +# CYPRESS_BASE_URL=https://proxy:8443 # INTERNAL_BACKEND_URL=http://provider:8000 # NEXT_PUBLIC_PROJECT_URL=https://localhost:8443 # REACT_ENVIRONMENT=development diff --git a/{{cookiecutter.project_dirname}}/.gitlab-ci.yml b/{{cookiecutter.project_dirname}}/.gitlab-ci.yml index c32d67c..49a5c7c 100644 --- a/{{cookiecutter.project_dirname}}/.gitlab-ci.yml +++ b/{{cookiecutter.project_dirname}}/.gitlab-ci.yml @@ -21,7 +21,6 @@ variables: cache: paths: - node_modules/ - - .yarn {% with env=cookiecutter.resources.envs[0] %} .development: rules: &development-rules @@ -130,11 +129,12 @@ sentry_release_production: test: stage: Test - image: docker/compose:debian-1.29.2 + image: docker:20 services: - docker:20-dind needs: [] variables: + COMPOSE_FILE: docker-compose.yaml:docker-compose/local.yaml COMPOSE_PROJECT_NAME: "${CI_PROJECT_PATH_SLUG}-${CI_JOB_NAME}-${CI_JOB_ID}" SERVICE_CONTAINER_NAME: "${CI_PROJECT_PATH_SLUG}-${CI_JOB_NAME}-${CI_JOB_ID}_frontend" SERVICE_DOCKER_FILE: "docker/test.Dockerfile" @@ -300,20 +300,15 @@ build_production: .e2e: stage: E2E - image: docker/compose:debian-1.29.2 + image: docker:20 services: - docker:20-dind variables: COMPOSE_PROJECT_NAME: "${CI_PROJECT_PATH_SLUG}-${CI_JOB_NAME}-${CI_JOB_ID}" SERVICE_CONTAINER_NAME: "${CI_PROJECT_PATH_SLUG}-${CI_JOB_NAME}-${CI_JOB_ID}_e2e" before_script: - - > - if [ "${PACT_ENABLED}" == "true" ]; - then - export COMPOSE_FILE=docker-compose/consumer-image.yaml:docker-compose/services.yaml:docker-compose/provider.yaml; - else - export COMPOSE_FILE=docker-compose/consumer-image.yaml:docker-compose/services.yaml; - fi + - if [ "${PACT_ENABLED}" == "true" ]; then COMPOSE_PROFILES=pact; else COMPOSE_PROFILES=no-pact; fi + - export COMPOSE_PROFILES - export CONSUMER_IMAGE=${CI_REGISTRY}/${CI_PROJECT_PATH}:${VERSION_REF} - docker login -u gitlab-ci-token -p ${CI_BUILD_TOKEN} ${CI_REGISTRY} script: @@ -374,15 +369,8 @@ e2e_manual: NEXT_PUBLIC_PROJECT_URL: 'https://proxy:8443' REACT_ENVIRONMENT: 'production' SERVICE_DOCKER_FILE: "docker/remote.Dockerfile" + COMPOSE_FILE: docker-compose.yaml:docker-compose/e2e.yaml:docker-compose/e2e-branch.yaml needs: ["test"] - before_script: - - > - if [ "${PACT_ENABLED}" == "true" ]; - then - export COMPOSE_FILE=docker-compose/consumer.yaml:docker-compose/services.yaml:docker-compose/provider.yaml; - else - export COMPOSE_FILE=docker-compose/consumer.yaml:docker-compose/services.yaml; - fi .deploy: stage: Deploy diff --git a/{{cookiecutter.project_dirname}}/README.md b/{{cookiecutter.project_dirname}}/README.md index 7655d63..7f7670a 100644 --- a/{{cookiecutter.project_dirname}}/README.md +++ b/{{cookiecutter.project_dirname}}/README.md @@ -8,15 +8,6 @@ This service is generated from [20tab standard project](https://github.com/20tab ## The Kubernetes resource limits The Kubernetes deployment service limits should be adapted to the expected load of the other services and to the size of the available nodes. -By default, the `s-1vcpu-1gb-amd` DigitalOcean droplet is used (https://slugs.do-api.dev/), which allocates 900.00m of CPU capacity and 1.54Gi of memory capacity. -The following default values are calculated assuming 2 deployments and 2 stacks on a single node. - -| tfvars name | default value | -|--|--| -| service_limits_cpu | 225m | -| service_limits_memory | 256Mi | -| service_requests_cpu | 25m | -| service_requests_memory | 115Mi | ## Git @@ -112,7 +103,9 @@ docker-compose up :warning: **env variable** in custom mode you must be sure to have env, set in the system or in `.env` file. ```bash - COMPOSE_FILE=docker-compose.yaml:docker-compose/volumes.yaml:docker-compose/services.yaml:docker-compose/provider.yaml + COMPOSE_FILE=docker-compose.yaml:docker-compose/local.yaml + COMPOSE_PROFILES=pact + CYPRESS_BASE_URL=https://proxy:8443 INTERNAL_BACKEND_URL=http://provider:8000 NEXT_PUBLIC_PROJECT_URL=https://localhost:8443 REACT_ENVIRONMENT=development diff --git a/{{cookiecutter.project_dirname}}/docker-compose.yaml b/{{cookiecutter.project_dirname}}/docker-compose.yaml new file mode 100644 index 0000000..e4272e7 --- /dev/null +++ b/{{cookiecutter.project_dirname}}/docker-compose.yaml @@ -0,0 +1,46 @@ +version: "3.9" + +services: + + consumer: + environment: + - INTERNAL_BACKEND_URL=${INTERNAL_BACKEND_URL:-http://provider:8000} + - NEXT_PUBLIC_PROJECT_URL=${NEXT_PUBLIC_PROJECT_URL:-https://localhost:8443} + - REACT_ENVIRONMENT=${REACT_ENVIRONMENT:-development} + healthcheck: + test: wget -O- -q http://localhost:3000/api/health/ || exit 1 + + provider: + command: -p 8000 -d pacts -o --insecure-tls + entrypoint: ./pact_stub_server.sh + healthcheck: + test: wget -O- -q http://localhost:8000/api/health/ || exit 1 + image: pactfoundation/pact-stub-server + profiles: + - pact + volumes: + - ./scripts/pact_stub_server.sh:/app/pact_stub_server.sh + - ./pacts:/app/pacts:ro + working_dir: /app + + proxy: + depends_on: + consumer: + condition: service_healthy + provider: + condition: service_healthy + extends: + file: ./docker-compose/common.yaml + service: proxy + profiles: + - pact + + proxy-no-pact: + depends_on: + consumer: + condition: service_healthy + extends: + file: ./docker-compose/common.yaml + service: proxy + profiles: + - no-pact diff --git a/{{cookiecutter.project_dirname}}/docker-compose/services.yaml b/{{cookiecutter.project_dirname}}/docker-compose/common.yaml similarity index 70% rename from {{cookiecutter.project_dirname}}/docker-compose/services.yaml rename to {{cookiecutter.project_dirname}}/docker-compose/common.yaml index 38f65d6..37b1746 100644 --- a/{{cookiecutter.project_dirname}}/docker-compose/services.yaml +++ b/{{cookiecutter.project_dirname}}/docker-compose/common.yaml @@ -1,18 +1,19 @@ -version: "3.4" +version: "3.9" services: proxy: - image: traefik:v2.6 - depends_on: - consumer: - condition: service_healthy - volumes: - - ../proxy:/traefik:ro command: - "--configFile=/traefik/conf/static.yaml" + image: traefik:v2.6 + networks: + default: + aliases: + - proxy ports: - "${LOCAL_HTTPS_PORT:-8443}:8443" + volumes: + - ../proxy:/traefik:ro cypress: build: @@ -21,10 +22,12 @@ services: args: USER: ${USER:-appuser} container_name: cypress - depends_on: - - proxy environment: - - CYPRESS_BASE_URL=https://proxy:8443 + - CYPRESS_BASE_URL=${CYPRESS_BASE_URL:-https://proxy:8443} + networks: + default: + aliases: + - cypress user: ${USER:-appuser} volumes: - ../cypress:/app/cypress diff --git a/{{cookiecutter.project_dirname}}/docker-compose/consumer-image.yaml b/{{cookiecutter.project_dirname}}/docker-compose/consumer-image.yaml deleted file mode 100644 index 241bada..0000000 --- a/{{cookiecutter.project_dirname}}/docker-compose/consumer-image.yaml +++ /dev/null @@ -1,12 +0,0 @@ -version: "3.4" - -services: - - consumer: - image: ${CONSUMER_IMAGE} - environment: - - INTERNAL_BACKEND_URL=${INTERNAL_BACKEND_URL:-http://provider:8000} - - NEXT_PUBLIC_PROJECT_URL=${NEXT_PUBLIC_PROJECT_URL:-https://proxy:8443} - - REACT_ENVIRONMENT=${REACT_ENVIRONMENT:-production} - healthcheck: - test: wget -O- -q http://localhost:3000/api/health/ || exit 1 diff --git a/{{cookiecutter.project_dirname}}/docker-compose/consumer.yaml b/{{cookiecutter.project_dirname}}/docker-compose/consumer.yaml deleted file mode 100644 index 631ab6a..0000000 --- a/{{cookiecutter.project_dirname}}/docker-compose/consumer.yaml +++ /dev/null @@ -1,14 +0,0 @@ -version: "3.4" - -services: - - consumer: - build: - context: ../ - dockerfile: ${SERVICE_DOCKER_FILE:-docker/local.Dockerfile} - environment: - - INTERNAL_BACKEND_URL=${INTERNAL_BACKEND_URL:-http://provider:8000} - - NEXT_PUBLIC_PROJECT_URL=${NEXT_PUBLIC_PROJECT_URL:-https://localhost:8443} - - REACT_ENVIRONMENT=${REACT_ENVIRONMENT:-development} - healthcheck: - test: wget -O- -q http://localhost:3000/api/health/ || exit 1 diff --git a/{{cookiecutter.project_dirname}}/docker-compose/e2e-branch.yaml b/{{cookiecutter.project_dirname}}/docker-compose/e2e-branch.yaml new file mode 100644 index 0000000..82c472a --- /dev/null +++ b/{{cookiecutter.project_dirname}}/docker-compose/e2e-branch.yaml @@ -0,0 +1,8 @@ +version: "3.9" + +services: + + consumer: + build: + context: ./ + dockerfile: ${SERVICE_DOCKER_FILE:-docker/remote.Dockerfile} diff --git a/{{cookiecutter.project_dirname}}/docker-compose/e2e.yaml b/{{cookiecutter.project_dirname}}/docker-compose/e2e.yaml new file mode 100644 index 0000000..b8c1ba5 --- /dev/null +++ b/{{cookiecutter.project_dirname}}/docker-compose/e2e.yaml @@ -0,0 +1,24 @@ +version: "3.9" + +services: + + consumer: + image: ${CONSUMER_IMAGE} + + cypress: + depends_on: + - proxy + extends: + file: ./docker-compose/common.yaml + service: cypress + profiles: + - pact + + cypress-no-pact: + depends_on: + - proxy-no-pact + extends: + file: ./docker-compose/common.yaml + service: cypress + profiles: + - no-pact diff --git a/{{cookiecutter.project_dirname}}/docker-compose/local.yaml b/{{cookiecutter.project_dirname}}/docker-compose/local.yaml new file mode 100644 index 0000000..c02c861 --- /dev/null +++ b/{{cookiecutter.project_dirname}}/docker-compose/local.yaml @@ -0,0 +1,10 @@ +version: "3.9" + +services: + + consumer: + build: + context: ./ + dockerfile: ${SERVICE_DOCKER_FILE:-docker/local.Dockerfile} + volumes: + - ./:/app diff --git a/{{cookiecutter.project_dirname}}/docker-compose/provider.yaml b/{{cookiecutter.project_dirname}}/docker-compose/provider.yaml deleted file mode 100644 index 4beac9b..0000000 --- a/{{cookiecutter.project_dirname}}/docker-compose/provider.yaml +++ /dev/null @@ -1,19 +0,0 @@ -version: "3.4" - -services: - - provider: - image: pactfoundation/pact-stub-server - entrypoint: ./pact_stub_server.sh - command: -p 8000 -d pacts -o --insecure-tls - working_dir: /app - volumes: - - ../scripts/pact_stub_server.sh:/app/pact_stub_server.sh - - ../pacts:/app/pacts:ro - healthcheck: - test: wget -O- -q http://localhost:8000/api/health/ || exit 1 - - proxy: - depends_on: - provider: - condition: service_healthy diff --git a/{{cookiecutter.project_dirname}}/docker-compose/volumes.yaml b/{{cookiecutter.project_dirname}}/docker-compose/volumes.yaml deleted file mode 100644 index d44842c..0000000 --- a/{{cookiecutter.project_dirname}}/docker-compose/volumes.yaml +++ /dev/null @@ -1,8 +0,0 @@ -version: "3.4" - -services: - - consumer: - volumes: - - ../:/app - - /var/run/dbus/system_bus_socket:/var/run/dbus/system_bus_socket diff --git a/{{cookiecutter.project_dirname}}/docker/e2e.Dockerfile b/{{cookiecutter.project_dirname}}/docker/e2e.Dockerfile index b5912d0..58d2ac3 100644 --- a/{{cookiecutter.project_dirname}}/docker/e2e.Dockerfile +++ b/{{cookiecutter.project_dirname}}/docker/e2e.Dockerfile @@ -1,3 +1,5 @@ +# syntax=docker/dockerfile:1 + FROM cypress/base:16.18.1 ARG USER=appuser ENV APPUSER=$USER PATH="$PATH:./node_modules/.bin" @@ -10,3 +12,4 @@ RUN yarn add cypress typescript RUN cypress install RUN mkdir cypress-outputs CMD [ "cypress", "run" ] +LABEL company="20tab" project="{{ cookiecutter.project_slug }}" service="frontend" stage="e2e" diff --git a/{{cookiecutter.project_dirname}}/docker/local.Dockerfile b/{{cookiecutter.project_dirname}}/docker/local.Dockerfile index ab90b59..5ceb1bf 100644 --- a/{{cookiecutter.project_dirname}}/docker/local.Dockerfile +++ b/{{cookiecutter.project_dirname}}/docker/local.Dockerfile @@ -1,8 +1,6 @@ # syntax=docker/dockerfile:1 FROM node:16-bullseye-slim -LABEL company="20tab" project="{{ cookiecutter.project_slug }}" service="frontend" stage="local" - ARG DEBIAN_FRONTEND=noninteractive ENV LANG=C.UTF-8 LC_ALL=C.UTF-8 NEXT_TELEMETRY_DISABLED=1 NODE_ENV="development" WORKDIR=/app RUN apt-get update \ @@ -24,3 +22,4 @@ WORKDIR ${WORKDIR} RUN chown node ${WORKDIR} ENTRYPOINT ["./scripts/entrypoint.sh"] CMD yarn start +LABEL company="20tab" project="{{ cookiecutter.project_slug }}" service="frontend" stage="local" diff --git a/{{cookiecutter.project_dirname}}/docker/remote.Dockerfile b/{{cookiecutter.project_dirname}}/docker/remote.Dockerfile index 5b4acb7..b700905 100644 --- a/{{cookiecutter.project_dirname}}/docker/remote.Dockerfile +++ b/{{cookiecutter.project_dirname}}/docker/remote.Dockerfile @@ -1,8 +1,6 @@ # syntax=docker/dockerfile:1 FROM node:16-alpine AS build -LABEL company="20tab" project="{{ cookiecutter.project_slug }}" service="frontend" stage="build" - ENV PATH="$PATH:./node_modules/.bin" WORKDIR /app COPY package.json yarn.lock* package-lock.json* pnpm-lock.yaml* ./ @@ -21,8 +19,6 @@ COPY store ./store COPY styles ./styles COPY utils ./utils COPY tsconfig.json next.config.js sentry.client.config.js sentry.server.config.js middleware.ts ./ -# Environment variables must be present at build time -# https://github.com/vercel/next.js/discussions/14030 ARG SENTRY_AUTH_TOKEN \ SENTRY_ORG \ SENTRY_PROJECT_NAME \ @@ -35,21 +31,17 @@ ENV NEXT_TELEMETRY_DISABLED=1 \ SENTRY_PROJECT_NAME=$SENTRY_PROJECT_NAME \ SENTRY_URL=$SENTRY_URL RUN yarn build +LABEL company="20tab" project="{{ cookiecutter.project_slug }}" service="frontend" stage="build" FROM node:16-alpine AS remote -LABEL company="20tab" project="{{ cookiecutter.project_slug }}" service="frontend" stage="remote" - WORKDIR /app RUN addgroup --system --gid 1001 nodejs RUN adduser --system --uid 1001 nextjs USER nextjs COPY ["next.config.js", "package.json", "sentry.client.config.js", "sentry.server.config.js", "server.js", "yarn.lock", "middleware.ts", "./"] COPY ["public/", "public/"] -# Automatically leverage output traces to reduce image size -# https://nextjs.org/docs/advanced-features/output-file-tracing COPY --from=build --chown=nextjs:nodejs /app/.next/standalone ./ COPY --from=build --chown=nextjs:nodejs /app/.next/static ./.next/static -# Environment variables must be redefined at run time ARG SENTRY_AUTH_TOKEN \ SENTRY_ORG \ SENTRY_PROJECT_NAME \ @@ -62,3 +54,4 @@ ENV NEXT_TELEMETRY_DISABLED=1 \ SENTRY_PROJECT_NAME=$SENTRY_PROJECT_NAME \ SENTRY_URL=$SENTRY_URL CMD yarn start +LABEL company="20tab" project="{{ cookiecutter.project_slug }}" service="frontend" stage="remote" diff --git a/{{cookiecutter.project_dirname}}/docker/test.Dockerfile b/{{cookiecutter.project_dirname}}/docker/test.Dockerfile index 4148b1f..fa71241 100644 --- a/{{cookiecutter.project_dirname}}/docker/test.Dockerfile +++ b/{{cookiecutter.project_dirname}}/docker/test.Dockerfile @@ -1,11 +1,8 @@ # syntax=docker/dockerfile:1 FROM node:16-bullseye-slim -LABEL company="20tab" project="{{ cookiecutter.project_slug }}" service="frontend" stage="test" - ARG DEBIAN_FRONTEND=noninteractive -ARG USER=appuser -ENV APPUSER=$USER LANG=C.UTF-8 LC_ALL=C.UTF-8 NEXT_TELEMETRY_DISABLED=1 NODE_ENV="development" TZ='Europe/Rome' WORKDIR=/app +ENV LANG=C.UTF-8 LC_ALL=C.UTF-8 NEXT_TELEMETRY_DISABLED=1 NODE_ENV="development" TZ='Europe/Rome' WORKDIR=/app RUN apt-get update \ && apt-get install --assume-yes --no-install-recommends \ g++ \ @@ -13,10 +10,8 @@ RUN apt-get update \ python3 \ && rm -rf /var/lib/apt/lists/* WORKDIR $WORKDIR -RUN addgroup --system --gid 997 $APPUSER -RUN adduser --system --uid 997 $APPUSER -USER $APPUSER ENV PATH="$PATH:./node_modules/.bin" -COPY --chown=$APPUSER package.json yarn.lock ./ +COPY package.json yarn.lock ./ ENTRYPOINT ["./scripts/test.sh"] CMD yarn ci:unit-test && yarn ci:contract-test +LABEL company="20tab" project="{{ cookiecutter.project_slug }}" service="frontend" stage="test" diff --git a/{{cookiecutter.project_dirname}}/package.json b/{{cookiecutter.project_dirname}}/package.json index ca83cb8..12df5d8 100644 --- a/{{cookiecutter.project_dirname}}/package.json +++ b/{{cookiecutter.project_dirname}}/package.json @@ -7,6 +7,7 @@ "build": "next build", "ci:contract-test": "npx jest pact/contracts --testEnvironment=node --color --detectOpenHandles --passWithNoTests", "ci:unit-test": "npx jest --color --silent --detectOpenHandles --testPathIgnorePatterns=pact/contracts --coverage --coverageDirectory ./coverage/tests --ci --reporters=default --reporters=jest-junit", "e2e": "CYPRESS_BASE_URL=http://localhost:3000 cypress open", + "e2e": "CYPRESS_BASE_URL=https://localhost:8443 cypress open", "lint": "next lint", "pact": "npx jest pact/contracts --testEnvironment=node --detectOpenHandles", "start": "node server.js", diff --git a/{{cookiecutter.project_dirname}}/proxy/conf/dynamic.yaml b/{{cookiecutter.project_dirname}}/proxy/conf/dynamic.yaml index f83c0d4..5c26ed7 100644 --- a/{{cookiecutter.project_dirname}}/proxy/conf/dynamic.yaml +++ b/{{cookiecutter.project_dirname}}/proxy/conf/dynamic.yaml @@ -1,23 +1,20 @@ http: routers: provider: - rule: "PathPrefix(`/api`)" + rule: PathPrefix(`/api`) service: provider consumer: - rule: "PathPrefix(`/`)" - service: consumer - consumer-sockjs-node: - rule: "PathPrefix(`/sockjs-node`)" + rule: PathPrefix(`/`) service: consumer services: provider: loadBalancer: servers: - - url: "http://provider:8000/" + - url: "http://provider:8000/" consumer: loadBalancer: servers: - - url: "http://consumer:3000/" + - url: "http://consumer:3000/" tls: certificates: diff --git a/{{cookiecutter.project_dirname}}/scripts/ci_pact.sh b/{{cookiecutter.project_dirname}}/scripts/ci_pact.sh index 921951f..c637238 100755 --- a/{{cookiecutter.project_dirname}}/scripts/ci_pact.sh +++ b/{{cookiecutter.project_dirname}}/scripts/ci_pact.sh @@ -3,13 +3,17 @@ if [ "${VAULT_ADDR}" != "" ]; then apk update && apk add curl jq - export VAULT_TOKEN=`curl --silent --request POST --data "role=pact" --data "jwt=${CI_JOB_JWT_V2}" ${VAULT_ADDR%/}/v1/auth/gitlab-jwt/login | jq -r .auth.client_token` + vault_token=$(curl --silent --request POST --data "role=pact" --data "jwt=${CI_JOB_JWT_V2}" "${VAULT_ADDR%/}"/v1/auth/gitlab-jwt/login | jq -r .auth.client_token) - pact_secrets=`curl --silent --header "X-Vault-Token: ${VAULT_TOKEN}" ${VAULT_ADDR%/}/v1/${PROJECT_SLUG}/pact | jq -r .data` + pact_secrets=$(curl --silent --header "X-Vault-Token: ${vault_token}" "${VAULT_ADDR%/}"/v1/"${PROJECT_SLUG}"/pact | jq -r .data) - export PACT_BROKER_BASE_URL=`echo ${pact_secrets} | jq -r .pact_broker_base_url` - export PACT_BROKER_PASSWORD=`echo ${pact_secrets} | jq -r .pact_broker_password` - export PACT_BROKER_USERNAME=`echo ${pact_secrets} | jq -r .pact_broker_username` + PACT_BROKER_BASE_URL=$(echo "${pact_secrets}" | jq -r .pact_broker_base_url) + PACT_BROKER_PASSWORD=$(echo "${pact_secrets}" | jq -r .pact_broker_password) + PACT_BROKER_USERNAME=$(echo "${pact_secrets}" | jq -r .pact_broker_username) + + export PACT_BROKER_BASE_URL + export PACT_BROKER_PASSWORD + export PACT_BROKER_USERNAME fi -docker-entrypoint.sh pact-broker ${@} +docker-entrypoint.sh pact-broker "${@}" diff --git a/{{cookiecutter.project_dirname}}/scripts/ci_sentry.sh b/{{cookiecutter.project_dirname}}/scripts/ci_sentry.sh index e3e1842..a042d64 100755 --- a/{{cookiecutter.project_dirname}}/scripts/ci_sentry.sh +++ b/{{cookiecutter.project_dirname}}/scripts/ci_sentry.sh @@ -2,26 +2,27 @@ apk update && apk add git -git config --global --add safe.directory ${PROJECT_DIR} +git config --global --add safe.directory "${PROJECT_DIR}" if [ "${VAULT_ADDR}" != "" ]; then apk add curl jq - export VAULT_TOKEN=`curl --silent --request POST --data "role=${VAULT_ROLE}" --data "jwt=${CI_JOB_JWT_V2}" ${VAULT_ADDR%/}/v1/auth/gitlab-jwt/login | jq -r .auth.client_token` + vault_token=$(curl --silent --request POST --data "role=${VAULT_ROLE}" --data "jwt=${CI_JOB_JWT_V2}" "${VAULT_ADDR%/}"/v1/auth/gitlab-jwt/login | jq -r .auth.client_token) - export SENTRY_AUTH_TOKEN=`curl --silent --header "X-Vault-Token: ${VAULT_TOKEN}" ${VAULT_ADDR%/}/v1/${PROJECT_SLUG}/envs/${ENV_NAME}/sentry | jq -r .data.sentry_auth_token` - - export SENTRY_DSN=`curl --silent --header "X-Vault-Token: ${VAULT_TOKEN}" ${VAULT_ADDR%/}/v1/${PROJECT_SLUG}/envs/${ENV_NAME}/${SERVICE_SLUG}/sentry | jq -r .data.sentry_dsn` + SENTRY_AUTH_TOKEN=$(curl --silent --header "X-Vault-Token: ${vault_token}" "${VAULT_ADDR%/}"/v1/"${PROJECT_SLUG}"/envs/"${ENV_NAME}"/sentry | jq -r .data.sentry_auth_token) + SENTRY_DSN=$(curl --silent --header "X-Vault-Token: ${vault_token}" "${VAULT_ADDR%/}"/v1/"${PROJECT_SLUG}"/envs/"${ENV_NAME}"/"${SERVICE_SLUG}"/sentry | jq -r .data.sentry_dsn) + export SENTRY_AUTH_TOKEN + export SENTRY_DSN fi case "${1}" in "release") - sentry-cli releases new ${VERSION_REF} -p ${SENTRY_PROJECT_NAME} --log-level=debug; - sentry-cli releases set-commits ${VERSION_REF} --auto --ignore-missing; - sentry-cli releases finalize ${VERSION_REF}; + sentry-cli releases new "${VERSION_REF}" -p "${SENTRY_PROJECT_NAME}" --log-level=debug; + sentry-cli releases set-commits "${VERSION_REF}" --auto --ignore-missing; + sentry-cli releases finalize "${VERSION_REF}"; ;; "success") - sentry-cli releases deploys ${VERSION_REF} new -e ${CI_ENVIRONMENT_NAME} -t $((RELEASE_END-RELEASE_START)); + sentry-cli releases deploys "${VERSION_REF}" new -e "${CI_ENVIRONMENT_NAME}" -t $((RELEASE_END-RELEASE_START)); ;; "failure") sentry-cli send-event -m "Deploy to ${CI_ENVIRONMENT_NAME} failed."; diff --git a/{{cookiecutter.project_dirname}}/scripts/deploy.sh b/{{cookiecutter.project_dirname}}/scripts/deploy.sh index 971828c..6054744 100755 --- a/{{cookiecutter.project_dirname}}/scripts/deploy.sh +++ b/{{cookiecutter.project_dirname}}/scripts/deploy.sh @@ -1,10 +1,10 @@ #!/bin/sh -e # init.sh must be sourced to let it export env vars -. ${PROJECT_DIR}/scripts/deploy/init.sh +. "${PROJECT_DIR}"/scripts/deploy/init.sh -sh ${PROJECT_DIR}/scripts/deploy/terraform.sh validate +sh "${PROJECT_DIR}"/scripts/deploy/terraform.sh validate -sh ${PROJECT_DIR}/scripts/deploy/terraform.sh plan-json +sh "${PROJECT_DIR}"/scripts/deploy/terraform.sh plan-json -sh ${PROJECT_DIR}/scripts/deploy/terraform.sh apply -auto-approve +sh "${PROJECT_DIR}"/scripts/deploy/terraform.sh apply -auto-approve diff --git a/{{cookiecutter.project_dirname}}/scripts/deploy/init.sh b/{{cookiecutter.project_dirname}}/scripts/deploy/init.sh index 3548507..fc09a27 100755 --- a/{{cookiecutter.project_dirname}}/scripts/deploy/init.sh +++ b/{{cookiecutter.project_dirname}}/scripts/deploy/init.sh @@ -4,27 +4,27 @@ export TF_VAR_env_slug="${ENV_SLUG}" export TF_VAR_project_slug="${PROJECT_SLUG}" export TF_VAR_stack_slug="${STACK_SLUG}" -var_file="${TERRAFORM_VARS_DIR}/.tfvars" +terraform_cli_args="-var-file=${TERRAFORM_VARS_DIR%/}/.tfvars" if [ "${TERRAFORM_EXTRA_VAR_FILE}" != "" ]; then - extra_var_file="${TERRAFORM_VARS_DIR}/${TERRAFORM_EXTRA_VAR_FILE}" - touch ${extra_var_file} - var_files="-var-file=${var_file} -var-file=${extra_var_file}" -else - var_files="-var-file=${var_file}" + extra_var_file="${TERRAFORM_VARS_DIR%/}/${TERRAFORM_EXTRA_VAR_FILE}" + touch "${extra_var_file}" + terraform_cli_args="${terraform_cli_args} -var-file=${extra_var_file}" fi if [ "${VAULT_ADDR}" != "" ]; then - . ${PROJECT_DIR}/scripts/deploy/vault.sh + . "${PROJECT_DIR}"/scripts/deploy/vault.sh + terraform_cli_args="${terraform_cli_args} -var-file=${TERRAFORM_VARS_DIR%/}/vault-secrets.tfvars.json" fi -export TERRAFORM_VAR_FILE_ARGS=${var_files} +export TF_CLI_ARGS_destroy="${terraform_cli_args}" +export TF_CLI_ARGS_plan="${terraform_cli_args}" case "${TERRAFORM_BACKEND}" in "gitlab") - . ${PROJECT_DIR}/scripts/deploy/gitlab.sh + . "${PROJECT_DIR}"/scripts/deploy/gitlab.sh ;; "terraform-cloud") - . ${PROJECT_DIR}/scripts/deploy/terraform-cloud.sh + . "${PROJECT_DIR}"/scripts/deploy/terraform-cloud.sh ;; esac diff --git a/{{cookiecutter.project_dirname}}/scripts/deploy/terraform-cloud.sh b/{{cookiecutter.project_dirname}}/scripts/deploy/terraform-cloud.sh index 515e6ca..db3e59a 100755 --- a/{{cookiecutter.project_dirname}}/scripts/deploy/terraform-cloud.sh +++ b/{{cookiecutter.project_dirname}}/scripts/deploy/terraform-cloud.sh @@ -1,7 +1,7 @@ #!/bin/sh -e export TF_CLI_CONFIG_FILE="${TF_ROOT}/cloud.tfc" -cat << EOF > ${TF_CLI_CONFIG_FILE} +cat << EOF > "${TF_CLI_CONFIG_FILE}" { "credentials": { "app.terraform.io": { diff --git a/{{cookiecutter.project_dirname}}/scripts/deploy/terraform.sh b/{{cookiecutter.project_dirname}}/scripts/deploy/terraform.sh index 1bd1a45..d5f19b7 100755 --- a/{{cookiecutter.project_dirname}}/scripts/deploy/terraform.sh +++ b/{{cookiecutter.project_dirname}}/scripts/deploy/terraform.sh @@ -1,6 +1,6 @@ #!/bin/sh -e -if [ "${DEBUG_OUTPUT}" == "true" ]; then +if [ "${DEBUG_OUTPUT}" = "true" ]; then set -x fi @@ -21,8 +21,8 @@ JQ_PLAN=' export TF_IN_AUTOMATION=true init() { - cd ${TF_ROOT} - if [ "${TERRAFORM_BACKEND}" == "terraform-cloud" ]; then + cd "${TF_ROOT}" + if [ "${TERRAFORM_BACKEND}" = "terraform-cloud" ]; then terraform init "${@}" -input=false else terraform init "${@}" -input=false -reconfigure @@ -36,7 +36,7 @@ case "${1}" in ;; "destroy") init - terraform "${@}" ${TERRAFORM_VAR_FILE_ARGS} -auto-approve + terraform "${@}" -auto-approve ;; "fmt") terraform "${@}" -check -diff -recursive @@ -48,11 +48,11 @@ case "${1}" in ;; "plan") init - terraform "${@}" ${TERRAFORM_VAR_FILE_ARGS} -input=false -out="${plan_cache}" + terraform "${@}" -input=false -out="${plan_cache}" ;; "plan-json") init - terraform plan ${TERRAFORM_VAR_FILE_ARGS} -input=false -out="${plan_cache}" + terraform plan -input=false -out="${plan_cache}" terraform show -json "${plan_cache}" | \ jq -r "${JQ_PLAN}" \ > "${plan_json}" diff --git a/{{cookiecutter.project_dirname}}/scripts/deploy/vault.sh b/{{cookiecutter.project_dirname}}/scripts/deploy/vault.sh index 567db80..33e803e 100755 --- a/{{cookiecutter.project_dirname}}/scripts/deploy/vault.sh +++ b/{{cookiecutter.project_dirname}}/scripts/deploy/vault.sh @@ -1,14 +1,18 @@ #!/bin/sh -e -export VAULT_TOKEN=`curl --silent --request POST --data "role=${VAULT_ROLE}" --data "jwt=${CI_JOB_JWT_V2}" ${VAULT_ADDR%/}/v1/auth/gitlab-jwt/login | jq -r .auth.client_token` +vault_token=$(curl --silent --request POST --data "role=${VAULT_ROLE}" --data "jwt=${CI_JOB_JWT_V2}" "${VAULT_ADDR%/}"/v1/auth/gitlab-jwt/login | jq -r .auth.client_token) + +secrets_data="{}" for secret_path in ${VAULT_SECRETS} do - secret_var_file=${TERRAFORM_VARS_DIR}/`echo ${secret_path} | tr / -`.json - curl --silent --header "X-Vault-Token: ${VAULT_TOKEN}" ${VAULT_ADDR%/}/v1/${PROJECT_SLUG}/${VAULT_SECRETS_PREFIX}/${secret_path} | jq -r ".data // {}" > ${secret_var_file} - var_files="${var_files} -var-file=${secret_var_file}" + secret_data=$(curl --silent --header "X-Vault-Token: ${vault_token}" "${VAULT_ADDR%/}"/v1/"${PROJECT_SLUG}"/"${VAULT_SECRETS_PREFIX}"/"${secret_path}" | jq -r '.data // {}') || secret_data="{}" + secrets_data=$(echo "${secrets_data}" | jq --argjson new_data "${secret_data}" '. * $new_data') done -if [ "${TERRAFORM_BACKEND}" == "terraform-cloud" ]; then - export TFC_TOKEN=`curl --silent --header "X-Vault-Token: ${VAULT_TOKEN}" ${VAULT_ADDR%/}/v1/${PROJECT_SLUG}-tfc/creds/default | jq -r .data.token ` +echo "${secrets_data}" > "${TERRAFORM_VARS_DIR%/}"/vault-secrets.tfvars.json + +if [ "${TERRAFORM_BACKEND}" = "terraform-cloud" ]; then + TFC_TOKEN=$(curl --silent --header "X-Vault-Token: ${vault_token}" "${VAULT_ADDR%/}"/v1/"${PROJECT_SLUG}"-tfc/creds/default | jq -r .data.token) + export TFC_TOKEN fi diff --git a/{{cookiecutter.project_dirname}}/scripts/entrypoint.sh b/{{cookiecutter.project_dirname}}/scripts/entrypoint.sh index c219c21..c0257c2 100755 --- a/{{cookiecutter.project_dirname}}/scripts/entrypoint.sh +++ b/{{cookiecutter.project_dirname}}/scripts/entrypoint.sh @@ -1,2 +1,3 @@ -#!/usr/bin/env bash -exec "$@" +#!/bin/sh -e + +exec "${@}" diff --git a/{{cookiecutter.project_dirname}}/scripts/pact_stub_server.sh b/{{cookiecutter.project_dirname}}/scripts/pact_stub_server.sh index d2e3f49..3420ae3 100755 --- a/{{cookiecutter.project_dirname}}/scripts/pact_stub_server.sh +++ b/{{cookiecutter.project_dirname}}/scripts/pact_stub_server.sh @@ -9,7 +9,7 @@ if ! which inotifywait > /dev/null; then fi while true; do - ./pact-stub-server $@ & + ./pact-stub-server "${@}" & inotifywait \ --event attrib \ --event create \ @@ -17,5 +17,5 @@ while true; do --event modify \ --event move \ --recursive /app/pacts - [[ `jobs -pr` == "" ]] || kill `jobs -pr` + [[ $(jobs -pr) == "" ]] || kill "$(jobs -pr)" done diff --git a/{{cookiecutter.project_dirname}}/scripts/test.sh b/{{cookiecutter.project_dirname}}/scripts/test.sh index f871813..16a55a0 100755 --- a/{{cookiecutter.project_dirname}}/scripts/test.sh +++ b/{{cookiecutter.project_dirname}}/scripts/test.sh @@ -1,3 +1,4 @@ #!/bin/sh -e + yarn install -exec "$@" +exec "${@}"