# This CircleCI config requires the following env vars to be configured # AWS keys (to push images and trigger stack update) # see "AWS Permissions" section in your CircleCI project configuration section # OPENRESTY_REPO_URI - repo uri, do not include version tag # example: 0000000000.dkr.ecr.us-east-1.amazonaws.com/myapplication/openresty # COMPOSE_PROJECT_NAME - the name of your project, used to determine the name of your stack # Production database connection info # AWS_REGION - region where you ECS cluster is located (ex: us-east-1) # SUPER_USER - your database admin user # PRODUCTION_SUPER_USER_PASSWORD - password for the database admin user # PRODUCTION_DB_HOST - host uri (ex: myapplication-db.zzzzzzzzz.us-east-1.rds.amazonaws.com:5432) # DB_NAME - database name # PRODUCTION_DB_SECURITY_GROUP - AWS security group id that the db is in version: 2 jobs: pull_docker_images: machine: enabled: true steps: - restore_cache: keys: - v2-docker-images - run: name: docker pull & save command: | if [ ! -f ~/.docker/images.tar ]; then docker pull postgres docker pull subzerocloud/postgrest docker pull openresty/openresty:jessie docker pull lren/pgtap # docker pull subzerocloud/pg-amqp-bridge # docker pull rabbitmq:3-management mkdir -p ~/.docker docker save --output ~/.docker/images.tar \ postgres \ subzerocloud/postgrest \ openresty/openresty:jessie \ lren/pgtap # subzerocloud/pg-amqp-bridge \ # rabbitmq:3-management \ fi - save_cache: paths: - ~/.docker key: v2-docker-images install_npm_dependencies: docker: - image: circleci/node:latest steps: - checkout - restore_cache: keys: - v2-npm-dependencies-{{ checksum "package.json" }} - run: npm install - save_cache: paths: - node_modules key: v2-npm-dependencies-{{ checksum "package.json" }} test: machine: enabled: true steps: - checkout - restore_cache: keys: - v2-docker-images - restore_cache: keys: - v2-npm-dependencies-{{ checksum "package.json" }} - run: name: load cached docker images command: docker load --input ~/.docker/images.tar - run: name: bring up application stack command: docker-compose up -d db postgrest openresty && sleep 10 - run: name: run tests command: npm test deploy: machine: enabled: true # environment: # - PATH: "$PATH:/home/$USER/perl5/bin" # - PERL_CPANM_OPT: "--local-lib=/home/$USER/perl5" # - PERL5LIB: "/home/$USER/perl5/lib/perl5:$PERL5LIB" steps: - checkout - restore_cache: keys: - v3-deploy-dependencies # hack to set env var that need interpolation # (https://circleci.com/docs/2.0/env-vars/#interpolating-enviroment-variables-to-set-other-environment-variables) - run: echo 'export PATH=$PATH:/home/$USER/perl5/bin' >> $BASH_ENV - run: echo 'export PERL_CPANM_OPT="--local-lib=/home/$USER/perl5"' >> $BASH_ENV - run: echo 'export PERL5LIB=/home/$USER/perl5/lib/perl5:$PERL5LIB' >> $BASH_ENV - run: name: install dependencies command: | sudo apt-get install liblist-moreutils-perl curl -L https://cpanmin.us | perl - App::cpanminus cpanm App::Sqitch DBD::Pg - save_cache: paths: - ~/perl5 key: v3-deploy-dependencies - deploy: name: build and push openresty image command: | docker build -t openresty ./openresty/ docker tag openresty $OPENRESTY_REPO_URI:$CIRCLE_TAG aws ecr get-login --region $AWS_REGION | sh docker push $OPENRESTY_REPO_URI:$CIRCLE_TAG - deploy: name: deploy the latest database migrations command: | cd db/migrations # sqitch config --user engine.pg.client /opt/local/pgsql/bin/psql sqitch config --user user.name 'CircleCI' sqitch config --user user.email 'bot@circleci.com' sqitch target add production db:pg://$SUPER_USER:$PRODUCTION_SUPER_USER_PASSWORD@$PRODUCTION_DB_HOST/$DB_NAME sqitch engine add pg production # temporatily whitelist CircleCI ip public_ip_address=$(wget -qO- http://checkip.amazonaws.com) echo "this computers public ip address is $public_ip_address" aws ec2 authorize-security-group-ingress \ --region $AWS_REGION \ --group-id $PRODUCTION_DB_SECURITY_GROUP \ --protocol tcp \ --port 5432 \ --cidr ${public_ip_address}/32 sleep 5 sqitch deploy aws ec2 revoke-security-group-ingress \ --region $AWS_REGION \ --group-id $PRODUCTION_DB_SECURITY_GROUP \ --protocol tcp \ --port 5432 \ --cidr ${public_ip_address}/32 - deploy: name: tag openresty image as latest command: | # this will be fast since all the layers are already in the repository docker tag openresty $OPENRESTY_REPO_URI:latest docker push $OPENRESTY_REPO_URI:latest - deploy: name: trigger ECS service update command: | aws cloudformation update-stack \ --region $AWS_REGION \ --stack-name $COMPOSE_PROJECT_NAME \ --capabilities CAPABILITY_IAM \ --use-previous-template \ --parameters \ ParameterKey=ClusterName,UsePreviousValue=true \ ParameterKey=DesiredCount,ParameterValue=1 \ ParameterKey=Version,ParameterValue=$CIRCLE_TAG \ ParameterKey=OpenRestyImage,UsePreviousValue=true \ ParameterKey=ListenerHostNamePattern,UsePreviousValue=true \ ParameterKey=HasHttpsListener,UsePreviousValue=true \ ParameterKey=DbHost,UsePreviousValue=true \ ParameterKey=DbPassword,UsePreviousValue=true \ ParameterKey=JwtSecret,UsePreviousValue=true # uncomment the lines below if you changed default values # when you created the stack # ParameterKey=PostgrestImage,UsePreviousValue=true \ # ParameterKey=DbPort,UsePreviousValue=true \ # ParameterKey=DbName,UsePreviousValue=true \ # ParameterKey=DbSchema,UsePreviousValue=true \ # ParameterKey=DbUser,UsePreviousValue=true \ # ParameterKey=DbAnonRole,UsePreviousValue=true \ # ParameterKey=DbPool,UsePreviousValue=true \ # ParameterKey=MaxRows,UsePreviousValue=true \ # ParameterKey=PreRequest,UsePreviousValue=true \ workflows: version: 2 build-and-deploy: jobs: - pull_docker_images: filters: tags: only: /v[0-9]+(\.[0-9]+)*/ - install_npm_dependencies: filters: tags: only: /v[0-9]+(\.[0-9]+)*/ - test: filters: tags: only: /v[0-9]+(\.[0-9]+)*/ requires: - pull_docker_images - install_npm_dependencies - deploy: requires: - test filters: tags: only: /v[0-9]+(\.[0-9]+)*/ branches: ignore: /.*/