One of the largest benefits of Architects framework is that provisioning new environments is always limited to a single step, architect deploy. No matter how complex the application is or how many dependencies it has, architect deploy is able to automatically provision it in a new environment.

What this means is that not only can developers run the stack privately, but the stack can also be provisioned automatically whenever there is a new branch or pull request. This automation is perfect for creating previews of impending code changes so that product managers can review and integration tests can be run end to end.

Github Actions

Create preview environment

The workflow below can be pasted into a file in your repository in the .github/workflows folder to trigger automated preview environments via Architect. These previews will be created whenever a pull request is submitted that targets the master branch. Be sure to set values in Github Secrets for the architect fields: ARCHITECT_EMAIL and ARCHITECT_PASSWORD. Replace <account-name>, <cluster-name> with the appropriate values.

ARCHITECT_PASSWORD must be a personal access token.

name: Architect Preview

on:
  pull_request:
    types:
      - opened
      - synchronize
      - reopened

env:
  ARCHITECT_EMAIL: ${{ secrets.ARCHITECT_EMAIL }}
  ARCHITECT_PASSWORD: ${{ secrets.ARCHITECT_PASSWORD }}
  ARCHITECT_ACCOUNT: <account-name>

jobs:
  deploy_environment:
    runs-on: ubuntu-latest
    permissions:
      contents: read
      issues: write
      pull-requests: write
    steps:
      - uses: actions/checkout@v3
      - uses: actions/setup-node@v3
        with:
          node-version: '18'
      - name: Setup docker build caching
        uses: crazy-max/ghaction-github-runtime@v2.1.0
      - name: Install Architect CLI
        run:  npm install -g @architect-io/cli
      - name: Login to Architect Cloud
        run: architect login
      - name: Convert branch to environment name
        shell: bash
        run: echo "env_name=${GITHUB_HEAD_REF/\//-}" >> $GITHUB_OUTPUT
        id: extract_branch
      - name: Create env if not exists
        run: architect environment:create ${{ steps.extract_branch.outputs.env_name }} --cluster <cluster-name>
      - name: Register and deploy component
        run: architect deploy --auto-approve -e ${{ steps.extract_branch.outputs.env_name }} ./architect.yml
      - name: Get ingress routes
        id: get_ingress_routes
        run: echo "ingresses=\"$(architect environment:ingresses ${{ steps.extract_branch.outputs.env_name }})\"" >> $GITHUB_OUTPUT
      - name: Architect preview information PR comment
        uses: actions/github-script@v6
        with:
          script: |
            github.rest.issues.createComment({
              issue_number: context.issue.number,
              owner: context.repo.owner,
              repo: context.repo.repo,
              body: `Changes are live:
              ${{ steps.get_ingress_routes.outputs.ingresses }}`
            })

Cleaning up the environment

Once your PR is closed, either because it was merged in successfully or closed and rejected, you’ll likely want to clean up the environment so that you don’t incur continued costs. Github Actions and Architect make this easy, and you can just copy and paste the following workflow into another file in your .github/workflows folder:

name: Clean up preview environment

on:
  pull_request:
    types:
      - closed

env:
  ARCHITECT_EMAIL: ${{ secrets.ARCHITECT_EMAIL }}
  ARCHITECT_PASSWORD: ${{ secrets.ARCHITECT_PASSWORD }}
  ARCHITECT_ACCOUNT: reach-demo

