Automated preview environments
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