HashiConf Global Join us for HashiConf Global October 4-6 in Los Angeles & online. Register Now
  • Overview
    • Enforce Policy as Code
    • Infrastructure as Code
    • Inject Secrets into Terraform
    • Integrate with Existing Workflows
    • Manage Kubernetes
    • Manage Virtual Machine Images
    • Multi-Cloud Deployment
    • Network Infrastructure Automation
    • Terraform CLI
    • Terraform Cloud
    • Terraform Enterprise
  • Registry
  • Tutorials
    • About the Docs
    • Intro to Terraform
    • Configuration Language
    • Terraform CLI
    • Terraform Cloud
    • Terraform Enterprise
    • Provider Use
    • Plugin Development
    • Registry Publishing
    • Integration Program
    • Terraform Tools
    • CDK for Terraform
    • Glossary
  • Community
GitHub
Download
Try Terraform Cloud
    • v0.12.x (latest)
    • v0.11.x
    • v0.10.x
    • v0.9.x
    • v0.8.x

    CDK for Terraform

  • Overview
  • Get Started
    • Architecture
    • HCL Interoperability
    • Constructs
    • Providers
    • Resources
    • Modules
    • Data Sources
    • Variables and Outputs
    • Functions
    • Iterators
    • Remote Backends
    • Aspects
    • Assets
    • Tokens
    • Stacks
  • Examples and Guides
    • Project Setup
    • Configuration File
    • Best Practices
    • Environment Variables
    • Terraform Cloud
    • Deployment Patterns
    • Remote Templates
    • AWS Adapter [preview]
    • Unit Tests
    • Debugging
    • CLI Configuration
    • Commands
    • Overview
    • Typescript
    • Python
    • Java
    • C#
    • Go
    • Providers
    • Overview
    • Upgrading to Version 0.12
    • Upgrading to Version 0.11
    • Upgrading to Version 0.10
    • Upgrading to Version 0.9
    • Upgrading to Version 0.7
    • Upgrading to Version 0.6
  • Community
  • Telemetry
  • Other Docs

  • Intro to Terraform
  • Configuration Language
  • Terraform CLI
  • Terraform Cloud
  • Terraform Enterprise
  • Provider Use
  • Plugin Development
  • Registry Publishing
  • Integration Program
  • Terraform Tools
  • CDK for Terraform
  • Glossary
Type '/' to Search

»Providers

A provider is a Terraform plugin that allows users to manage an external API. Provider plugins like the AWS provider or the cloud-init provider act as a translation layer that allows Terraform to communicate with many different cloud providers, databases, and services.

diagram: How Terraform uses plugins

Terraform uses providers to provision resources, which describe one or more infrastructure objects like virtual networks and compute instances. Each provider on the Terraform Registry has documentation detailing available resources and their configuration options.

In your CDK for Terraform (CDKTF) application, you will use your preferred programming language to define the resources you want Terraform to manage on one or more providers. This page explains how to install and use providers in your CDKTF application. Refer to Resources for details about defining infrastructure resources and changing resource behavior.

You can install pre-built providers, import providers from the Terraform Registry, or reference local providers to define resources for your application. CDKTF generates the required code bindings from the providers you define in cdktf.json. This allows you to define resources for that provider in your preferred programming language.

You can also use the provider add command to add providers to your CDKTF application. It will automatically try to install a pre-built provider if available and fall back to generating bindings locally if none was found.

»Import Providers

CDK for Terraform lets you import Terraform providers to your project.

This TypeScript example project has a main.ts file that defines AWS resources.

import { Construct } from "constructs";
import { App, TerraformStack } from "cdktf";
import { AwsProvider, EC2 } from "./.gen/providers/aws";

class MyStack extends TerraformStack {
  constructor(scope: Construct, id: string) {
    super(scope, id);

    new AwsProvider(this, "aws", {
      region: "us-east-1",
    });

    new EC2.Instance(this, "Hello", {
      ami: "ami-2757f631",
      instanceType: "t2.micro",
    });
  }
}

const app = new App();
new MyStack(app, "hello-terraform");
app.synth();
import { Construct } from "constructs";
import { App, TerraformStack } from "cdktf";
import { AwsProvider, EC2 } from "./.gen/providers/aws";