jobs:
  remove_environment:
    runs-on: ubuntu-latest
    permissions:
      contents: read
      issues: write
      pull-requests: write
    steps:
      - uses: actions/checkout@v3
      - uses: actions/setup-node@v3
        with:
          node-version: '18'
      - name: Install Architect CLI
        run:  npm install -g @architect-io/cli
      - name: Login to Architect Cloud
        run: architect login
      - name: Convert branch to environment name
        shell: bash
        run: echo "env_name=${GITHUB_HEAD_REF/\//-}" >> $GITHUB_OUTPUT
        id: extract_branch
      - name: Remove components from environment
        run: architect destroy -e ${{ steps.extract_branch.outputs.env_name }} --auto-approve
      - name: Remove environment
        run: architect environment:destroy ${{ steps.extract_branch.outputs.env_name }} --auto-approve
      - name: Architect preview information PR comment
        uses: actions/github-script@v6
        with:
          script: |
            github.rest.issues.createComment({
              issue_number: context.issue.number,
              owner: context.repo.owner,
              repo: context.repo.repo,
              body: `PR environment cleaned up successfully`
            })

Post updates to slack

Depending on the size of your application your PR environment might take a while to first boot up. If you want to receive notifications in slack when the deployments are done, use slacks github action as the last step in your PR workflows. Just replace <slack-webhook-url> with one you generate from your slack organization settings:

# ...

jobs:
  deploy_environment:
    steps:
      # ...
      - name: Post Architect preview information to Slack
        id: slack
        uses: slackapi/slack-github-action@v1.14.0
        with:
          payload: "{\"preview_env\":\"https://cloud.architect.io/${{ secrets.ARCHITECT_ACCOUNT }}/environments/${{ steps.extract_branch.outputs.env_name }}\",\"app_endpoints\":\"${{ steps.get_ingress_routes.outputs.ingresses }}\"}"
        env:
          SLACK_WEBHOOK_URL: <slack-webhook-url>

Gitlab CI

Creating and cleaning up preview environments

This job can be pasted into your .gitlab-ci.yml at the root of your repository. You are welcome to change the stage to whatever fits your needs to allow you to run tests before the preview is generated. Please be sure to assign correct values for the variables in the job marked with <set-this-as-a-CI/CD-variable> as well as the ones mentioned in the note below.

This configuration takes advantage of GitLab environments in order to give you better control and visibility into what environments exist and what’s deployed to them. On PR creation, both a GitLab and Architect environment will be created. The component specified in the repository will be registered with the Architect Cloud and deployed to the environment. When the PR is either merged or closed, the GitLab environment will be automatically deleted and the component deployed to the environment in the Architect Cloud will be destroyed.

This example assumes that the repo has ARCHITECT_EMAIL, ARCHITECT_PASSWORD, ARCHITECT_ACCOUNT, and ARCHITECT_CLUSTER set as CI/CD variables.

ARCHITECT_PASSWORD must be a personal access token.

stages:
  - preview

variables:
  ARCHITECT_ACCOUNT: <set-this-as-a-CI/CD-variable>
  ARCHITECT_CLUSTER: <set-this-as-a-CI/CD-variable>
  ARCHITECT_ENVIRONMENT: preview-$CI_MERGE_REQUEST_ID
  ARCHITECT_CACHE_DIR: .architect-cache/

.preview_common: &preview_common
  image: docker:23.0.1
  services:
    - docker:23.0.1-dind
  before_script:
    - apk add --update npm
    - npm install -g @architect-io/cli
    - architect login -e $ARCHITECT_EMAIL -p $ARCHITECT_PASSWORD

deploy_preview:
  <<: *preview_common
  stage: preview
  timeout: 1h
  script:
    - architect environment:create "${ARCHITECT_ENVIRONMENT}" --description="https://gitlab.com/${CI_MERGE_REQUEST_PROJECT_PATH}/-/merge_requests/${CI_MERGE_REQUEST_IID}"
    - architect deploy ./architect.yml --auto-approve --cache-directory=$ARCHITECT_CACHE_DIR
  environment:
    name: $ARCHITECT_ACCOUNT/preview-$CI_MERGE_REQUEST_IID
    on_stop: destroy_preview
  rules:
    - if: $CI_MERGE_REQUEST_IID
  cache:
    key: architect-preview-cache-$CI_COMMIT_REF_SLUG
    paths:
      - $ARCHITECT_CACHE_DIR

