Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add experimental support for Go #686

Merged
merged 46 commits into from
May 26, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
46 commits
Select commit Hold shift + click to select a range
591fde2
empty commit to allow opening PR to track work required for supportin…
ansgarm May 5, 2021
14efba0
initial rough support for using golang
ansgarm May 5, 2021
408bb6c
wip: change generated go module names
ansgarm May 7, 2021
859031f
Merge branch 'main' into support-golang
ansgarm May 10, 2021
632870d
change go package name to reside in hashicorp github org
ansgarm May 11, 2021
de6fc21
add example for Go
ansgarm May 11, 2021
dfcef31
add Github Actions job for releasing to hashicorp/terraform-cdk-go
ansgarm May 11, 2021
4d75c5e
update jsii-srcmak patch to be based on PR cdklabs/jsii-srcmak/476
ansgarm May 14, 2021
6baa534
chore: add tsconfig.buildinfo to gitignore
ansgarm May 18, 2021
0f799ac
chore: work on docs and examples
ansgarm May 18, 2021
8010165
Merge branch 'main' into support-golang
ansgarm May 18, 2021
85627a6
feat: add template for go
ansgarm May 19, 2021
9c12ce0
chore: upgrade jsii-srcmak and remove patch-package
ansgarm May 20, 2021
68d70a4
chore: adjust constructs maker to infer go module name from root project
ansgarm May 21, 2021
31e0bd6
tests: add integration test for go
ansgarm May 21, 2021
adf9478
feat: add namespace (if there is one) to provider constraint to use f…
ansgarm May 21, 2021
6f7d030
Merge branch 'main' into support-golang
ansgarm May 21, 2021
8920037
chore: add somehow missing snapshot
ansgarm May 21, 2021
3ff0a58
tests: increase timeouts
ansgarm May 21, 2021
e573e5b
fix case statement not behaving as intended
ansgarm May 25, 2021
ff2732d
tests: update snapshots
ansgarm May 25, 2021
2185b27
tests: add test for determineGoModuleName helper
ansgarm May 25, 2021
8e02a6f
chore: add config to build go example in CI
ansgarm May 25, 2021
864be00
chore: remove obsolete dependency
ansgarm May 25, 2021
b45c5f6
chore: add go to build examples workflow
ansgarm May 25, 2021
4f9558a
chore: update go docker example to reflect new import path
ansgarm May 25, 2021
9e71ffa
chore: update go aws example to reflect new import path
ansgarm May 25, 2021
4a8cc63
chore: improve comment
ansgarm May 25, 2021
854f9a6
chore: add go examples to lerna.json
ansgarm May 25, 2021
e0e46d3
chore: add go examples to workspaces in root package.json
ansgarm May 25, 2021
6ffdd30
chore: run tidy only after modules have been generated
ansgarm May 25, 2021
0565e21
fix: change codeMakerOutput for go from '.gen' to 'generated' as lead…
ansgarm May 25, 2021
0018556
docs: improve steps
ansgarm May 25, 2021
22b4f85
docs: reword installation instructions for clarity
ansgarm May 25, 2021
d662595
chore: add package.json to aws go example
ansgarm May 25, 2021
c58fa6c
fix: set NODE_OPTIONS with more memory for provider generation via pr…
ansgarm May 25, 2021
a6937b9
revert: remove NODE_OPTIONS env from Dockerfile as this is set via pr…
ansgarm May 25, 2021
53efa6b
docs: finish up getting started guide for Go. updating gitignore of g…
ansgarm May 25, 2021
11d2e78
feat(cli): add note about getting jsii-runtime dependency when using …
ansgarm May 25, 2021
699bc10
docs: list Go examples with disclaimer in Readme
ansgarm May 25, 2021
543459a
docs: link Go getting started guide in Readme
ansgarm May 25, 2021
894e1f7
docs: add info about jsii.String() helper method to Go getting starte…
ansgarm May 25, 2021
1e73a60
Add aws eks module to aws example
skorfmann May 25, 2021
d56f624
Update yarn.lock
skorfmann May 25, 2021
56a3deb
chore: use alias for long package name
ansgarm May 26, 2021
78b1883
feat(cli): don't override the NODE_OPTIONS env var if it was set alre…
ansgarm May 26, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/examples.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ jobs:
strategy:
matrix:
terraform: ["0.14.7"]
target: ["python", "csharp", "java", "typescript"]
target: ["python", "csharp", "java", "typescript", "go"]
container:
image: docker.mirror.hashicorp.services/hashicorp/jsii-terraform
env:
Expand Down
17 changes: 17 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,23 @@ jobs:
env:
NUGET_API_KEY: ${{ secrets.NUGET_API_KEY }}

release_golang:
name: Release Go to Github Repo
needs: build_artifact
runs-on: ubuntu-latest
container:
image: docker.mirror.hashicorp.services/hashicorp/jsii-terraform
steps:
- name: Download dist
uses: actions/download-artifact@v2
with:
name: dist
path: dist
- name: Release
run: npx -p jsii-release jsii-release-golang
env:
GITHUB_TOKEN: ${{ secrets.TERRAFORM_CDK_GO_REPO_GITHUB_TOKEN }}

release_homebrew:
name: Release to Homebrew
# The branch or tag ref that triggered the workflow run.
Expand Down
19 changes: 18 additions & 1 deletion .github/workflows/release_next.yml
Original file line number Diff line number Diff line change
Expand Up @@ -102,4 +102,21 @@ jobs:
- name: Release
run: npx -p jsii-release jsii-release-nuget
env:
NUGET_API_KEY: ${{ secrets.NUGET_API_KEY }}
NUGET_API_KEY: ${{ secrets.NUGET_API_KEY }}