class MyStack extends TerraformStack {
  constructor(scope: Construct, id: string) {
    super(scope, id);

    new AwsProvider(this, "aws", {
      region: "us-east-1",
    });

    new EC2.Instance(this, "Hello", {
      ami: "ami-2757f631",
      instanceType: "t2.micro",
    });
  }
}

const app = new App();
new MyStack(app, "hello-terraform");
app.synth();

»Add Provider to cdktf.json

To use a new provider, first add it to the "terraformProviders" array in the cdktf.json file.

The example below adds the DNS Simple provider:

{
  "language": "typescript",
  "app": "npm run --silent compile && node main.js",
  "terraformProviders": ["aws@~> 2.0", "dnsimple/dnsimple"]
}
{
  "language": "typescript",
  "app": "npm run --silent compile && node main.js",
  "terraformProviders": ["aws@~> 2.0", "dnsimple/dnsimple"]
}

»Generate Classes

Go to the working directory and run cdktf get to create the appropriate TypeScript classes for the provider automatically.

cdktf get
⠋ downloading and generating providers...
cdktf get
⠋ downloading and generating providers...
Generated typescript constructs in the output directory: .gen
Generated typescript constructs in the output directory: .gen

»Import Classes

Import and use the generated classes in your application. The TypeScript example below imports the DnsimpleProvider and Record resources from ./.gen/providers/dnsimple and defines them.

import { Construct } from "constructs";
import { App, TerraformStack, Token } from "cdktf";
import { AwsProvider, EC2 } from "./.gen/providers/aws";
import { DnsimpleProvider, Record } from "./.gen/providers/dnsimple";

class MyStack extends TerraformStack {
  constructor(scope: Construct, id: string) {
    super(scope, id);

    new AwsProvider(this, "aws", {
      region: "us-east-1",
    });

    const instance = new EC2.Instance(this, "Hello", {
      ami: "ami-2757f631",
      instanceType: "t2.micro",
    });

    new DnsimpleProvider(this, "dnsimple", {
      token: Token.asString(process.env.DNSIMPLE_TOKEN),
      account: Token.asString(process.env.DNSIMPLE_ACCOUNT),
    });

    new Record(this, "web-www", {
      domain: "example.com",
      name: "web",
      value: instance.publicIp,
      type: "A",
    });
  }
}

const app = new App();
new MyStack(app, "hello-terraform");
app.synth();
import { Construct } from "constructs";
import { App, TerraformStack, Token } from "cdktf";
import { AwsProvider, EC2 } from "./.gen/providers/aws";
import { DnsimpleProvider, Record } from "./.gen/providers/dnsimple";

class MyStack extends TerraformStack {
  constructor(scope: Construct, id: string) {
    super(scope, id);

    new AwsProvider(this, "aws", {
      region: "us-east-1",
    });

    const instance = new EC2.Instance(this, "Hello", {
      ami: "ami-2757f631",
      instanceType: "t2.micro",
    });

    new DnsimpleProvider(this, "dnsimple", {
      token: Token.asString(process.env.DNSIMPLE_TOKEN),
      account: Token.asString(process.env.DNSIMPLE_ACCOUNT),
    });

    new Record(this, "web-www", {
      domain: "example.com",
      name: "web",
      value: instance.publicIp,
      type: "A",
    });
  }
}

const app = new App();
new MyStack(app, "hello-terraform");
app.synth();

Use the synth command to convert your code into a JSON Terraform configuration file.

cdktf synth --json
cdktf synth --json
{
  "//": {
    "metadata": {
      "version": "0.0.11-pre.8757404fa25b6e405f1a51eac11b96943ccb372e",
      "stackName": "vpc-example"
    }
  },
  "terraform": {
    "required_providers": {
      "aws": "~> 2.0",
      "dnsimple": "undefined"
    }
  },
  "provider": {
    "aws": [
      {
        "region": "us-east-1"
      }
    ],
    "dnsimple": [
      {
        "account": "hello@example.com",
        "token": "xxxxxxxxxx"
      }
    ]
  },
  "resource": {
    "aws_instance": {
      "vpcexample_Hello_279554CB": {
        "ami": "ami-2757f631",
        "instance_type": "t2.micro",
        "//": {
          "metadata": {
            "path": "vpc-example/Hello",
            "uniqueId": "vpcexample_Hello_279554CB",
            "stackTrace": [
              .....
            ]
          }
        }
      }
    },
    "dnsimple_record": {
      "vpcexample_webwww_477C7150": {
        "domain": "example.com",
        "name": "web",
        "type": "A",
        "value": "${aws_instance.vpcexample_Hello_279554CB.public_ip}",
        "//": {
          "metadata": {
            "path": "vpc-example/web-www",
            "uniqueId": "vpcexample_webwww_477C7150",
            "stackTrace": [
              .....
            ]
          }
        }
      }
    }
  }
}