destroy_preview:
  <<: *preview_common
  stage: preview
  script:
    - architect destroy --auto-approve
    - architect environment:destroy "${ARCHITECT_ENVIRONMENT}" --auto-approve
  environment:
    name: $ARCHITECT_ACCOUNT/preview-$CI_MERGE_REQUEST_IID
    action: stop
  rules:
    - if: $CI_MERGE_REQUEST_ID
      when: manual
    - if: $CI_MERGE_REQUEST_APPROVED

BitBucket Pipelines

Creating and cleaning up preview environments

This job can be pasted into your bitbucket-pipelines.yml at the root of your repository. Be sure to add repository variables for the ones mentioned in the note below.

On pull request creation, an Architect environment will be created. The component specified in the repository will be registered with the Architect Cloud and deployed to the environment. The pipeline provides the option to remove the deployed component and its environment from the Architect Cloud manually, which should be done once the pull request is merged or closed.

This example assumes that the repo has ARCHITECT_EMAIL, ARCHITECT_PASSWORD, ARCHITECT_ACCOUNT, and ARCHITECT_CLUSTER set as CI/CD variables.

ARCHITECT_PASSWORD must be a personal access token.

image: docker:23.0.1

pipelines:
  pull-requests:
    '**':
      - step:
          name: 'Deploy preview'
          services:
            - docker
          script:
            - apk add --update npm
            - npm install -g @architect-io/cli
            - architect login
            - architect environment:create preview-$BITBUCKET_PR_ID --description="https://bitbucket.com/$BITBUCKET_WORKSPACE/$BITBUCKET_REPO_SLUG/pull-requests/$BITBUCKET_PR_ID" --ttl=1d
            - architect deploy ./architect.yml --environment preview-$BITBUCKET_PR_ID --auto-approve
      - step:
          name: 'Destroy preview'
          trigger: 'manual'
          services:
            - docker
          script:
            - apk add --update npm
            - npm install -g @architect-io/cli
            - architect login
            - architect destroy --environment preview-$BITBUCKET_PR_ID --auto-approve
            - architect environment:destroy preview-$BITBUCKET_PR_ID --auto-approve

The --ttl flag is used here in order to clean up the environment automatically after one day because BitBucket doesn’t have a feature to trigger a pipeline when a pull request is closed.

CircleCI

CircleCI doesn’t have complete features to handle preview environment creation and destruction, but the Trigger CircleCI Pipeline GitHub Action can help to work around that. The CircleCI GitHub Action can be used in combination with GitHub’s event triggers to run a CircleCI workflow.

This example assumes that ARCHITECT_EMAIL, ARCHITECT_PASSWORD, ARCHITECT_ACCOUNT, and ARCHITECT_CLUSTER are set as project variables in CircleCI. Also, the variable CCI_TOKEN must be a CircleCI personal access token and be set as a GitHub Action secret in the GitHub repo. CCI_TOKEN should not be set to a CircleCI project-specific API token.

ARCHITECT_PASSWORD must be a personal access token.

Preview environment creation trigger

The file circleci-create-preview.yml will trigger a CircleCI workflow to be run when a pull request is created or updated in GitHub. Note that GHA_Meta is set to ARC_CREATE_PREVIEW in order to inform the CircleCI workflow to run only the preview creation job.

# .github/workflows/circleci-create-preview.yml
name: Preview environment create trigger

on:
  pull_request:

jobs:
  architect_create_preview:
    runs-on: ubuntu-latest
    steps:
      - name: Trigger CircleCI Pipeline
        uses: CircleCI-Public/trigger-circleci-pipeline-action@v1.0.7
        env:
          CCI_TOKEN: ${{ secrets.CCI_TOKEN }}
        with:
          GHA_Meta: ARC_CREATE_PREVIEW

Preview environment destruction trigger

