Terraform remote backend helps users store Terraform state and run Terraform commands remotely using Terraform Cloud.
Note: CDK for Terraform only supports Terraform Cloud workspaces that have "Execution Mode" set to "local". The project doesn't support remote operations yet. To change the execution mode for a Terraform Cloud workspace, visit the "General" setting tab in the workspace and find "Execution Mode" section, select "local" and save the settings.
A Terraform JSON configuration for a remote backend can be defined in two ways:
-
Use a TerraformBackend subclass to define a backend. It will synthesize to a JSON configuration in the autogenerated
cdk.tf.json
file.const stack = new MyStack(app, "hello-terraform"); new RemoteBackend(stack, { hostname: "app.terraform.io", organization: "company", workspaces: { name: "my-app-prod", }, });
-
Create a JSON file such as
remote.tf.json
incdktf.out
directory.
The cdktf.out
directory contains our synthesized code that can be generated by running cdktf synth
in
any CDK for Terraform project.
cd cdktf.out
vim remote.tf.json
{
"terraform": {
"backend": {
"remote": {
"hostname": "app.terraform.io",
"organization": "company",
"workspaces": {
"name": "my-app-prod"
}
}
}
}
}
The output directory is as follows.
tree .
.
├── cdk.tf.json
└── remote.tf.json
Running terraform init
will initialize Terraform remote backend.
$ terraform init
Users can then run terraform plan
and terraform apply
to manage their infrastructure.
When migrating a project that is using local storage (terraform.tfstate
file) to store the state of the project to remote state store like Terraform Cloud, users need to define move the Terraform state file to the CDK for Terraform output directory.
Here is a project called hello-terraform
that is using local storage to store the Terraform state.
cd hello-terraform
Add remote state backend using TerraformBackend.
vim main.ts
const stack = new MyStack(app, "hello-terraform");
new RemoteBackend(stack, {
hostname: "app.terraform.io",
organization: "company",
workspaces: {
name: "my-app-prod",
},
});
Synthesize application
cdktf synth
Move Terraform state file into the output directory.
mv terraform.tfstate cdktf.out
Run Terraform init
cd cdktf.out
terraform init
Initializing the backend...
Do you want to copy existing state to the new backend?
Pre-existing state was found while migrating the previous "local" backend to the
newly configured "remote" backend. No existing state was found in the newly
configured "remote" backend. Do you want to copy this state to the new "remote"
backend? Enter "yes" to copy and "no" to start with an empty state.
Enter a value: yes
Successfully configured the backend "remote"! Terraform will automatically
use this backend unless the backend configuration changes.
Initializing provider plugins...
.....
Terraform has been successfully initialized!
You may now begin working with Terraform. Try running "terraform plan" to see
any changes that are required for your infrastructure. All Terraform commands
should now work.
If you ever set or change modules or backend configuration for Terraform,
rerun this command to reinitialize your working directory. If you forget, other
commands will detect it and remind you to do so if necessary.
Validate state migration by running the cdktf diff
command in the root hello-terraform
cd ..
cdktf diff
There are no changes to the stack.
Stack: hello-terraform
Diff: 0 to create, 0 to update, 0 to delete.
- local
new LocalBackend(stack, {...});
- artifactory
new ArtifactoryBackend(stack, {...});
- azurerm
new AzurermBackend(stack, {...});
- consul
new ConsulBackend(stack, {...});
- cos
new CosBackend(stack, {...});
- etcd
new EtcdBackend(stack, {...});
- etcdv3
new EtcdV3Backend(stack, {...});
- gcs
new GcsBackend(stack, {...});
- http
new HttpBackend(stack, {...});
- manta
new MantaBackend(stack, {...});
- oss
new OssBackend(stack, {...});
- pg
new PgBackend(stack, {...});
- s3
new S3Backend(stack, {...});
- swift
new SwiftBackend(stack, {...});
Unsupported backends can be configured via a Stack Escape Hatch.
stack.addOverride("terraform.backend", {
atlas: {
name: "example_corp/networking-prod",
address: "https://app.terraform.io",
},
});
Escaped hatches can also be used on backend constructs.
const backend = new RemoteBackend(stack, {...});
backend.addOverride('organization', 'my_other_company');