The file dsl.go
contains CDK code, which creates the CloudFormation template.
Let’s look at the Lambda Function as an example:
myHandler := awslambda.NewFunction(stack, aws.String("myHandler"),
&awslambda.FunctionProps{
Description: aws.String("dsl - dynamodb s3 lambda"),
FunctionName: aws.String("logincomingobject"),
LogRetention: logs.RetentionDays_THREE_MONTHS,
MemorySize: aws.Float64(1024),
Timeout: awscdk.Duration_Seconds(aws.Float64(10)),
Code: awslambda.Code_FromAsset(&lambdaPath, &awss3assets.AssetOptions{}),
Handler: aws.String("main"),
Runtime: awslambda.Runtime_GO_1_X(),
})
When you call cdk synth
(just generate) or cdk diff
(see differences to deployed stack) or cdk deploy
(deploy stack), inside the directory cdk.out the template is generated in the file dsl.template.json.
The naming schema is ${stackname}.template.json. So if you rename the stack, some orphaned files will be created.
Delete the cdk.out
directory from time to time, it takes a lot of space and is just there to hold generated files.
This is the Lambda Function part of the generated CloudFormation:
"myHandler0D56A5FA": {
"Type": "AWS::Lambda::Function",
"Properties": {
"Code": {
"S3Bucket": {
"Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}"
},
"S3Key": "5730888db11c312649e198855f33a572c8f61507cf6bfa67b9d1d98e01a83d4c.zip"
},
...
"Handler": "main",
"MemorySize": 1024,
"Runtime": "go1.x",
"Timeout": 10
},
If you have a simple configuration, you can be quite sure that the right CloudFormation is generated. But there are a few things that can go wrong:
Then a Unit test for the infrastructure is a good idea.
Let us assume we want to test the Function and there is only one function:
The test code is in the file dsl_test.go
3 import (
4 "testing"
5 "github.com/aws/aws-sdk-go-v2/aws"
6
7 "github.com/aws/aws-cdk-go/awscdk/v2"
8 assertions "github.com/aws/aws-cdk-go/awscdk/v2/assertions"
9
10 "dsl"
11 )
Import | why |
---|---|
4 testing | testing basic |
5 aws | just for pointer conversion / you could use jssi |
7 cdk | to generate the stack |
8 assertions | helper for the assert checks itself |
10 dsl | because the package is dsl_test we need to import dsl |
15 func TestInfraDslStack(t *testing.T) {
16 // GIVEN
17 app := awscdk.NewApp(nil)
18
19 // WHEN
20 stack := dsl.NewDslStack(app, "MyStack", nil)
21
22 // THEN
23 template := assertions.Template_FromStack(stack)
24
25 template.HasResourceProperties(aws.String("AWS::Lambda::Function"), map[string]interface{}{
26 "Runtime": "go1.x",
27 })
28 }
Line | what |
---|---|
17 | create the CDK APP |
20 | the creation of the stack, which is defined in package dsl. No aka “nil” options |
23 | generate the Template. This step is the slowest |
25,26 | Look into the function and test the property “runtime” |
So this test checks for this line in the generated CloudFormation file:
"Runtime": "go1.x",
This seems a little basic. But you should have at least one test to check whether your CDK code has no errors and generates CloudFormation.
export I_TEST=no
go test -v
Gives the output:
=== RUN TestInfraDslStack
--- PASS: TestInfraDslStack (2.17s)
=== RUN TestInfraLambdaExists
integration_test.go:15: Skipping testing in non Integration environment
--- SKIP: TestInfraLambdaExists (0.00s)
PASS
ok dsl 2.706s
With the env variable “I_TEST” we control whether the integration test are run or not. The Integration tests have this code to control skippability:
if os.Getenv("I_TEST") != "yes" {
t.Skip("Skipping testing in non Integration environment")
}
There are more helper functions in the assertion library - just experiment with different values to see the effects!
Now that we have a infrastructure Unit test, in the next chapter I create a Infrastructure Integration test.
See the full source on github.