Skip to content
This repository has been archived by the owner on Aug 1, 2024. It is now read-only.

feat: add go workshop #636

Merged
merged 13 commits into from
Aug 29, 2022
19 changes: 19 additions & 0 deletions code/go/main-workshop/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Binaries for programs and plugins
*.exe
*.exe~
*.dll
*.so
*.dylib

# Test binary, built with `go test -c`
*.test

# Output of the go coverage tool, specifically when used with LiteIDE
*.out

# go.sum should be committed
!go.sum

# CDK asset staging directory
.cdk.staging
cdk.out
12 changes: 12 additions & 0 deletions code/go/main-workshop/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Welcome to your CDK Go project!

This is a blank project for Go development with CDK.

The `cdk.json` file tells the CDK Toolkit how to execute your app.

## 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
52 changes: 52 additions & 0 deletions code/go/main-workshop/cdk-workshop.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package main

import (
"github.com/aws/aws-cdk-go/awscdk/v2"
"github.com/aws/aws-cdk-go/awscdk/v2/awslambda"
"github.com/aws/aws-cdk-go/awscdk/v2/awsapigateway"
"github.com/aws/constructs-go/constructs/v10"
"github.com/aws/jsii-runtime-go"
"cdk-workshop/hitcounter"
"github.com/cdklabs/cdk-dynamo-table-viewer-go/dynamotableviewer"
)

type CdkWorkshopStackProps struct {
awscdk.StackProps
}

func NewCdkWorkshopStack(scope constructs.Construct, id string, props *CdkWorkshopStackProps) awscdk.Stack {
var sprops awscdk.StackProps
if props != nil {
sprops = props.StackProps
}
stack := awscdk.NewStack(scope, &id, &sprops)

helloHandler := awslambda.NewFunction(stack, jsii.String("HelloHandler"), &awslambda.FunctionProps{
Code: awslambda.Code_FromAsset(jsii.String("lambda"), nil),
Runtime: awslambda.Runtime_NODEJS_16_X(),
Handler: jsii.String("hello.handler"),
})

hitcounter := hitcounter.NewHitCounter(stack, "HelloHitCounter", &hitcounter.HitCounterProps{
Downstream: helloHandler,
})

awsapigateway.NewLambdaRestApi(stack, jsii.String("Endpoint"), &awsapigateway.LambdaRestApiProps{
Handler: hitcounter.Handler(),
})

dynamotableviewer.NewTableViewer(stack, jsii.String("ViewHitCounter"), &dynamotableviewer.TableViewerProps{
Title: jsii.String("Hello Hits"),
Table: hitcounter.Table(),
})

return stack
}

func main() {
peterwoodworth marked this conversation as resolved.
Show resolved Hide resolved
app := awscdk.NewApp(nil)

NewCdkWorkshopStack(app, "CdkWorkshopStack", &CdkWorkshopStackProps{})

app.Synth(nil)
}
25 changes: 25 additions & 0 deletions code/go/main-workshop/cdk-workshop_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package main

import (
"testing"

"github.com/aws/aws-cdk-go/awscdk/v2"
assertions "github.com/aws/aws-cdk-go/awscdk/v2/assertions"
peterwoodworth marked this conversation as resolved.
Show resolved Hide resolved
"github.com/aws/jsii-runtime-go"
)

func TestCdkWorkshopStack(t *testing.T) {
peterwoodworth marked this conversation as resolved.
Show resolved Hide resolved
// GIVEN
app := awscdk.NewApp(nil)

// WHEN
stack := NewCdkWorkshopStack(app, "MyStack", nil)

// THEN
template := assertions.Template_FromStack(stack)

template.HasResourceProperties(jsii.String("AWS::SQS::Queue"), map[string]interface{}{
"VisibilityTimeout": 300,
})
template.ResourceCountIs(jsii.String("AWS::SNS::Topic"), jsii.Number(1))
}
36 changes: 36 additions & 0 deletions code/go/main-workshop/cdk.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
{
"app": "go mod download && go run cdk-workshop.go",
"watch": {
"include": [
"**"
],
"exclude": [
"README.md",
"cdk*.json",
"go.mod",
"go.sum",
"**/*test.go"
]
},
"context": {
"@aws-cdk/aws-apigateway:usagePlanKeyOrderInsensitiveId": true,
"@aws-cdk/core:stackRelativeExports": true,
"@aws-cdk/aws-rds:lowercaseDbIdentifier": true,
"@aws-cdk/aws-lambda:recognizeVersionProps": true,
"@aws-cdk/aws-lambda:recognizeLayerVersion": true,
"@aws-cdk/aws-cloudfront:defaultSecurityPolicyTLSv1.2_2021": true,
"@aws-cdk-containers/ecs-service-extensions:enableDefaultLogDriver": true,
"@aws-cdk/aws-ec2:uniqueImdsv2TemplateName": true,
"@aws-cdk/core:checkSecretUsage": true,
"@aws-cdk/aws-iam:minimizePolicies": true,
"@aws-cdk/aws-ecs:arnFormatIncludesClusterName": true,
"@aws-cdk/core:validateSnapshotRemovalPolicy": true,
"@aws-cdk/aws-codepipeline:crossAccountKeyAliasStackSafeResourceName": true,
"@aws-cdk/aws-s3:createDefaultLoggingPolicy": true,
"@aws-cdk/aws-sns-subscriptions:restrictSqsDescryption": true,
"@aws-cdk/core:target-partitions": [
"aws",
"aws-cn"
]
}
}
10 changes: 10 additions & 0 deletions code/go/main-workshop/go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
module cdk-workshop

