The default deployment process will create an instance of the component as an unnamed global tenant, but you can deploy a separate instance by providing a tenanat name. Having multiple instances of a component deployed in this manner is called a “multi-tenant deployment”.

architect deploy react-app@app1

This process works for updating existing deployments as well. If an “app1” tenant of the examples/react-app component had already been deployed, the above command would have deployed to that same tenant, leaving any other instances of the component untouched.

Deployments and management lifecycle

When you view your deployed components, you’ll see that the react-app has the name “app1” whereas the typical deployment without a tenant name will show only the component. In this example we’ve deployed the example React App twice with the tenant names “app1” and “app2”, and once without a tenant name.

Secrets and values

Configuring individual tenants works the same way as deploying those tenants: by providing the tenant name. Secrets use the component scopes to specify which values will be applied to which components, so setting a secret for a tenant is as simple as providing the tenant name in the component scope.

In the case of the example React App, the following will override the world_text secret for just the sandiego tenant.

"react-app@sandiego":
  world_text: San Diego

This enables minimal duplication of configuration, as you can specify any necessary values in a generic component scope, but then override specific values on a tenant-by-tenant basis. In the following example, the planetearth tenant would have the foo secret as configured in the first scope, but would have the overwritten values for world_text set in the second scope.

"react-app":
  foo: bar
  world_text: world!
"react-app@planetearth":
  world_text: Planet Earth

Automating deployments

Want to make it as easy as possible for your team to create tenants? Try creating a tenant file in your repository that gets read in by your CI jobs to automate deployments.

./tenants.json
[
  {
    "name": "cool-customer",
    "description": "The coolest of customers",
    "owner": "thor@architect.io"
  },
  {
    "name": "rad-customer",
    "description": "The raddest of customers",
    "owner": "ironman@architect.io"
  }
]

Setting up the workflow

With a file like that in the root of your repository, you can iterate over the list of tenants directly in your CI workflow.

name: Deploy tenants

env:
  ARCHITECT_EMAIL: ${{ secrets.ARCHITECT_EMAIL }} # pass secrets into a job from Github > Settings > Secrets
  ARCHITECT_PASSWORD: ${{ secrets.ARCHITECT_PASSWORD }}
  ARCHITECT_ACCOUNT: <account-name>

on:
  push:
    branches:
      - main

jobs:
  register:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - uses: actions/setup-node@v3
        with:
          node-version: "16"
      - uses: crazy-max/ghaction-github-runtime@v2
      - name: Install Architect CLI
        run: npm install -g @architect-io/cli
      - name: Login to Architect Cloud
        run: architect login
      - name: Register component
        run: architect register ./architect.yml --tag latest

  get-tenants:
    runs-on: ubuntu-latest
    outputs:
      matrix: ${{ steps.get-tenants.outputs.matrix }}
    steps:
      - uses: actions/checkout@v3
      - id: get-tenants
        run: |
          JSON=$(cat ./tenants.json)
          echo "::set-output name=matrix::${JSON//'%'/'%25'}"
  
  deploy:
    needs: [get-tenants, register]
    runs-on: ubuntu-latest
    strategy:
      matrix: ${{ fromJson(needs.get-tenants.outputs.matrix) }}
    steps:
      - uses: actions/checkout@v3
      - uses: actions/setup-node@v3
        with:
          node-version: "16"
      - uses: crazy-max/ghaction-github-runtime@v2
      - name: Install Architect CLI
        run: npm install -g @architect-io/cli
      - name: Login to Architect Cloud
        run: architect login
      - name: Register and deploy to Staging
        run: architect deploy app:latest@${{ matrix.name }} --environment production --auto-approve