Skip to main content
You can configure your Continuous Integration/Continuous Deployment (CI/CD) environment to automatically deploy your CDKTN applications. This page explains different types of deployment patterns to help you choose the methods that are most appropriate for your use case.

Deployment Methods

You can provision your infrastructure using either CDKTN CLI commands (e.g., cdktn deploy) or by synthesizing your application into a Terraform configuration file and using Terraform directly. Both approaches allow you to use HCP Terraform and integrate with a CI/CD pipeline.

Run CDKTN CLI Commands

We recommend using CDKTN CLI commands in the following use cases:
  • Your application performs additional tasks For example, your application may build a Docker image or start a build pipeline locally through synchronous APIs. You might also be using the null provider to execute these actions when a resource is created (e.g., after the Docker registry has been created). Running cdktn deploy triggers all of these actions at runtime in addition to using Terraform to provision your infrastructure.
  • Your application contains stacks with complex dependencies. Each stack in a CDKTN application is like a separate Terraform working directory. Terraform respects complex dependencies within the same configuration, but it is not designed to manage complex dependencies between multiple working directories. For example, if you define a stack A that depends on data from stack B and stack C, Terraform runs will fail. This is because Terraform will not understand that it must wait to build stack A until both stack B and stack C are completed.

Run cdktn synth and Use Terraform Directly

We recommend synthesizing your CDKTN application and using Terraform directly when you need to integrate into existing Terraform workflows. Your organization may already use HCP Terraform or have integrated Terraform into CI pipelines. In these cases, you may want to run cdktn synth and set the output folder to a particular directory that you can reference in your existing workflows.

Using HCP Terraform

HCP Terraform lets you review the current state of your infrastructure and run progress in the HCP Terraform UI. You can also use HCP Terraform as the source of secrets. Refer to Set Up CDKTN With HCP Terraform for details. Refer to Example Workflows for several examples of connecting your CDKTN application to HCP Terraform and using HCP Terraform in a Continuous Integration pipeline.

Managing Secrets and Sensitive Data

You should read secrets with Terraform Variables so that they do not appear in your synthesized CDKTN code.

Example Workflows

The following examples demonstrate common deployment workflows for your CDKTN application.

Deploy with Terraform and HCP Terraform

Connect your synthesized CDKTN configuration to a HCP Terraform workspace with the following steps:
  1. Add a pre-commit step in your CDKTN application that runs cdktn synth. This creates Terraform configuration files in the cdktf.out/stacks/<stack-name> directory.
  2. Configure the VCS integration for a HCP Terraform workspace to point to the directory with the synthesized configuration files. To deploy multiple independent stacks, configure one HCP Terraform workspace to point to the output directory for each stack.
Refer to Automatic Run Triggering in the HCP Terraform documentation for details about how to trigger Terraform runs from merges and commits.

Terraform CDK GitHub Action

You can use the Terraform CDK GitHub Action if you are using GitHub Actions and you want a default review / deployment workflow. The Terraform CDK GitHub Action runs the CDKTN CLI under the hood, it comments Terraform plans on your pull requests and provides a default review workflow. If you need more customization, refer to GitHub Actions CI and HCP Terraform.

GitHub Actions CI and HCP Terraform

Set the TERRAFORM_CLOUD_TOKEN environment variable to the HCP Terraform API token. This allows the CDKTN stacks CloudBackend to connect to HCP Terraform. You must create a job like this for every stack so that you can pass the stack name into cdktn diff <stack name>. None of the stacks can depend on each other because Terraform cannot reason about which stacks must be launched first to respect these dependencies. The following example shows a GitHub Actions configuration where the CDKTN application is deployed from the main branch and uses HCP Terraform. You could store this file in .github/workflows/cdktn-deploy.yml.
name: CDKTN Deployment

on:
  push:
    branches: [main]

jobs:
  deploy:
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v3
      - name: Use Node.js 18.x
        uses: actions/setup-node@v3
        with:
          node-version: 18.x
          cache: "npm"
      - name: Install CDKTN CLI
        run: npm install -g cdktn-cli
      - name: Install Terraform
        uses: hashicorp/setup-terraform@v2
        with:
          terraform_version: 1.1.7
      - name: Install dependencies
        run: npm ci
      # If you use providers or modules that are not pre-built, you can install them here
      - name: Generate bindings for providers and modules
        run: cdktn get
      - name: Run Tests
        run: npm test
      - name: Deploy
        run: cdktn deploy --auto-approve '*' # Deploys all stacks
        env:
          TERRAFORM_CLOUD_TOKEN: ${{ secrets.TF_API_TOKEN }}
To get the plan output posted as a comment on your pull request, add the following to your .github/workflows/cdktn-diff.yml file:
name: CDKTN Diff

on: [pull_request]

jobs:
  diff:
    name: "Terraform CDK Diff"
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v2

      - name: Setup Terraform
        uses: hashicorp/setup-terraform@v1
        with:
          terraform_version: 1.1.7
          cli_config_credentials_token: ${{ secrets.TF_CLOUD_TOKEN }}

      - uses: actions/setup-node@v1
        with:
          node-version: "14"

      - run: yarn install

      # CDKTN runs the plan here, so you need to fill in the name of your stack.
      - name: plan
        run: cdktn plan <stack name>
        env:
          TERRAFORM_CLOUD_TOKEN: ${{ secrets.TF_API_TOKEN }}
        continue-on-error: true # We want to see the plan output even if the plan fails

      # Replace this step with any workflow you like, e.g. posting a message in a slack channel.
      - uses: actions/github-script@0.9.0
        if: github.event_name == 'pull_request'
        env:
          PLAN: "terraform\n${{ steps.plan.outputs.stdout }}" # CDKTN gets the output from the last step
        with:
          github-token: ${{ secrets.GH_COMMENT_TOKEN }} # Create a secret with a GitHub token that can comment on PRs
          script: |
            const output = `#### Terraform Plan 📖\`${{ steps.plan.outcome }}\`
            <details><summary>Show Plan</summary>
            \`\`\`${process.env.PLAN}\`\`\`
            </details>
            *Pusher: @${{ github.actor }}, Action: \`${{ github.event_name }}\`, Working Directory: \`${{ env.tf_actions_working_dir }}\`, Workflow: \`${{ github.workflow }}\`*`;
            github.issues.createComment({
              issue_number: context.issue.number,
              owner: context.repo.owner,
              repo: context.repo.repo,
              body: output
            })

Running the CDKTN CLI on a General Purpose CI

If you have a general purpose CI like GitHub Actions or CircleCI configured, use the cdktn deploy --auto-approve <your stacks> command to trigger a deployment. This deploys your stacks in the right order and in parallel. To set up this workflow, you must install the following software:
  • Node in version 14.0+
  • The cdktn-cli CLI
  • Terraform v1.0+
  • Any other languages you use for your CDKTN application
Auto-approved deployments skip the option to review planned changes to your infrastructure before Terraform applies them. Minimize risk of unpredictable infrastructure changes and configuration drift by making sure that no one can change your infrastructure outside of your automated build pipeline. Refer to Non-Interactive Workflows for details.

Contribute Additional Examples

To share another solution, please open a GitHub issue or submit a pull request for this documentation page.