The file circleci-destroy-preview.yml will trigger a CircleCI workflow to be run when a pull request is closed in GitHub. As preview environments are named preview-<pull_request_number> in the CircleCI workflows, GHA_Meta is set to the pull request number in order to let the CircleCI preview destruction workflow know which component and environment to destroy. This is set in the GitHub Action and passed to CircleCI because this number isn’t available in a CircleCI workflow when a pull request is closed.

# .github/workflows/circleci-destroy-preview.yml
name: Preview environment destroy trigger

on:
  pull_request:
    types:
      - closed

jobs:
  architect_destroy_preview:
    runs-on: ubuntu-latest
    steps:
      - name: Trigger CircleCI Pipeline
        uses: CircleCI-Public/trigger-circleci-pipeline-action@v1.0.7
        env:
          CCI_TOKEN: ${{ secrets.CCI_TOKEN }}
        with:
          GHA_Meta: ${{ github.event.number }}

Preview environment workflows

The CircleCI config file will run the actual Architect preview environment creation and destruction workflows triggered by the GitHub Actions. The workflow conditions are set so that a preview environment will be created when the workflow is triggered with << pipeline.parameters.GHA_Meta >> equal to ARC_CREATE_PREVIEW. A preview environment destruction workflow will be triggered when << pipeline.parameters.GHA_Meta >> isn’t equal to ARC_CREATE_PREVIEW.

# .circleci/config.yml
version: 2.1

parameters: # parameters required by the "Trigger CircleCI Pipeline" GitHub Action
  GHA_Action:
    type: string
    default: ""
  GHA_Meta:
    type: string
    default: ""
  GHA_Actor:
    type: string
    default: ""
  GHA_Event:
    type: string
    default: ""

.job_common: &job_common
  docker:
    - image: cimg/node:18.14.1

jobs:
  create_preview:
    <<: *job_common
    steps:
      - run:
          name: Set up PR number environment variable
          command: |
            export PR_NUMBER=$(echo << pipeline.git.branch >> | sed 's/[^0-9]*//g')
            echo "export PR_NUMBER=$PR_NUMBER" >> "$BASH_ENV"
      - run:
          name: Create environment
          command: architect environment:create preview-$PR_NUMBER
      - run:
          name: Deploy component
          command: architect deploy architect.yml --auto-approve -e preview-$PR_NUMBER
  destroy_preview:
    <<: *job_common
    steps:
      - run:
          name: Set up PR number environment variable
          command: |
            export PR_NUMBER=<< pipeline.parameters.GHA_Meta >>
            echo "export PR_NUMBER=$PR_NUMBER" >> "$BASH_ENV"
      - run:
          name: Destroy component
          command: architect destroy --environment preview-$PR_NUMBER --auto-approve
      - run:
          name: Destroy environment
          command: architect environment:destroy preview-$PR_NUMBER --auto-approve

.pre_job_common: &pre_job_common
  pre-steps:
    - checkout
    - setup_remote_docker:
        version: 20.10.18
        docker_layer_caching: true
    - run:
        name: Install Architect CLI
        command: npm install -g @architect-io/cli
    - run:
        name: Log in to Architect
        command: architect login

workflows:
  create_preview_workflow:
    when:
      and:
        - equal: [ ARC_CREATE_PREVIEW, << pipeline.parameters.GHA_Meta >>]
        - << pipeline.parameters.GHA_Action >> # included to prevent double execution of CircleCI workflows - https://github.com/marketplace/actions/trigger-circleci-pipeline#to-prevent-double-execution
    jobs:
      - create_preview:
          <<: *pre_job_common
  destroy_preview_workflow:
    when:
      and:
        - not:
            equal: [ ARC_CREATE_PREVIEW, << pipeline.parameters.GHA_Meta >>]
        - << pipeline.parameters.GHA_Action >>
    jobs:
      - destroy_preview:
          <<: *pre_job_common