Aptible deploy docker image from CI


#1

So I’ve set up my circle ci to build and test my applications docker image. I would like CI to be able to directly deploy my tested image to aptible with the new aptible cli deployment feature. Is there a way to authorize CI to use aptible deploy without requiring an interactive login?


#2

You’ll need to log in using the CLI to be able to call aptible deploy. The CLI supports non-interactive usage for aptible login, which is what you’ll need to use here: https://www.aptible.com/documentation/enclave/cli/login.html

We recommend creating a separate user in Aptible for your CI platform.


#3

@thomas So would you need to disable 2FA for this CI account?

I tried using the toolbelt somewhere I wasn’t logged in and saw a message about using an environment variable instead of logging in. I can’t find any docs on that so would appreciate any info you could share.


#4

@rob :

  • Indeed, you’d have to disable 2FA on the robot account
  • There is indeed an environment variable called APTIBLE_ACCESS_TOKEN that can be used to provide the CLI with an access token, but that wouldn’t be useful in your scenario: you need to login to generate the access token in the first place.

#5

Saw this topic here and thought I’d add our example circleci config in case it was useful to someone. First deploys to the dev environment and then after manual approval deploys to the production environment. You do have to manually deploy the image to each app once before your first deployment so that the app stores the username and password to pull from your private docker registry using aptible deploy --git-detach --app "$APP_NAME" --docker-image "$DOCKER_IMAGE" --private-registry-username "DOCKER_USER" --private-registry-password "$DOCKER_PASSWORD". Also if you use a Procfile be sure to add it to your Dockerfile. And feel free to use our aptible-cli image if you’d like.

# Python CircleCI 2.0 configuration file
#
# Check https://circleci.com/docs/2.0/language-python/ for more details
#
version: 2
jobs:
  build:
    docker:
      - image: python:3.6

    working_directory: ~/repo

    steps:
      - checkout

      # Download and cache dependencies
      - restore_cache:
          keys:
          - v2-dependencies-{{ checksum "requirements.txt" }}-{{ checksum "requirements-dev.txt" }}
          # fallback to using the latest cache if no exact match is found
          - v2-dependencies-

      - run:
          # Put everything in a virtualenv to make it easier to cache
          name: Install dependencies
          command: |
            python -m venv ../venv
            . ../venv/bin/activate
            pip install -r requirements-dev.txt

      - save_cache:
          paths:
            - ../venv
          key: v2-dependencies-{{ checksum "requirements.txt" }}-{{ checksum "requirements-dev.txt" }}

      # run tests!
      - run:
          name: Run tests
          command: |
            . ../venv/bin/activate
            make test

      - run:
          name: Run linter
          command: |
            . ../venv/bin/activate
            make lint

      - run:
          name: Run type checker
          command: |
            . ../venv/bin/activate
            make type-check

      - run:
          name: Run static vulnerability check
          command: |
            . ../venv/bin/activate
            make bandit

  create_docker:
   machine:
     docker_layer_caching: true
   steps:
     - checkout

     - run: docker login -u $DOCKER_USER -p $DOCKER_PASS

     # build the application image
     - run:
         name: Build docker container
         command: |
           TAG_NAME=:${CIRCLE_BRANCH//\//_}
           if [ "${CIRCLE_BRANCH}" == "master" ]; then
             TAG_NAME=""
           fi
           docker build -t semprehealth/$DOCKER_IMAGE$TAG_NAME .
           docker push semprehealth/$DOCKER_IMAGE$TAG_NAME

  deploy_development:

    docker:
      - image: semprehealth/aptible-cli

    working_directory: ~/repo

    steps:

      - run:
          name: deploy to aptible
          command: |
            aptible login --email $APTIBLE_EMAIL --password $APTIBLE_PASSWORD
            aptible deploy --app "$APTIBLE_DEV_APP" --docker-image "semprehealth/$DOCKER_IMAGE"

  deploy_production:

    docker:
      - image: semprehealth/aptible-cli

    working_directory: ~/repo

    steps:

      - run:
          name: deploy to aptible
          command: |
            aptible login --email $APTIBLE_EMAIL --password $APTIBLE_PASSWORD
            aptible deploy --app "$APTIBLE_PROD_APP" --docker-image "semprehealth/$DOCKER_IMAGE"

workflows:
  version: 2
  build_deploy:
    jobs:
      - build
      - create_docker
      - deploy_development:
          requires:
            - build
            - create_docker
          filters:
            branches:
              only:
                - master
      - hold:
          type: approval
          requires:
           - deploy_development
      - deploy_production:
          requires:
            - hold

#6

Very nice; thanks for sharing @jesse!