go 1.16
peterwoodworth marked this conversation as resolved.
Show resolved Hide resolved

require (
github.com/aws/aws-cdk-go/awscdk/v2 v2.38.1
github.com/aws/constructs-go/constructs/v10 v10.1.84
github.com/aws/jsii-runtime-go v1.65.0
github.com/cdklabs/cdk-dynamo-table-viewer-go/dynamotableviewer v0.2.248 // indirect
peterwoodworth marked this conversation as resolved.
Show resolved Hide resolved
)
42 changes: 42 additions & 0 deletions code/go/main-workshop/go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
github.com/Masterminds/semver/v3 v3.1.1 h1:hLg3sBzpNErnxhQtUy/mmLR2I9foDujNK030IGemrRc=
github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs=
github.com/aws/aws-cdk-go/awscdk/v2 v2.0.0/go.mod h1:2PrsMzp7CioaiAHHEr8zCVkbMIKp+sZs/S15kTkLUH0=
github.com/aws/aws-cdk-go/awscdk/v2 v2.37.0 h1:2n5yszXhyJD0egC+TWmhAuLdsydG4fhA/bYhp8+Vnw0=
github.com/aws/aws-cdk-go/awscdk/v2 v2.37.0/go.mod h1:4CRq7lyCSLNh7DhqbGrDlpeRB3J/INAbBHbNqJsT2+M=
github.com/aws/aws-cdk-go/awscdk/v2 v2.38.1 h1:5Jz4KkHMa0MS4uLQO8X32cuyHxRY8YOOWyFCJRFpfWE=
github.com/aws/aws-cdk-go/awscdk/v2 v2.38.1/go.mod h1:rNrZ+WbqCuPfpUrMcDmrEOel9ZlMCy2+E0iyNCJjS+4=
github.com/aws/constructs-go/constructs/v10 v10.0.5/go.mod h1:l9g2pvi6/NDTGfjih3Zocwk3K4ASge77Pf5KZ2j2484=
github.com/aws/constructs-go/constructs/v10 v10.0.9/go.mod h1:RC6w8bOwxLmPX7Jfo9dkEZ9iVfgH4QnaVnfWvaNOHy0=
github.com/aws/constructs-go/constructs/v10 v10.1.65 h1:KBv8lul4KYoHN5e1Tw9YjhfKpc7+b7EOqvRkyfrdQ24=
github.com/aws/constructs-go/constructs/v10 v10.1.65/go.mod h1:nJzXC/q76n0XkbL76eG0OvJQwbD/lWc7sjerJEARubA=
github.com/aws/constructs-go/constructs/v10 v10.1.71/go.mod h1:nJzXC/q76n0XkbL76eG0OvJQwbD/lWc7sjerJEARubA=
github.com/aws/constructs-go/constructs/v10 v10.1.84 h1:tB6ui58Bvr/mO+qGsghf4v+4NubnBBDjTUkTY/tvBOg=
github.com/aws/constructs-go/constructs/v10 v10.1.84/go.mod h1:7+5GjvX5buJY6vZZmMxd50Ke1+NXzjva8N2eL+3txQQ=
github.com/aws/jsii-runtime-go v1.28.0/go.mod h1:6tZnlstx8bAB3vnLFF9n8bbkI//LDblAek9zFyMXV3E=
github.com/aws/jsii-runtime-go v1.37.0/go.mod h1:6tZnlstx8bAB3vnLFF9n8bbkI//LDblAek9zFyMXV3E=
github.com/aws/jsii-runtime-go v1.46.0/go.mod h1:6tZnlstx8bAB3vnLFF9n8bbkI//LDblAek9zFyMXV3E=
github.com/aws/jsii-runtime-go v1.63.2 h1:brb+tRuZ3lDzFuz6DJCkv7fYLYkTKGVcSb4OgVybsa4=
github.com/aws/jsii-runtime-go v1.63.2/go.mod h1:Dq2QkYFSpiHGabsCBMmLnnGkyx3lnf5k6C6fq8RN/90=
github.com/aws/jsii-runtime-go v1.65.0 h1:A6o9DpZD0+IeFrXJ/qBPX7VJne5Vuk2KSfrG5Ez2dz8=
github.com/aws/jsii-runtime-go v1.65.0/go.mod h1:Dq2QkYFSpiHGabsCBMmLnnGkyx3lnf5k6C6fq8RN/90=
github.com/cdklabs/cdk-dynamo-table-viewer v0.2.248 h1:qs2dMIOnCQ6s7nhT6wDyKBcL0haJwyNAKgGoA0ICcOw=
github.com/cdklabs/cdk-dynamo-table-viewer v0.2.248/go.mod h1:SknfA0tupkK9y9l35o64RWIr0LNGgwpe+Nag4d7e0G4=
github.com/cdklabs/cdk-dynamo-table-viewer-go v0.0.0-20220823004116-3d19340eb06d h1:ORv74+9SCZHnBgrVmYm9Hivpt5vVnHc8Eb2bcOIrb5k=
github.com/cdklabs/cdk-dynamo-table-viewer-go v0.0.0-20220823004116-3d19340eb06d/go.mod h1:fTBHq/yVSzsVKc5CMVXCzuhgnzmXBvAgF9kZ685jxTA=
github.com/cdklabs/cdk-dynamo-table-viewer-go/dynamotableviewer v0.2.248 h1:WemEJJwFDVANkBm0u/wEIEgvCITfnX5L9Co0EQW763I=
github.com/cdklabs/cdk-dynamo-table-viewer-go/dynamotableviewer v0.2.248/go.mod h1:k4cRRJUP2rBTxriNTIlJqoXgsTVoYtoCZPi6OLRGKXY=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
57 changes: 57 additions & 0 deletions code/go/main-workshop/hitcounter/hitcounter.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package hitcounter