release_golang:
name: Release Go to Github Repo
needs: build_artifact
runs-on: ubuntu-latest
container:
image: docker.mirror.hashicorp.services/hashicorp/jsii-terraform
steps:
- name: Download dist
uses: actions/download-artifact@v2
with:
name: dist
path: dist
- name: Release
run: npx -p jsii-release jsii-release-golang
env:
GITHUB_TOKEN: ${{ secrets.TERRAFORM_CDK_GO_REPO_GITHUB_TOKEN }}
7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ Choose a language:
* [Python](./docs/getting-started/python.md)
* [Java](./docs/getting-started/java.md)
* [C#](./docs/getting-started/csharp.md)
* [Go](./docs/getting-started/go.md)

## Examples

Expand Down Expand Up @@ -77,6 +78,12 @@ Choose a language:
* [azure](./examples/csharp/azure)
* [google](./examples/csharp/google)

### Go
> Please note: Support for Golang is at an experimental state. In the CDK for Terraform and in the [upstream library JSII](https://aws.github.io/jsii/user-guides/lib-author/configuration/targets/go/) which powers the support for the supported languages.

* [docker](./examples/go/docker)
* [aws](./examples/go/aws) ⚠️ _High memory usage: the provider generation currently needs ~6 GB of memory. Hence the maximum for Node.js is [currently set to 8GB](https://github.com/hashicorp/terraform-cdk/blob/11d2e783d1fe94e50abd116ba73689c02590a391/packages/cdktf-cli/lib/get/constructs-maker.ts#L279)_

## Documentation

* Install and run a quick start tutorial at [HashiCorp Learn](https://learn.hashicorp.com/terraform/cdktf/cdktf-install)
Expand Down
4 changes: 2 additions & 2 deletions docs/cli-commands.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ Options:
--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]
--output, -o Output directory for generated Constructs [string] [default: ".gen"]
--language, -l Output programming language [string] [required] [choices: "typescript", "python", "java", "csharp"]
--language, -l Output programming language [string] [required] [choices: "typescript", "python", "java", "csharp", "go"]
-h, --help Show help [boolean]
```

Expand Down Expand Up @@ -113,7 +113,7 @@ 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]
--template The template name to be used to create a new project. [string] [choices: "python", "typescript", "java", "csharp"]
--template The template name to be used to create a new project. [string] [choices: "python", "typescript", "java", "csharp", "go"]
--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]
Expand Down
2 changes: 1 addition & 1 deletion docs/getting-started/csharp.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ Install with [Homebrew](https://brew.sh):
```shell
$ brew install cdktf
```
Or install with npm (requires [Node.js](https://nodejs.org)):
Or install with `npm` (comes with [Node.js](https://nodejs.org)):

```bash
npm install -g cdktf-cli
Expand Down
290 changes: 290 additions & 0 deletions docs/getting-started/go.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,290 @@
# Getting Started with Go

## Prerequisites

- [Terraform](https://www.terraform.io/downloads.html) >= v0.12
- [Node.js](https://nodejs.org) >= v12.16
- [Go](https://golang.org/dl/) >= 1.16 (CDK for Terraform uses [go modules](https://golang.org/doc/go1.11#modules) and JSII requires Go 1.16)

### Install CDK for Terraform CLI

Install with [Homebrew](https://brew.sh):

```shell
$ brew install cdktf
```
Or install with `npm` (comes with [Node.js](https://nodejs.org)):

```bash
npm install -g cdktf-cli
```

Learn more how to use the cdktf command-line interface [here](../cli-commands.md).

## Initialize a new CDK for Terraform project

```bash
mkdir hello-terraform
cd hello-terraform
```

**Initialize a new CDK for Terraform project**

```bash
cdktf init --template="go" --local
```

This will initialize a brand new CDK for Terraform project in Go using an interactive command.

```bash
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.

## CDK for Terraform Application

You can now open up the `main.go` file to view your application code.

```bash
vim main.go
```

```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](../../examples/) directory for additional examples.

Let's take a simple Go application that uses the CDK for Terraform package.

```go
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](https://github.com/aws/aws-cdk-rfcs/blob/master/text/204-golang-bindings.md#optional-values-and-pointer-types)
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.

## Generating Go provider bindings
For the above example to work, we need to add the `kreuzwerker/docker` Terraform provider to the `cdktf.json`.

```json
{
...
"terraformProviders": [
"kreuzwerker/docker@~> 2.11"
],
...
}
```

After adding the provider and saving the file, we can run `cdktf get` to download generate the bindings for the providers. By default the generated Go code will be output to the `generated` subdirectory.

### Dependencies
The generated provider bindings depend on `jsii-runtime-go`. To automatically add that depedency to your code, you can run `go mod tidy`.

## Synthesize Application

When you are ready you can run the `synthesize` command to generate Terraform JSON configuration for the application.

```bash
cdktf synth
```

```bash
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.

```bash
cd cdktf.out
```

Terraform AWS provider and instance expressed as Terraform JSON configuration.

```json
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`.

## Deploy Application

> Note: You can use Terraform commands like `terraform init`, `terraform plan`, and `terraform apply` with the generated
> Terraform JSON configuration (learn more [here](../working-with-cdk-for-terraform/synthesizing-config.md)) 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.

```bash
cdktf deploy
```

This command will ask for confirmation on a generated diff and then deploy the application.

```bash
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

```bash
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.

## Destroy Application

You can destroy the application by running `cdktf destroy`.

```bash
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.

```bash
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

```bash
Destroying Stack: hello-terraform
Resources
✔ DOCKER_CONTAINER nginxContainer docker_container.nginxContainer
✔ DOCKER_IMAGE nginxImage docker_image.nginxImage

Summary: 2 destroyed.
```
Loading