Skip to content

CI/CD Integration

Yaffle provides a GitHub Action to fetch OpenTofu outputs from your preview environments. Use it to deploy your application to preview infrastructure.

- uses: yaffle-dot-dev/outputs-action@v1
id: infra
with:
workspace: infra
wait: true
- name: Deploy to preview
run: |
aws ecs update-service \
--cluster ${{ steps.infra.outputs.cluster_arn }} \
--service my-app \
--force-new-deployment
  1. The action calls the Yaffle API
  2. If wait: true, it waits for the workspace to finish applying
  3. Once ready, it fetches the OpenTofu outputs
  4. Outputs are set as step outputs for use in subsequent steps
InputDescriptionDefault
workspaceWorkspace path.
waitWait for preview to be readyfalse
wait-timeoutTimeout in seconds300
pr-numberPR number (auto-detected)Current PR
orgOrganization nameRepository owner
repoRepository nameCurrent repository
OutputDescription
preview-idThe Yaffle preview ID
preview-statusStatus: ready, planning, applying, failed
outputs-jsonAll outputs as JSON
<name>Each OpenTofu output as a separate output
name: Deploy to Preview
on:
pull_request:
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
# Wait for Yaffle to finish applying infrastructure
- uses: yaffle-dot-dev/outputs-action@v1
id: infra
with:
workspace: infra
wait: true
wait-timeout: 600
# Deploy using the outputs
- name: Deploy application
run: |
echo "Deploying to cluster: ${{ steps.infra.outputs.cluster_arn }}"
echo "Using ALB: ${{ steps.infra.outputs.alb_dns }}"
# Your deployment commands here
./deploy.sh \
--cluster "${{ steps.infra.outputs.cluster_arn }}" \
--image "my-app:${{ github.sha }}"
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: yaffle-dot-dev/outputs-action@v1
id: network
with:
workspace: infra/network
wait: true
- uses: yaffle-dot-dev/outputs-action@v1
id: database
with:
workspace: infra/database
wait: true
- name: Configure app
run: |
echo "VPC: ${{ steps.network.outputs.vpc_id }}"
echo "DB Host: ${{ steps.database.outputs.endpoint }}"
jobs:
e2e-tests:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: yaffle-dot-dev/outputs-action@v1
id: infra
with:
workspace: infra
wait: true
- name: Run E2E tests
env:
API_URL: ${{ steps.infra.outputs.api_url }}
DB_HOST: ${{ steps.infra.outputs.db_endpoint }}
run: |
npm test

For outputs that are objects or lists:

- uses: yaffle-dot-dev/outputs-action@v1
id: infra
- name: Parse complex outputs
run: |
# Get all outputs as JSON
echo '${{ steps.infra.outputs.outputs-json }}' | jq '.'
# Extract specific nested values
SUBNET_IDS=$(echo '${{ steps.infra.outputs.outputs-json }}' | jq -r '.private_subnet_ids.value | join(",")')
echo "Subnets: $SUBNET_IDS"

Complete workflow that waits for infrastructure, deploys an app, and runs tests:

name: Preview Deploy & Test
on:
pull_request:
jobs:
deploy:
runs-on: ubuntu-latest
outputs:
api_url: ${{ steps.infra.outputs.api_url }}
steps:
- uses: actions/checkout@v4
- uses: yaffle-dot-dev/outputs-action@v1
id: infra
with:
workspace: infra
wait: true
wait-timeout: 900
- uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: arn:aws:iam::123456789:role/deploy
aws-region: us-east-1
- name: Deploy to ECS
run: |
aws ecs update-service \
--cluster ${{ steps.infra.outputs.cluster_arn }} \
--service ${{ steps.infra.outputs.service_name }} \
--force-new-deployment
aws ecs wait services-stable \
--cluster ${{ steps.infra.outputs.cluster_arn }} \
--services ${{ steps.infra.outputs.service_name }}
test:
needs: deploy
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Run E2E tests
env:
API_URL: ${{ needs.deploy.outputs.api_url }}
run: npm run test:e2e