import (
"github.com/aws/aws-cdk-go/awscdk/v2"
"github.com/aws/aws-cdk-go/awscdk/v2/awsdynamodb"
"github.com/aws/aws-cdk-go/awscdk/v2/awslambda"
"github.com/aws/constructs-go/constructs/v10"
"github.com/aws/jsii-runtime-go"
)

type HitCounterProps struct {
Downstream awslambda.IFunction
}

type hitCounter struct {
constructs.Construct
handler awslambda.IFunction
table awsdynamodb.Table
}

type HitCounter interface {
constructs.Construct
Handler() awslambda.IFunction
Table() awsdynamodb.Table
}

func NewHitCounter(scope constructs.Construct, id string, props *HitCounterProps) HitCounter {
this := constructs.NewConstruct(scope, &id)

table := awsdynamodb.NewTable(this, jsii.String("Hits"), &awsdynamodb.TableProps{
PartitionKey: &awsdynamodb.Attribute{Name: jsii.String("path"), Type: awsdynamodb.AttributeType_STRING},
RemovalPolicy: awscdk.RemovalPolicy_DESTROY,
})

handler := awslambda.NewFunction(this, jsii.String("HitCounterHandler"), &awslambda.FunctionProps{
Runtime: awslambda.Runtime_NODEJS_16_X(),
Handler: jsii.String("hitcounter.handler"),
Code: awslambda.Code_FromAsset(jsii.String("lambda"), nil),
Environment: &map[string]*string{
"DOWNSTREAM_FUNCTION_NAME": (*props).Downstream.FunctionName(),
"HITS_TABLE_NAME": table.TableName(),
},
})

table.GrantReadWriteData(handler)
props.Downstream.GrantInvoke(handler)

return &hitCounter{this, handler, table}
}

func (h *hitCounter) Handler() awslambda.IFunction {
return h.handler
}

