Terraform
Remote Backends
Terraform stores state about managed infrastructure to map real-world resources to the configuration, keep track of metadata, and improve performance. Terraform stores this state in a local file by default, but you can also use a Terraform remote backend to store state remotely.
By default, cdktf init
will configure a HCP Terraform workspace and a corresponding remote backend to store state for the new project. If you run cdktf init --local
to configure your new project to use a local backend to store state, you can still migrate the state to a remote backend later.
You can configure your CDK for Terraform (CDKTF) remote backend to be HCP Terraform, another Terraform supported backend, or a custom location.
When to Use Remote Backends
Consider using a remote backend when multiple individuals or teams need access to your infrastructure state data.
Remote state makes it easier for teams to work together because all members have access to the latest state data in the remote store. It also allows you to share output values with other configurations, allowing groups to share infrastructure resources. For example, a core infrastructure team can handle building the core machines and then expose some information that other teams can use for their own infrastructure.
Define Remote Backends
You can define a JSON configuration for a remote backend
with a TerraformBackend
subclass or a JSON configuration file.
The following example uses the TerraformBackend
subclass CloudBackend
.
import { Construct } from "constructs";
import {
CloudBackend,
TerraformStack,
TerraformOutput,
NamedCloudWorkspace,
App,
} from "cdktf";
export class CloudBackendStack extends TerraformStack {
constructor(scope: Construct, id: string) {
super(scope, id);
new CloudBackend(this, {
hostname: "app.terraform.io",
organization: "company",
workspaces: new NamedCloudWorkspace("my-app-prod"),
});
new TerraformOutput(this, "dns-server", {
value: "hello-world",
});
}
}
When you call cdktf synth
, CDKTF generates a JSON file called remote.tf.json
in the cdktf.out
stack sub-directory containing the synthesized CDKTF code. For example, CDKTF creates the output for a stack called hello-terraform
in cdktf.out/stacks/hello-terraform
.
The following example shows the stack output directory.
tree .
.
├── cdk.tf.json
└── remote.tf.json
The following example shows the generated remote.tf.json
file.
{
"terraform": {
"backend": {
"remote": {
"hostname": "app.terraform.io",
"organization": "company",
"workspaces": {
"name": "my-app-prod"
}
}
}
}
}
Initialize Remote Backends
All cdktf
operations perform an automatic terraform init
, but you can also initialize manually.
To manually initialize a remote backend, go to the corresponding stack output directory in the cdktf.out
folder and run terraform init
.
$ cd cdkf.out/stacks/hello-terraform
$ terraform init
Migrate Local State Storage to Remote
After you define your remote backend, you can migrate existing local state files to the designated remote location. This requires moving Terraform state files to the CDKTF output directory.
Consider an example project called hello-terraform
that is using local storage to store the Terraform state. To migrate the local stage files to the remote backend:
Navigate into the main project directory.
Use
CloudBackend
to add a new remote backend.
class LocalBackendStack extends TerraformStack {
constructor(scope: Construct, id: string) {
super(scope, id);
new TerraformOutput(this, "dns-server", {
value: "local",
});
}
}
const app = new App();
const stack = new LocalBackendStack(app, "local-to-cloud-backend");
new CloudBackend(stack, {
hostname: "app.terraform.io",
organization: "company",
workspaces: new NamedCloudWorkspace("my-app-prod"),
});
Run
cdktf diff <stack name> --migrate-state
to migrate the state into HCP Terraform or Terraform Enterprise.Initializing Terraform Cloud... Migrating from backend "local" to Terraform Cloud. Do you wish to proceed? As part of migrating to Terraform Cloud, Terraform can optionally copy your current workspace state to the configured Terraform Cloud workspace. Answer "yes" to copy the latest state snapshot to the configured Terraform Cloud workspace. Answer "no" to ignore the existing state and just activate the configured Terraform Cloud workspace with its existing state, if any. Should Terraform migrate your existing state? Enter a value: yes Initializing provider plugins... - Reusing previous version of hashicorp/random from the dependency lock file - Using previously-installed hashicorp/random v3.4.3 Terraform Cloud has been successfully initialized!
Supported Backends
In addition to HCP Terraform, Terraform and CDKTF support the following backends.
- local
new LocalBackend(stack, {...});
- azurerm
new AzurermBackend(stack, {...});
- consul
new ConsulBackend(stack, {...});
- cos
new CosBackend(stack, {...});
- gcs
new GcsBackend(stack, {...});
- http
new HttpBackend(stack, {...});
- oss
new OssBackend(stack, {...});
- pg
new PgBackend(stack, {...});
- s3
new S3Backend(stack, {...});
Note: CDK for Terraform v0.14 deprecated the artifactory, etcd, etcdv3, manta, and swift backends, and removed them in v0.20. Terraform removed these backends in v1.3. For migration paths from these removed backends, refer to Upgrading to Terraform v1.3.
Escape Hatches
Escape hatches can add to or override existing resources, and you can use them for backends or backend constructs that CDKTF does not natively support. Escape hatch methods have an Override
suffix (e.g., addOverride
).
The following example uses an escape hatch to add an unsupported remote backend on a Stack
object.
stack.addOverride("terraform.backend", {
atlas: {
name: "example_corp/networking-prod",
address: "https://app.terraform.io",
},
});