Schedule Weekly OpenSearch Backups Using the FormKiQ CLI
What You Will Build
This tutorial outlines how to run a weekly OpenSearch snapshot backup using the FormKiQ CLI.
The scheduled workflow uses:
- The FormKiQ CLI
--opensearch --create-snapshotcommand. - AWS CodeBuild as the short-lived runtime for the CLI.
- Amazon EventBridge Scheduler to start the backup once per week.
- An IAM role that lets the CLI discover the FormKiQ deployment and call the IAM-authenticated FormKiQ API.
At the end of the tutorial, you will have a weekly scheduled job that creates snapshots with date-based names such as weekly-default-2026-06-26.
Before You Begin
Confirm you have:
- A FormKiQ Advanced or Enterprise deployment with the OpenSearch module installed.
- OpenSearch snapshot support enabled for the deployment.
- A FormKiQ CLI Linux release asset URL from the FormKiQ CLI releases page.
- AWS CLI access to the AWS account and Region where FormKiQ is deployed.
- Permission to create IAM roles, IAM policies, CodeBuild projects, EventBridge schedules, and CloudWatch Logs.
- The FormKiQ
AppEnvironment, AWS Region, and site ID to back up.
Manual snapshot backups are for provisioned OpenSearch domains. Snapshot backups are not supported for OpenSearch Serverless.
Variables Used
| Placeholder | Description |
|---|---|
AWS_REGION | AWS Region where FormKiQ and the scheduled backup resources run. |
APP_ENVIRONMENT | FormKiQ application environment used by the CLI to discover stack outputs. |
SITE_ID | FormKiQ site ID to back up. Use default unless your deployment uses multiple sites. |
FK_CLI_ZIP_URL | Linux FormKiQ CLI zip asset URL from the FormKiQ CLI releases page. |
SNAPSHOT_PREFIX | Prefix for generated OpenSearch snapshot names. |
PROJECT_NAME | CodeBuild project that runs the CLI backup command. |
CODEBUILD_ROLE_NAME | IAM role used by the CodeBuild project. |
SCHEDULER_ROLE_NAME | IAM role used by EventBridge Scheduler to start CodeBuild. |
SCHEDULE_NAME | EventBridge schedule name. |
Set the variables before running the examples:
Open the FormKiQ CLI releases page, choose the release you want to run, and copy the Linux zip asset URL into FK_CLI_ZIP_URL.
export AWS_REGION="us-east-1"
export APP_ENVIRONMENT="prod"
export SITE_ID="default"
export FK_CLI_ZIP_URL="PASTE_LINUX_FORMKIQ_CLI_ZIP_ASSET_URL"
export SNAPSHOT_PREFIX="weekly-${SITE_ID}"
export PROJECT_NAME="formkiq-opensearch-weekly-backup"
export CODEBUILD_ROLE_NAME="formkiq-opensearch-weekly-backup-codebuild"
export SCHEDULER_ROLE_NAME="formkiq-opensearch-weekly-backup-scheduler"
export SCHEDULE_NAME="formkiq-opensearch-weekly-backup"
export AWS_ACCOUNT_ID="$(aws sts get-caller-identity --query Account --output text)"
Workflow Overview
- Verify the FormKiQ CLI backup command manually.
- Create the CodeBuild service role.
- Create the CodeBuild project that downloads and runs the CLI.
- Run the CodeBuild project once on demand.
- Create the EventBridge Scheduler role.
- Schedule the CodeBuild project to run weekly.
- Verify weekly snapshots.
- Document restore and cleanup procedures.
Step 1: Verify the Backup Command Manually
Run one backup from a workstation or AWS CloudShell before automating it:
fk --configure \
--app-environment "${APP_ENVIRONMENT}" \
--region "${AWS_REGION}"
Create a test snapshot:
SNAPSHOT_NAME="${SNAPSHOT_PREFIX}-manual-$(date -u +%Y-%m-%d)"
fk --opensearch \
--create-snapshot \
--site-id "${SITE_ID}" \
--snapshot-name "${SNAPSHOT_NAME}"
If the manual command fails, resolve the FormKiQ profile, IAM permission, or OpenSearch snapshot configuration before creating the schedule.
Step 2: Create the CodeBuild Service Role
Create a trust policy for CodeBuild:
cat > codebuild-trust-policy.json <<'EOF'
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "codebuild.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
EOF
Create the role:
aws iam create-role \
--role-name "${CODEBUILD_ROLE_NAME}" \
--assume-role-policy-document file://codebuild-trust-policy.json \
--region "${AWS_REGION}"
Create a permissions policy for the backup job:
cat > codebuild-permissions-policy.json <<'EOF'
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:PutLogEvents"
],
"Resource": "*"
},
{
"Effect": "Allow",
"Action": [
"cloudformation:DescribeStacks",
"cloudformation:ListStacks"
],
"Resource": "*"
},
{
"Effect": "Allow",
"Action": "execute-api:Invoke",
"Resource": "*"
}
]
}
EOF
Attach the policy:
aws iam put-role-policy \
--role-name "${CODEBUILD_ROLE_NAME}" \
--policy-name FormKiQOpenSearchWeeklyBackup \
--policy-document file://codebuild-permissions-policy.json \
--region "${AWS_REGION}"
The example uses broad resources to keep the tutorial readable. For production, scope execute-api:Invoke to the FormKiQ API ARN and scope CloudWatch Logs to the CodeBuild log group.
Step 3: Create the CodeBuild Project
Create a buildspec that downloads the FormKiQ CLI, configures it with the CodeBuild role credentials, and creates a snapshot with a date-based name:
cat > buildspec.yml <<'EOF'
version: 0.2
phases:
install:
commands:
- curl -L -o formkiq-cli.zip "${FK_CLI_ZIP_URL}"
- unzip -o formkiq-cli.zip
- chmod +x fk
- ./fk --help
pre_build:
commands:
- ./fk --configure --app-environment "${APP_ENVIRONMENT}" --region "${AWS_REGION}"
build:
commands:
- SNAPSHOT_NAME="${SNAPSHOT_PREFIX}-$(date -u +%Y-%m-%d)"
- ./fk --opensearch --create-snapshot --site-id "${SITE_ID}" --snapshot-name "${SNAPSHOT_NAME}"
EOF
Create the CodeBuild project definition:
cat > codebuild-project.json <<EOF
{
"name": "${PROJECT_NAME}",
"source": {
"type": "NO_SOURCE",
"buildspec": "$(python3 -c 'import json; print(json.dumps(open("buildspec.yml").read()))')"
},
"artifacts": {
"type": "NO_ARTIFACTS"
},
"environment": {
"type": "LINUX_CONTAINER",
"image": "aws/codebuild/standard:7.0",
"computeType": "BUILD_GENERAL1_SMALL",
"environmentVariables": [
{
"name": "AWS_REGION",
"value": "${AWS_REGION}",
"type": "PLAINTEXT"
},
{
"name": "APP_ENVIRONMENT",
"value": "${APP_ENVIRONMENT}",
"type": "PLAINTEXT"
},
{
"name": "SITE_ID",
"value": "${SITE_ID}",
"type": "PLAINTEXT"
},
{
"name": "SNAPSHOT_PREFIX",
"value": "${SNAPSHOT_PREFIX}",
"type": "PLAINTEXT"
},
{
"name": "FK_CLI_ZIP_URL",
"value": "${FK_CLI_ZIP_URL}",
"type": "PLAINTEXT"
}
]
},
"serviceRole": "arn:aws:iam::${AWS_ACCOUNT_ID}:role/${CODEBUILD_ROLE_NAME}"
}
EOF
Create the project:
aws codebuild create-project \
--cli-input-json file://codebuild-project.json \
--region "${AWS_REGION}"
Step 4: Run the Backup Job On Demand
Start the CodeBuild project:
aws codebuild start-build \
--project-name "${PROJECT_NAME}" \
--region "${AWS_REGION}"
Open the CodeBuild build logs and confirm the fk --opensearch --create-snapshot command completed successfully.
Step 5: Create the EventBridge Scheduler Role
Create a trust policy for EventBridge Scheduler:
cat > scheduler-trust-policy.json <<'EOF'
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "scheduler.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
EOF
Create the role:
aws iam create-role \
--role-name "${SCHEDULER_ROLE_NAME}" \
--assume-role-policy-document file://scheduler-trust-policy.json \
--region "${AWS_REGION}"
Allow the scheduler to start only this CodeBuild project:
cat > scheduler-permissions-policy.json <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "codebuild:StartBuild",
"Resource": "arn:aws:codebuild:${AWS_REGION}:${AWS_ACCOUNT_ID}:project/${PROJECT_NAME}"
}
]
}
EOF
Attach the policy:
aws iam put-role-policy \
--role-name "${SCHEDULER_ROLE_NAME}" \
--policy-name StartFormKiQOpenSearchWeeklyBackup \
--policy-document file://scheduler-permissions-policy.json \
--region "${AWS_REGION}"
Step 6: Create the Weekly Schedule
Create a weekly schedule that starts the CodeBuild project every Sunday at 06:00 UTC:
aws scheduler create-schedule \
--name "${SCHEDULE_NAME}" \
--schedule-expression "cron(0 6 ? * SUN *)" \
--flexible-time-window Mode=OFF \
--target "Arn=arn:aws:scheduler:::aws-sdk:codebuild:startBuild,RoleArn=arn:aws:iam::${AWS_ACCOUNT_ID}:role/${SCHEDULER_ROLE_NAME},Input={\"ProjectName\":\"${PROJECT_NAME}\"}" \
--region "${AWS_REGION}"
Adjust the cron expression to match your recovery point objective and preferred maintenance window.
Step 7: Verify the Result
After the first scheduled run:
- Confirm the EventBridge schedule invocation succeeded.
- Confirm the CodeBuild build completed successfully.
- Review the CodeBuild logs for the generated snapshot name.
- Use the FormKiQ CLI to return the snapshot list JSON and confirm the snapshot exists:
fk --opensearch \
--list-snapshots \
--site-id "${SITE_ID}"
Inspect the generated snapshot details:
fk --opensearch \
--get-snapshot \
--site-id "${SITE_ID}" \
--snapshot-name "weekly-default-YYYY-MM-DD"
Document the snapshot naming pattern and the expected weekly run time in your operations handbook.
Restore Procedure
Keep the restore command in your recovery runbook:
fk --opensearch \
--restore-snapshot \
--site-id "${SITE_ID}" \
--snapshot-name "weekly-default-YYYY-MM-DD"
The restore operation creates a separate restored OpenSearch index. Confirm restored-index access and search behavior before using it for production recovery.
Clean Up
To remove the scheduled backup resources:
aws scheduler delete-schedule \
--name "${SCHEDULE_NAME}" \
--region "${AWS_REGION}"
aws codebuild delete-project \
--name "${PROJECT_NAME}" \
--region "${AWS_REGION}"
aws iam delete-role-policy \
--role-name "${SCHEDULER_ROLE_NAME}" \
--policy-name StartFormKiQOpenSearchWeeklyBackup \
--region "${AWS_REGION}"
aws iam delete-role \
--role-name "${SCHEDULER_ROLE_NAME}" \
--region "${AWS_REGION}"
aws iam delete-role-policy \
--role-name "${CODEBUILD_ROLE_NAME}" \
--policy-name FormKiQOpenSearchWeeklyBackup \
--region "${AWS_REGION}"
aws iam delete-role \
--role-name "${CODEBUILD_ROLE_NAME}" \
--region "${AWS_REGION}"
This cleanup removes the schedule and runner. It does not delete OpenSearch snapshots.
Troubleshooting
| Problem | Likely cause | What to check |
|---|---|---|
fk --configure fails in CodeBuild | The role cannot discover the FormKiQ CloudFormation stack. | Confirm APP_ENVIRONMENT, AWS_REGION, and cloudformation:ListStacks / cloudformation:DescribeStacks. |
fk --opensearch --create-snapshot fails | Snapshot support is not enabled or OpenSearch Serverless is used. | Confirm the OpenSearch module configuration and snapshot repository support. |
| CodeBuild cannot call the FormKiQ API | Missing API invoke permission or wrong Region/API URL. | Confirm execute-api:Invoke, the FormKiQ IamApiUrl, and CodeBuild Region. |
| EventBridge Scheduler does not start the build | Scheduler role cannot start CodeBuild or schedule is disabled. | Confirm the scheduler target, role ARN, codebuild:StartBuild, and schedule state. |
| Snapshot names collide | The generated name is not unique for your schedule frequency. | Include a date, timestamp, or build number in SNAPSHOT_NAME. |