func (h *hitCounter) Table() awsdynamodb.Table {
return h.table
}
8 changes: 8 additions & 0 deletions code/go/main-workshop/lambda/hello.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
exports.handler = async function(event) {
console.log("request:", JSON.stringify(event, undefined, 2));
return {
statusCode: 200,
headers: { "Content-Type": "text/plain" },
body: `Hello, CDK! You've hit ${event.path}\n`
};
};
28 changes: 28 additions & 0 deletions code/go/main-workshop/lambda/hitcounter.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
const { DynamoDB, Lambda } = require('aws-sdk');

exports.handler = async function(event) {
console.log("request:", JSON.stringify(event, undefined, 2));

// create AWS SDK clients
const dynamo = new DynamoDB();
const lambda = new Lambda();

// update dynamo entry for "path" with hits++
await dynamo.updateItem({
TableName: process.env.HITS_TABLE_NAME,
Key: { path: { S: event.path } },
UpdateExpression: 'ADD hits :incr',
ExpressionAttributeValues: { ':incr': { N: '1' } }
}).promise();

// call downstream function and capture response
const resp = await lambda.invoke({
FunctionName: process.env.DOWNSTREAM_FUNCTION_NAME,
Payload: JSON.stringify(event)
}).promise();

console.log('downstream response:', JSON.stringify(resp, undefined, 2));

// return response back to upstream caller
return JSON.parse(resp.Payload);
};
4 changes: 2 additions & 2 deletions workshop/content/20-typescript/30-hello-cdk/200-lambda.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,9 @@ each AWS service. For example, if you want to define an AWS Lambda function, we
will need to use the AWS Lambda construct library.

To discover and learn about AWS constructs, you can browse the [AWS Construct
Library reference](https://docs.aws.amazon.com/cdk/api/latest/docs/aws-construct-library.html).
Library reference](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-construct-library.html).

![](./clib.png)
![](/images/apiref.png)
peterwoodworth marked this conversation as resolved.
Show resolved Hide resolved

## A few words about copying & pasting in this workshop

Expand Down
Binary file not shown.
4 changes: 2 additions & 2 deletions workshop/content/30-python/30-hello-cdk/200-lambda.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,9 @@ each AWS service. For example, if you want to define an AWS Lambda function, we
will need to use the AWS Lambda construct library.

To discover and learn about AWS constructs, you can browse the [AWS Construct
Library reference](https://docs.aws.amazon.com/cdk/api/latest/docs/aws-construct-library.html).
Library reference](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-construct-library.html).

![](./clib.png)
![](/images/apiref.png)
peterwoodworth marked this conversation as resolved.
Show resolved Hide resolved

## A few words about copying & pasting in this workshop

Expand Down
Binary file removed workshop/content/30-python/30-hello-cdk/clib.png
Binary file not shown.
Binary file removed workshop/content/40-dotnet/30-hello-cdk/clib.png
Binary file not shown.
4 changes: 2 additions & 2 deletions workshop/content/50-java/30-hello-cdk/200-lambda.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,9 @@ each AWS service. For example, if you want to define an AWS Lambda function, we
will need to use the AWS Lambda construct library.

To discover and learn about AWS constructs, you can browse the [AWS Construct
Library reference](https://docs.aws.amazon.com/cdk/api/latest/docs/aws-construct-library.html).
Library reference](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-construct-library.html).

![](./clib.png)
![](/images/apiref.png)
peterwoodworth marked this conversation as resolved.
Show resolved Hide resolved
## A few words about copying & pasting in this workshop

In this workshop, we highly recommended to type CDK code instead of copying &
Expand Down
Binary file removed workshop/content/50-java/30-hello-cdk/clib.png
Binary file not shown.
49 changes: 49 additions & 0 deletions workshop/content/60-go/20-create-project/100-cdk-init.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
+++
title = "cdk init"
weight = 100
+++

## Create project directory

Create an empty directory on your system:

```
mkdir cdk-workshop && cd cdk-workshop
```

## cdk init

We will use `cdk init` to create a new Go CDK project:

```
cdk init sample-app --language go
```

Output should look like this (you can safely ignore warnings about
initialization of a git repository, this probably means you don't have git
installed, which is fine for this workshop):

```
Applying project template sample-app for go
# Welcome to your CDK Go project!

This is a blank project for Go development with CDK.

The `cdk.json` file tells the CDK Toolkit how to execute your app.

## 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

Initializing a new git repository...
✅ All done!
```

As you can see, it shows us a bunch of useful commands to get us started.

## See Also

- [AWS CDK Command Line Toolkit (cdk) in the AWS CDK User Guide](https://docs.aws.amazon.com/CDK/latest/userguide/tools.html)
Loading