Skip to content

Instantly share code, notes, and snippets.

@insekticid
Created July 24, 2020 11:13
Show Gist options
  • Save insekticid/566cdeb7a87d5cd8c344890e347eb376 to your computer and use it in GitHub Desktop.
Save insekticid/566cdeb7a87d5cd8c344890e347eb376 to your computer and use it in GitHub Desktop.
stages:
- build
- deploy
- trigger
- review
- production
- integration
- staging
- cleanup
variables:
BACKEND_DOMAIN: '$APP_DOMAIN'
BRANCH: "$CI_COMMIT_REF_SLUG"
REVIEW_BACKEND_DOMAIN: backend.review.$APP_DOMAIN
INTEGRATION_BACKEND_DOMAIN: backend.integration.$APP_DOMAIN
STAGING_BACKEND_DOMAIN: backend.staging.$APP_DOMAIN
PRODUCTION_BACKEND_DOMAIN: backend.$APP_DOMAIN
cache:
paths:
- node_modules/
.build_app_template: &build_job_definition
stage: build
image: node:9-alpine
script:
- apk update
- apk add git
- rm -fr /var/cache/apk/*
- configure_backend_url
- build_react
artifacts:
expire_in: 20 weeks
paths:
- build/
# build process is different dependency for each deployment
# each deployment has different build cache with hardcoded backend url
build app:
<<: *build_job_definition
only:
- master
- tags
build review app:
<<: *build_job_definition
only:
- branches
except:
- master
- triggers
build trigger app:
<<: *build_job_definition
only:
- triggers
.deploy_S3_template: &job_definition
stage: deploy
image: deployment/docker:git-aws-cli
dependencies:
- build app
variables:
GIT_STRATEGY: none
AUTO_DEVOPS_DOMAIN: $FRONTEND_DOMAIN_NAME
services:
- docker:dind
script:
- pwd & ls -al
- setup_aws_cli
- load_terraform_config
- terraform_deploy
- export_outputs
- s3_upload
- export_outputs
trigger deploy:
<<: *job_definition
stage: trigger
dependencies:
- build trigger app
environment:
name: trigger/$FRONTEND_ALIAS
url: https://$FRONTEND_ALIAS.review.$APP_DOMAIN
variables:
TF_VAR_domain_alias: "$FRONTEND_ALIAS"
only:
- triggers
production deploy:
<<: *job_definition
stage: production
environment:
name: production
url: https://www.$APP_DOMAIN
variables:
BRANCH: master
VAR_FILE_BRANCH: master
only:
- tags
staging deploy:
<<: *job_definition
stage: staging
environment:
name: staging
url: https://staging.$APP_DOMAIN
variables:
BRANCH: stage
VAR_FILE_BRANCH: master
only:
refs:
- master
except:
- triggers
integration deploy:
<<: *job_definition
stage: integration
environment:
name: integration
url: https://integration.$APP_DOMAIN
dependencies:
- build review app
variables:
VAR_FILE_BRANCH: dev
only:
refs:
- integration
except:
- triggers
review:
<<: *job_definition
stage: review
environment:
name: review/$CI_COMMIT_REF_NAME
url: https://$CI_COMMIT_REF_SLUG.review.$APP_DOMAIN
on_stop: stop_review
when: manual
dependencies:
- build review app
only:
refs:
- branches
except:
- master
- triggers
- integration
stop_review:
<<: *job_definition
stage: cleanup
script:
- setup_aws_cli
- load_terraform_config
- delete
when: manual
environment:
name: review/$CI_COMMIT_REF_NAME
action: stop
allow_failure: true
dependencies:
- review
only:
refs:
- branches
except:
- master
# ---------------------------------------------------------------------------
.auto_devops: &auto_devops |
[[ "$TRACE" ]] && set -x
export CI_APPLICATION_TAG=$CI_COMMIT_REF_SLUG
[[ "$CI_COMMIT_TAG" ]] && export CI_APPLICATION_TAG=$CI_COMMIT_TAG
export BASE_PATH=`pwd`
export REACT_APP_VERSION=$CI_APPLICATION_TAG
export REACT_APP_BUILD_DATE=$(date +"%Y-%m-%d %H-%M-%S")
echo "TAG: $CI_COMMIT_TAG - $CI_COMMIT_REF_SLUG"
function configure_backend_url() {
export BACKEND_DOMAIN=$REVIEW_BACKEND_DOMAIN
if [[ "$CI_APPLICATION_TAG" = "master" ]]; then
export BACKEND_DOMAIN=$STAGING_BACKEND_DOMAIN
fi
if [[ "$CI_APPLICATION_TAG" = "integration" ]]; then
export BACKEND_DOMAIN=$INTEGRATION_BACKEND_DOMAIN
fi
#do not allow to change backend url for production
if [[ "$CI_COMMIT_TAG" ]]; then
export BACKEND_DOMAIN=$PRODUCTION_BACKEND_DOMAIN
fi
export REACT_APP_API_URL="https://$BACKEND_DOMAIN/graphql"
echo "Backend API url: $REACT_APP_API_URL"
echo "------------------------------------"
}
function build_react() {
yarn install
yarn run build
yarn run test
}
function setup_aws_cli() {
aws configure set default.region $AWS_REGION
aws configure set aws_access_key_id "$AWS_ACCESS_KEY_ID"
aws configure set aws_secret_access_key "$AWS_SECRET_ACCESS_KEY"
echo "aws cli configured"
}
function load_terraform_config() {
git clone --depth=1 "https://gitlab-ci-token:$CI_JOB_TOKEN@gitlab.com/xxx/app-frontend.git"
}
function terraform_plan() {
cd aws-app-frontend/terraform/src
terraform --version
#terraform validate #just in case of problem
make init
make plan
cp terraform.tfplan ../../../terraform.tfplan
}
function terraform_deploy() {
cd aws-app-frontend/terraform/src
terraform --version
make init
make plan
make apply
}
function export_outputs() {
export AWS_OUTPUT=$(terraform output -json)
export AWS_BUCKET="s3://$(echo $AWS_OUTPUT | jq -r '.s3_bucket_name.value')"
export AWS_CLOUDFRONT_DIST_ID=$(echo $AWS_OUTPUT | jq -r '.cloudfront_distribution_id.value')
export FRONTEND_DOMAIN_NAME=$(echo $AWS_OUTPUT | jq -r '.frontend_domain_name.value')
export CLOUDFRONT_DOMAIN_NAME=$(echo $AWS_OUTPUT | jq -r '.cloudfront_domain_name.value')
export AUTO_DEVOPS_DOMAIN=$FRONTEND_DOMAIN_NAME
echo $CI_ENVIRONMENT_URL
export CI_ENVIRONMENT_URL=$FRONTEND_DOMAIN_NAME
echo $CI_ENVIRONMENT_URL
echo "Backend domain: $BACKEND_DOMAIN"
}
function s3_upload() {
aws s3 sync $BASE_PATH/build/ $AWS_BUCKET --acl public-read
aws cloudfront create-invalidation --distribution-id $AWS_CLOUDFRONT_DIST_ID --paths /index.html
}
function delete() {
cd aws-app-frontend/terraform/src
make init
echo yes | make destroy
}
before_script:
- *auto_devops
@insekticid
Copy link
Author

insekticid commented Jul 24, 2020

stages:
  - build

build image:
  stage: build
  image: docker:git
  services:
  - docker:dind
  script:
    - build_terraform

.auto_devops: &auto_devops |
  [[ "$TRACE" ]] && set -x
  export CI_APPLICATION_TAG=$CI_COMMIT_SHA
  [[ "$CI_APPLICATION_TAG" = "master" ]] && export CI_APPLICATION_TAG="latest"
  [[ "$CI_COMMIT_TAG" ]] && export CI_APPLICATION_TAG=$CI_COMMIT_TAG

  build_terraform() {
    export CI_APPLICATION_REPOSITORY=$CI_REGISTRY_IMAGE/hetzner
    docker build --pull --rm -t "$CI_APPLICATION_REPOSITORY:$CI_APPLICATION_TAG" hetzner/

    if [[ -n "$CI_REGISTRY_USER" ]]; then
      echo "Logging to GitLab Container Registry with CI credentials..."
      docker login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" "$CI_REGISTRY"
      echo ""
    fi

    echo "Pushing to GitLab Container Registry..."
    docker push "$CI_APPLICATION_REPOSITORY:$CI_APPLICATION_TAG"
    echo ""
  }


before_script:
  - *auto_devops

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment