Skip to main content

Ad-hoc Approvals

Introduction

Ideally, all schema changes should be pre-approved. However, in some cases, you might not have a pre-approved plan for a schema change. For instance, you might be deploying a schema after some manual change was made to the target database, or you might be deploying to an environment that doesn't have a CI pipeline for schema changes at all.

In such cases, you can set up an ad-hoc approval flow to define in which cases the Operator should pause the migration process and wait for human approval before applying the schema change.

Overview

Using the policy.lint.review configuration, users may control how the Operator should behave when it encounters a schema change without a pre-approved plan. The possible values for this configuration are:

Description
ALWAYSPauses the migration process and waits for human approval before applying the schema change.
WARNINGAnalyze the proposed schema change and wait for approval if any diagnostics are found.
ERRORAnalyze the proposed schema change and wait for approval if any severe diagnostics (errors) are found.

Guide: Using Ad-hoc Approvals

Step 1: Install the Operator and apply a schema

To get started, please follow the Quickstart guide to install the Atlas Operator, a database and an AtlasSchema resource.

Your AtlasSchema resource should look something like this:

apiVersion: db.atlasgo.io/v1alpha1
kind: AtlasSchema
metadata:
name: atlasschema-pg
spec:
urlFrom:
secretKeyRef:
key: url
name: postgres-credentials
schema:
sql: |
create table t1 (
id int
);

Verify that this schema is applied correcly to the database:

kubectl wait --for=condition=Ready -f atlas-schema.yaml

If the schema was applied correctly, you should see the following output:

atlasschema.db.atlasgo.io/atlasschema-pg condition met

Step 2: Create a Schema Registry Repo

In order to use ad-hoc approvals, the Atlas Operator needs a backing repository to store the plans and their state.

  1. Before proceeding, make sure you have an account on Atlas Cloud. If you don't have one you can create one for free in under a minute on our signup page.

  2. Once you have an account, create a new repository by clicking the "New" button in the top right corner of the page.

  3. Choose "Declarative Workflow".

  4. Name your repository, in our example we are using ad-hoc-approval.

  5. Choose the database engine you're using (in our example we are using PostgreSQL).

  6. Click "Create Repository".

Step 3: Create a Bot Token Secret

In order for the Operator to be able to interact with the Schema Registry, it needs a bot token.

  1. Follow the documentation for creating a bot token.
  2. Create a secret in your Kubernetes cluster with the bot token:
kubectl create secret generic atlas-token --from-literal=token=<your token here>

Step 4: Update the AtlasSchema resource

Next, update the AtlasSchema resource to include a reference to our newly created Schema Registry repository, our bot token secret, and the policy.lint.review configuration:

apiVersion: db.atlasgo.io/v1alpha1
kind: AtlasSchema
metadata:
name: atlasschema-pg
spec:
urlFrom:
secretKeyRef:
key: url
name: postgres-credentials
cloud:
repo: ad-hoc-approval
tokenFrom:
secretKeyRef:
name: atlas-token
key: token
policy:
lint:
review: ALWAYS
schema:
sql: |
create table t1 (
id int
);

Notice the following changes:

  1. We added a cloud section to the AtlasSchema resource. This section contains the repo field, which references the name of the Schema Registry repository we created in Step 2. The tokenFrom field references the secret we created in Step 3.

  2. We added a policy.lint.review field to the AtlasSchema resource. This field tells the Operator to pause the migration process and wait for human approval before applying the schema change.

Apply the updated schema:

kubectl apply -f atlas-schema.yaml

Step 5: Verify approval is required

Next, let's modify the schema to add a new column name to the t1 table. Update the atlas-schema.yaml file with the following content:

apiVersion: db.atlasgo.io/v1alpha1
kind: AtlasSchema
metadata:
name: atlasschema-pg
spec:
urlFrom:
secretKeyRef:
key: url
name: postgres-credentials
cloud:
repo: ad-hoc-approval
tokenFrom:
secretKeyRef:
name: atlas-token
key: token
policy:
lint:
review: ALWAYS
schema:
sql: |
create table t1 (
id int,
name text
);

Apply the updated schema:

kubectl apply -f atlas-schema.yaml

If we did everything correctly, the Operator should pause the migration process and wait for human approval before applying the schema change. You can verify this by checking the status of the AtlasSchema resource:

kubectl get atlasschema atlasschema-pg -o=jsonpath='{range .status.conditions[?(@.type=="Ready")]}Ready: {.status}{"\n"}Reason: {.reason}{"\n"}Message: {.message}{"\n"}{end}PlanLink: {.status.planLink}{"\n"}'

You should see something similar to:

Ready: False
Reason: ApprovalPending
Message: Schema plan is waiting for approval
PlanLink: https://rotemtam85.atlasgo.cloud/schemas/141733920787/plans/210453397576

Visit the PlanLink URL to review the proposed schema change and approve it:

Once the plan is approved, the Operator will apply the schema change to the database.

You can verify this using kubectl wait:

kubectl wait --for=condition=Ready atlasschema/atlasschema-pg --timeout=5s

If the schema was applied correctly, you should see the following output:

atlasschema.db.atlasgo.io/atlasschema-pg condition met

Alternative Policies

In this guide, we used the ALWAYS policy to require human approval for all schema changes. However, teams might not want to require approval for every schema change. As we mentioned in the Overview, there are two other possible values for the policy.lint.review configuration:

  1. WARNING: Analyze the proposed schema change and wait for approval if any diagnostics are found.
  2. ERROR: Analyze the proposed schema change and wait for approval if any severe diagnostics (errors) are found. By default, only destructive changes are considered errors.

Suppose you want to require approval only for destructive changes. In that case, you can set the policy.lint.review configuration to ERROR. This way, the Operator will pause the migration process and wait for human approval only if the proposed schema change contains destructive changes such as dropping a table or column.

Conclusion

In this guide, we learned how to set up an ad-hoc approval flow to define in which cases the Operator should pause the migration process and wait for human approval before applying the schema change.