AWS Developer Tools Blog
Getting started with the AWS Cloud Development Kit and Go
We are excited to announce that Go support for AWS CDK is now in Developer Preview. This means it is now ready for you to test drive in your own CDK applications. This post will show you how to initialize a new AWS CDK app as well as the basics of creating and deploying AWS CDK stacks using the Go programming language.
For more information about continuing development as it approaches stability, check out the project board in the jsii github repository. Additionally, we would love to hear about your experience. We encourage you to open a github issue for any bugs you may encounter as well as features that you would like to see added.
Creating a Go CDK Application
First, make sure you have the latest version of the AWS CDK CLI installed via npm.
$ npm install -g aws-cdk
Additionally, make sure to install the Go compiler toolchain version 1.16 or newer. You can find download and installation instructions for your platform at https://golang.org/dl/.
Next, create a new AWS CDK application in Go using cdk init
$ mkdir hello-cdk-go
$ cd hello-cdk-go
$ cdk init --language=go
This will create the initial files needed for an AWS CDK Go application in the current directory. It will also output a description of the commands needed to synthesize and deploy your stacks.
# Welcome to your CDK Go project!
This is a blank project for Go development with CDK.
**NOTICE**: Go support is still in Developer Preview. This implies that APIs may change while we address early
feedback from the community. We would love to hear about your experience through GitHub issues.
## Useful commands
* `cdk deploy` deploy this stack to your default AWS account/region
* `cdk diff` compare deployed stack with current state
* `cdk synth` emits the synthesized CloudFormation template
* `go test` run unit tests
Now, with your basic application scaffolded, examine the source files that were created by cdk init
├── README.md
├── hello-cdk-go.go
├── hello-cdk-go_test.go
├── cdk.json
└── go.mod
README.md
– The top level readme for your cdk projecthello-cdk-go.go
– Your Go program’s main entrypointhello-cdk-go_test.go
– Your unit tests for your applicationcdk.json
– A configuration file that tells the cdk cli how to build and run your applicationgo.mod
– The go module definition for your cdk app. This is where dependencies are declared on the aws-cdk Go packages that you need.
With the Go toolchain and CDK CLI installed you now have a working CDK Go Application!
Synthesizing Your Stack
Synthesizing your stack will generate a local directory, cdk.out
, which contains your application’s build artifact. This artifact is known as a cloud assembly and it contains an AWS CloudFormation template along with any assets and other resources required to deploy your application to AWS. The generated template’s structure is output to the console.
$ cdk synth
Resources:
MyTopic86869434:
Type: AWS::SNS::Topic
Properties:
DisplayName: MyCoolTopic
Metadata:
aws:cdk:path: HelloCdkGoStack/MyTopic/Resource
CDKMetadata:
Type: AWS::CDK::Metadata
Properties:
Analytics: v2:deflate64:H4sIAAAAAAAAAyWJQQrCMBAA39J73BLQQs/9QfUuYRNlW7Mr2Q0tlP5dq6cZZjz0F/BNFhaMM2xXCzi7sOhdWWG7yZvQDQ/+ye4GYbVS0Y42JpVaMB3+HZGMhHf3FA++a1/EdW1Djt25mZToVCob5QTjnx/dh+yLegAAAA==
Metadata:
aws:cdk:path: HelloCdkGoStack/CDKMetadata/Default
Condition: CDKMetadataAvailable
Conditions:
…
This application has several resources already defined. Next examine hello-cdk-go.go
where you will find the code that produced the preceeding.
package main
import (
"github.com/aws/aws-cdk-go/awscdk"
"github.com/aws/aws-cdk-go/awscdk/awssns"
"github.com/aws/constructs-go/constructs/v3"
"github.com/aws/jsii-runtime-go"
)
type HelloCdkGoStackProps struct {
awscdk.StackProps
}
func NewHelloCdkGoStack(scope constructs.Construct, id string, props *HelloCdkGoStackProps) awscdk.Stack {
var sprops awscdk.StackProps
if props != nil {
sprops = props.StackProps
}
stack := awscdk.NewStack(scope, &id, &sprops)
// The code that defines your stack goes here
// as an example, here's how you would define an AWS SNS topic:
awssns.NewTopic(stack, jsii.String("MyTopic"), &awssns.TopicProps{
DisplayName: jsii.String("MyCoolTopic"),
})
return stack
}
func main() {
app := awscdk.NewApp(nil)
NewHelloCdkGoStack(app, "HelloCdkGoStack", &HelloCdkGoStackProps{
awscdk.StackProps{
Env: env(),
},
})
app.Synth(nil)
}
// env determines the AWS environment (account+region) in which our stack is to
// be deployed. For more information see: https://docs.aws.amazon.com/cdk/latest/guide/environments.html
func env() *awscdk.Environment {
// If unspecified, this stack will be "environment-agnostic".
// Account/Region-dependent features and context lookups will not work, but a
// single synthesized template can be deployed anywhere.
//---------------------------------------------------------------------------
return nil
// Uncomment if you know exactly what account and region you want to deploy
// the stack to. This is the recommendation for production stacks.
//---------------------------------------------------------------------------
// return &awscdk.Environment{
// Account: jsii.String("123456789012"),
// Region: jsii.String("us-east-1"),
// }
// Uncomment to specialize this stack for the AWS Account and Region that are
// implied by the current CLI configuration. This is recommended for dev
// stacks.
//---------------------------------------------------------------------------
// return &awscdk.Environment{
// Account: jsii.String(os.Getenv("CDK_DEFAULT_ACCOUNT")),
// Region: jsii.String(os.Getenv("CDK_DEFAULT_REGION")),
// }
}
This file defines our program’s main
function. It also imports the github.com/aws/aws-cdk-go/awscdk
packages and then defines a few functions. Examine the main
function first.
func main() {
app := awscdk.NewApp(nil)
NewHelloCdkGoStack(app, "HelloCdkGoStack", &HelloCdkGoStackProps{
awscdk.StackProps{
Env: env(),
},
})
app.Synth(nil)
}
Here the awscdk.NewApp
function is called which initializes the CDK app.
The documentation for this function indicates that it returns a struct implementing the App interface. This interface is then passed to the NewHelloCdkGoStack
function along with the “HelloCdkGoStack” id and an instance of the HelloCdkGoStackProps
struct. If you examine this function further, you will notice what it is doing with these arguments.
func NewHelloCdkGoStack(scope constructs.Construct, id string, props *HelloCdkGoStackProps) awscdk.Stack {
var sprops awscdk.StackProps
if props != nil {
sprops = props.StackProps
}
stack := awscdk.NewStack(scope, &id, &sprops)
// The code that defines your stack goes here
// as an example, here's how you would define an AWS SNS topic:
awssns.NewTopic(stack, jsii.String("MyTopic"), &awssns.TopicProps{
DisplayName: jsii.String("MyCoolTopic"),
})
return stack
}
From here you can see that NewHelloCdkGoStack
extracts the embedded awscdk.StackProps
struct from its own props argument and passes it down when creating a new Stack. Then it creates a new SNS Topic with the id “MyTopic” and a name of “MyCoolTopic”.
You will also notice that NewHelloCdkGoStack
accepts a struct implementing the constructs.Construct
interface. If you follow the documentation, you will notice that awscdk.App
embeds awscdk.Stage
which in turn embeds constructs.Construct
.
The AWS CDK in Go uses interfaces to model constructs and provides factory functions for creating new instances of objects that implement these interfaces. When navigating the documentation, if you encounter an interface type InterfaceName
, there is always an exported function called NewInterfaceName
for acquiring one. awscdk.NewStack
returns an implementation of awscdk.Stack
and awslambda.NewFunction
returns an implementation of awslambda.Function
.
You may also notice the frequent usage of pointer types. Pointer types are used to allow for optionality which Go does not natively support. There are convenience functions provided by the jsii Go Runtime to make passing pointer types a little more ergonomic. You can see the usage of these functions above with jsii.String
, which accepts a string a returns a pointer to that string. This removes the need for allocating a variable in order to point to it just to pass a literal value that would otherwise be inline.
Both of these patterns may feel familiar to Go users, but for more information about why aws-cdk-go is modeled this way, check out the Go Language Bindings RFC.
Deploying Your App
Now that you know what the example app contains, you can deploy it to your AWS account using the deploy
command of the AWS CDK CLI. First, make sure you have credentials configured to allow your local environment to deploy to your intended account. Instructions for configuring credentials can be found in the User Guide for the AWS CLI. Then you can run the cdk deploy
command.
HelloCdkGoStack: deploying...
HelloCdkGoStack: creating CloudFormation changeset...
[█████████████████████████████████████████████] (3/3)
✅ HelloCdkGoStack
Stack ARN:
arn:aws:cloudformation:REGION:000000000000:stack/HelloCdkGoStack/00000000-0000-0000-0000-000000000000
Now that your stack is deployed, feel free to examine the AWS CDK Reference Documentation for constructs that you can add to your stack. Each construct has a corresponding interface that can be found in the Go documentation on pkg.go.dev.
Clean Up
After a successful deployment, you can inspect the created resources in your account. When you are ready to delete the test stack you can run the cdk destroy
command from your terminal.
$ cdk destroy
Are you sure you want to delete: HelloCdkGoStack (y/n)? y
HelloCdkGoStack: destroying...
10:18:56 AM | DELETE_IN_PROGRESS | AWS::CloudFormation::Sta
ck | HelloCdkGoStack
✅ HelloCdkGoStack: destroyed
Conclusion
In this post, you learned how to initialize and deploy a CDK Go application, as well as the basics of using the AWS CDK go module to define your own stacks and resources. We are excited to see what Gophers build using the CDK!
A lot of the code examples in the CDK reference documentation and developer guide are translated between supported languages. We are working on updating these examples to add Go translations. In the meantime, here are some basic guidelines to help map CDK APIs to Go.
- Instantiate constructs using the
NewConstructName
factory functions - Construct props are go structs that can be constructed using struct literals
- Use the pointer helper functions to pass primitive literal values to construct props (IE:
jsii.String
)
For more information about using the CDK with Go, check out the following documentation sites.
- AWS CDK Developer Guide
- AWS CDK Reference Documentation
- AWS CDK Go Module API Documentation
- JSII Go Bindings RFC
Since Go support is in Developer Preview, we are expecting to discover bugs and there are some known issues that the team is still fixing. If you’re interested in reporting new bugs, or helping to fix existing bugs, check out the new project board tracking work towards general availability. Also join the community on the cdk.dev slack channel to discuss your experience using the AWS CDK with Go.