Hands-on: Try the Build AWS Infrastructure with Go tutorial on HashiCorp Learn.
- Terraform >= v0.12
- Node.js >= v12.16
- Go >= 1.16 (CDK for Terraform uses go modules and JSII requires Go 1.16)
Install with Homebrew:
$ brew install cdktf
Or install with npm
(comes with Node.js):
npm install -g cdktf-cli
Learn more how to use the cdktf command-line interface here.
mkdir hello-terraform
cd hello-terraform
Initialize a new CDK for Terraform project
cdktf init --template="go" --local
This will initialize a brand new CDK for Terraform project in Go using an interactive command.
Note: By supplying '--local' option you have chosen local storage mode for storing the state of your stack.
This means that your Terraform state file will be stored locally on disk in a file 'terraform.tfstate' in the root of your project.
We will now set up the project. Please enter the details for your project.
If you want to exit, press ^C.
Project Name: (default: 'hello-terraform')
Project Description: (default: 'A simple getting started project for cdktf.')
Also, this command installs the cdktf
library so that it can be used in the project.
You can now open up the main.go
file to view your application code.
vim main.go
package main
import (
"github.com/aws/constructs-go/constructs/v3"
"github.com/hashicorp/terraform-cdk-go/cdktf"
)
func NewMyStack(scope constructs.Construct, id string) cdktf.TerraformStack {
stack := cdktf.NewTerraformStack(scope, &id)
// The code that defines your stack goes here
return stack
}
func main() {
app := cdktf.NewApp(nil)
NewMyStack(app, "hello-terraform")
app.Synth()
}
Refer to the examples directory for additional examples.
Let's take a simple Go application that uses the CDK for Terraform package.
package main
import (
"cdk.tf/go/stack/generated/kreuzwerker/docker"
"github.com/aws/constructs-go/constructs/v3"
"github.com/aws/jsii-runtime-go"
"github.com/hashicorp/terraform-cdk-go/cdktf"
)
func NewMyStack(scope constructs.Construct, id string) cdktf.TerraformStack {
stack := cdktf.NewTerraformStack(scope, &id)
docker.NewDockerProvider(stack, jsii.String("provider"), &docker.DockerProviderConfig{})
dockerImage := docker.NewImage(stack, jsii.String("nginxImage"), &docker.ImageConfig{
Name: jsii.String("nginx:latest"),
KeepLocally: jsii.Bool(false),
})
docker.NewContainer(stack, jsii.String("nginxContainer"), &docker.ContainerConfig{
Image: dockerImage.Latest(),
Name: jsii.String("tutorial"),
Ports: &[]*docker.ContainerPorts{{
Internal: jsii.Number(80), External: jsii.Number(8000),
}},
})
return stack
}
func main() {
app := cdktf.NewApp(nil)
NewMyStack(app, "hello-terraform")
app.Synth()
}
JSII is using pointers
to be able to represent an unset optional value as nil
. Hence the helper functions jsii.String()
and jsii.Number()
are used
in the example to get pointers to the corresponding types which can are passed as inputs.
As you can see in the example above we want to deploy AWS resources, therefore we need to use the Terraform AWS Provider. Every Terraform Provider and Terraform Module can be used with the workflow described here.
You specify it in your local cdktf.json
file, like this:
{
"language": "go",
"app": "go run main.go",
"terraformProviders": [
// Terraform Providers with version constraint go here
"aws@~> 3.45"
],
"terraformModules": [
// Terraform Modules with version constraint go here
],
"context": {
"excludeStackIdFromLogicalIds": "true"
}
}
Next you need to run cdktf get
which generates provider-specific bindings.
To save some time you can also use pre-built provider, please visit the "Using Providers and Modules"-Guide for more on that topic.
For the above example to work, we need to add the kreuzwerker/docker
Terraform provider to the cdktf.json
.
{
...
"terraformProviders": [
"kreuzwerker/docker@~> 2.11"
],
...
}
After adding the provider and saving the file, we can run cdktf get
to generate the bindings for the providers. By default the generated Go code will be output to the generated
subdirectory.
The generated provider bindings depend on jsii-runtime-go
. To automatically add that depedency to your code, you can run go mod tidy
.
When you are ready you can run the synthesize
command to generate Terraform JSON configuration for the application.
cdktf synth
Generated Terraform code for the stacks: hello-terraform
This command will generate a directory called cdktf.out
. This directory contains the Terraform JSON configuration for
the application.
cd cdktf.out
Terraform AWS provider and instance expressed as Terraform JSON configuration.
cat stacks/hello-terraform/cdk.json # shortened for brevity
{
"terraform": {
"required_providers": {
"docker": {
"version": "~> 2.11",
"source": "kreuzwerker/docker"
}
}
},
"provider": {
"docker": [
{}
]
},
"resource": {
"docker_image": {
"nginxImage": {
"keep_locally": false,
"name": "nginx:latest"
}
},
"docker_container": {
"nginxContainer": {
"image": "${docker_image.nginxImage.latest}",
"name": "tutorial",
"ports": [
{
"external": 8000,
"internal": 80
}
]
}
}
}
}
Note: You can generate the Terraform JSON configuration while synthesizing the code by running
cdktf synth --json
.
Note: You can use Terraform commands like
terraform init
,terraform plan
, andterraform apply
with the generated Terraform JSON configuration (learn more here) or optionally continue to use the CDK for Terraform CLI for a first-class experience.
You can now deploy your CDK for Terraform application using the cdktf deploy
command.
cdktf deploy
This command will ask for confirmation on a generated diff and then deploy the application.
Stack: hello-terraform
Resources
+ DOCKER_CONTAINER nginxContainer docker_container.nginxContainer
+ DOCKER_IMAGE nginxImage docker_image.nginxImage
Diff: 2 to create, 0 to update, 0 to delete.
Do you want to perform these actions?
CDK for Terraform will perform the actions described above.
Only 'yes' will be accepted to approve.
Enter a value:
Deployed application
Deploying Stack: hello-terraform
Resources
✔ DOCKER_CONTAINER nginxContainer docker_container.nginxContainer
✔ DOCKER_IMAGE nginxImage docker_image.nginxImage
Summary: 2 created, 0 updated, 0 destroyed.
The cdktf deploy
command runs a terraform apply
in the background. If you are using local storage mode then it creates a terraform.hello-terraform.tfstate
file in the root of the project.
You can destroy the application by running cdktf destroy
.
cdktf destroy
This command will ask for confirmation on a generated diff and then destroy the application if the user confirms that they want to continue with the destroy operation.
Stack: hello-terraform
Resources
- DOCKER_CONTAINER nginxContainer docker_container.nginxContainer
- DOCKER_IMAGE nginxImage docker_image.nginxImage
Diff: 0 to create, 0 to update, 2 to delete.
Do you want to perform these actions?
CDK for Terraform will perform the actions described above.
Only 'yes' will be accepted to approve.
Enter a value:
Destroyed application
Destroying Stack: hello-terraform
Resources
✔ DOCKER_CONTAINER nginxContainer docker_container.nginxContainer
✔ DOCKER_IMAGE nginxImage docker_image.nginxImage
Summary: 2 destroyed.