CDK for Terraform
Hashicorp recently announced cdktf
Cloud Development Kit for Terraform which currently supports Python3
and Typescript
.
With cdktf
we can write Terraform code in Python3
or Typescript
instead of HCL
which is the default language for Terraform.
Well, I thought of giving it a try and check out how it works out with Python3
.
Install cdktf
To install the most recent stable release of cdktf, use npm.
npm install --global cdktf-cli
To get up to date with the cutting edge development version
npm install --global cdktf-cli@next
Once the installation is done you can check the cdktf installation via cdktf
Commands:
cdktf deploy [OPTIONS] Deploy the given stack
cdktf destroy [OPTIONS] Destroy the given stack
cdktf diff [OPTIONS] Perform a diff (terraform plan) for the given stack
cdktf get [OPTIONS] Generate CDK Constructs for Terraform providers and modules.
cdktf init [OPTIONS] Create a new cdktf project from a template.
cdktf login Retrieves an API token to connect to Terraform Cloud.
cdktf synth [OPTIONS] Synthesizes Terraform code for the given app in a directory. [aliases: synthesize]
Options:
--version Show version number [boolean]
--disable-logging Dont write log files. Supported using the env CDKTF_DISABLE_LOGGING. [boolean] [default: true]
--log-level Which log level should be written. Only supported via setting the env CDKTF_LOG_LEVEL [string]
-h, --help Show help [boolean]
Options can be specified via environment variables with the "CDKTF_" prefix (e.g. "CDKTF_OUTPUT")
Okay now, let's do some real work we will create a project where we will deploy Nginx on top of Docker using cdktf
and Python3. For the Typescript example please check terraform-cdk.
Create a directory by any name in our case we will use below the python-docker
mkdir python-docker && cd $_
Initialize the project with the init command. We will use the --local
flag so that the infrastructure state will be stored locally.
cdktf init --template=python --local
Make sure you pass python
and not python3
else you will get below error
Invalid values:
Argument: template, Given: "python3", Choices: "python", "typescript"
cdktf
will generate the template for us, in our case, we will be using docker to get Nginx running so make sure to change the provider in cdktf.json
{
"language": "python",
"app": "pipenv run ./main.py",
"terraformProviders": ["docker"],
"codeMakerOutput": "imports"
}
Run the get command to download the dependencies for using Docker with Python.
cdktf get
Now add your code in main.py
file for building Docker
First import the Docker provider, this means the imports is a local directory created by the above command
from imports.docker import Image, Container
and later add below code
docker_image = Image(self, 'nginx-latest', name='nginx:latest', keep_locally=False)
Container(self, 'nginx-cdktf', name='nginx-python-cdktf',
image=docker_image.name, ports=[
{
'internal': 80,
'external': 8000
}], privileged=False)
Add the dependencies in Pipenv
file in our case
[packages]
constructs="3.0.4"
cdktf="0.0.12"
Pipenv will throw an error if you don't define the version for the packages
Run pipenv
to get all the dependencies to install the pipenv check the official website pipenv
pipenv install
Now compile and generate Terraform configuration
cdktf synth
The above command will create a folder called cdktf.out that contains all Terraform JSON configuration that was generated.
We can run the regular Terraform commands
cd cdktf.out
terraform init
terraform plan
terraform apply
OR
We can deploy
cdktf deploy
Top comments (3)
Thanks for writing this!
This sounds like something which could be improved as part of the Python template, what do you think? If so, it'd fantastic if you could file a bug cdk.tf/bug
Thanks! I will file a bug.
Oddly I get the following when running the cdktf command?
Adding cdktf~=0.1.0 to Pipfile's [packages]…
Traceback (most recent call last):
File "/usr/lib/python3/dist-packages/pipenv/project.py", line 527, in write_toml
formatted_data = contoml.dumps(data).rstrip()
File "/usr/lib/python3/dist-packages/pipenv/patched/contoml/init.py", line 36, in dumps
raise RuntimeError("Can only dump a TOMLFile instance loaded by load() or loads()")
RuntimeError: Can only dump a TOMLFile instance loaded by load() or loads()
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/usr/bin/pipenv", line 11, in
load_entry_point('pipenv==11.9.0', 'console_scripts', 'pipenv')()
File "/usr/lib/python3/dist-packages/pipenv/vendor/click/core.py", line 722, in call
return self.main(*args, **kwargs)
File "/usr/lib/python3/dist-packages/pipenv/vendor/click/core.py", line 697, in main
rv = self.invoke(ctx)
File "/usr/lib/python3/dist-packages/pipenv/vendor/click/core.py", line 1066, in invoke
return _process_result(sub_ctx.command.invoke(sub_ctx))
File "/usr/lib/python3/dist-packages/pipenv/vendor/click/core.py", line 895, in invoke
return ctx.invoke(self.callback, **ctx.params)
File "/usr/lib/python3/dist-packages/pipenv/vendor/click/core.py", line 535, in invoke
return callback(*args, **kwargs)
File "/usr/lib/python3/dist-packages/pipenv/cli.py", line 349, in install
core.do_install(
File "/usr/lib/python3/dist-packages/pipenv/core.py", line 1979, in do_install
project.add_package_to_pipfile(package_name, dev)
File "/usr/lib/python3/dist-packages/pipenv/project.py", line 610, in add_package_to_pipfile
self.write_toml(p)
File "/usr/lib/python3/dist-packages/pipenv/project.py", line 530, in write_toml
for package in data[section]:
KeyError: 'dev-packages'
cdktf init [OPTIONS]
Create a new cdktf project from a template.
Options:
--version Show version number [boolean]
--disable-logging Dont write log files. Supported using the env CDKTF_DISABLE_LOGGING. [boolean] [default: true]
--disable-plugin-cache-env Dont set TF_PLUGIN_CACHE_DIR automatically. This is useful when the plugin cache is configured differently. Supported using the env CDKTF_DISABLE_PLUGIN_CACHE_ENV. [boolean] [default: false]
--log-level Which log level should be written. Only supported via setting the env CDKTF_LOG_LEVEL [string]
--template The template name to be used to create a new project. [string] [choices: "csharp", "java", "python", "python-pip", "typescript", "typescript-minimal"]
--project-name The name of the project. [string]
--project-description The description of the project. [string]
--dist Install dependencies from a "dist" directory (for development) [string]
--local Use local state storage for generated Terraform. [boolean] [default: false]
--cdktf-version The cdktf version to use while creating a new project. [string] [default: "0.1.0"]
-h, --help Show help [boolean]
{ Error: Command failed: pipenv install cdktf~=0.1.0
at checkExecSyncError (child_process.js:629:11)
at execSync (child_process.js:666:13)
at Object.exports.post.options as post
at executePostHook (/home/khushil/.npm-global/lib/node_modules/cdktf-cli/node_modules/sscaff/lib/sscaff.js:61:37)
at Object.sscaff (/home/khushil/.npm-global/lib/node_modules/cdktf-cli/node_modules/sscaff/lib/sscaff.js:28:15)
status: 1,
signal: null,
output: [ null, null, null ],
pid: 13295,
stdout: null,
stderr: null }