{
  "//": {
    "metadata": {
      "version": "0.0.11-pre.8757404fa25b6e405f1a51eac11b96943ccb372e",
      "stackName": "vpc-example"
    }
  },
  "terraform": {
    "required_providers": {
      "aws": "~> 2.0",
      "dnsimple": "undefined"
    }
  },
  "provider": {
    "aws": [
      {
        "region": "us-east-1"
      }
    ],
    "dnsimple": [
      {
        "account": "hello@example.com",
        "token": "xxxxxxxxxx"
      }
    ]
  },
  "resource": {
    "aws_instance": {
      "vpcexample_Hello_279554CB": {
        "ami": "ami-2757f631",
        "instance_type": "t2.micro",
        "//": {
          "metadata": {
            "path": "vpc-example/Hello",
            "uniqueId": "vpcexample_Hello_279554CB",
            "stackTrace": [
              .....
            ]
          }
        }
      }
    },
    "dnsimple_record": {
      "vpcexample_webwww_477C7150": {
        "domain": "example.com",
        "name": "web",
        "type": "A",
        "value": "${aws_instance.vpcexample_Hello_279554CB.public_ip}",
        "//": {
          "metadata": {
            "path": "vpc-example/web-www",
            "uniqueId": "vpcexample_webwww_477C7150",
            "stackTrace": [
              .....
            ]
          }
        }
      }
    }
  }
}

»Install Pre-built Providers

It can take several minutes to generate the code bindings for providers with very large schemas, so we offer several popular providers as pre-built packages. Pre-built providers are a completely optional performance optimization, and you may prefer to generate the code bindings for these providers yourself. For example, you may want to use a different version of that provider than the one in the pre-built package. The Terraform CDK Providers page has a complete list, but available pre-built providers include:

  • AWS Provider
  • Google Provider
  • Azure Provider
  • Kubernetes Provider
  • Docker Provider
  • Github Provider
  • Null Provider

These packages are regularly published to NPM / PyPi, and you can treat them as you would any other dependency. The example below shows how to install the AWS provider in TypeScript / Node.

npm install @cdktf/provider-aws
npm install @cdktf/provider-aws

When you choose to install a pre-built provider via npm install, you should not define that provider again in your cdktf.json file. If you receive errors while running cdktf synth because of duplicate providers, remove the duplicates from your cdktf.json file, delete tsbuildinfo.json, and try running cdktf synth again.

»Provider Caching

Caching prevents CDK for Terraform from re-downloading providers between each CLI command. It is also useful when you need to remove the cdktf.out folder and re-synthesize your configuration. Finally, caching is necessary when you use multiple stacks within one application.

»Set the Caching Directory

Refer to the Terraform documentation about how to configure your plugin cache. Otherwise, CDKTF automatically sets the TF_PLUGIN_CACHE_DIR environment variable to $HOME/.terraform.d/plugin-cache when you use cdktf cli commands.

To disable this behavior, set CDKTF_DISABLE_PLUGIN_CACHE_ENV to a non null value, like CDKTF_DISABLE_PLUGIN_CACHE_ENV=1. You may want to do this when a different cache directory is configured via a .terraformrc configuration file.

»Use a Local Provider

Terraform needs to know the location of local providers to enable CDKTF to generate the appropriate type bindings. You can configure this in two ways:

  • Implied Local Mirrors
  • Development Overrides

Once configured properly, you can reference these providers in the cdktf.json file the same way that you reference providers from the Terraform Registry. Refer to the project configuration documentation for more details about the cdktf.json specification.

github logoEdit this page
  • Overview
  • Docs
  • Extend
  • Privacy
  • Security
  • Press Kit
  • Consent Manager