aws / aws/aws-sam-cli

Feature request: Support Golang multi-module workspaces

Open
#6,062 5 comments 0 reactions 0 assignees View on GitHub
area/build type/feature
Dominant language
Python
Stars
6.7k
Forks
1.2k
Avg merge
1d 10h
Merged PRs (30d)
52

Description

### Describe your idea/feature/enhancement

When using Golang for your Lambda functions it's typical to setup a workspace, see: https://go.dev/doc/tutorial/workspaces. What you can do with workspaces is reference to for example a module that might contain some shared logic. Extremely useful for your models that you might use in multiple lambda functions.

### Proposal

When you perform `sam build` the dependencies are downloaded. But when you are referencing a module in the same repository the build will fail. While if you would compile it from the workspace the `go.work` file is considered before downloading any external dependencies.

Things to consider:
1. Building using `go build ./functions/sample-function` does work:
```shell
GOOS=linux CGO_ENABLED=0 go build -o .aws-sam/build/SampleFunctionFunction/bootstrap ./functions/sample-function
```
However, using the command in a `Makefile`:
```Makefile
build-SampleFunctionFunction:
cd ../../ && GOOS=linux CGO_ENABLED=0 go build -o $(ARTIFACTS_DIR)/bootstrap ./functions/sample-function
```
Would fail in:
```shell
Building codeuri: /Users/nr18/workspace/prive/golang-sample-multiple/functions/sample-function runtime: provided.al2 metadata: {'BuildMethod': 'makefile'} architecture: arm64 functions:
SampleFunctionFunction
SampleFunctionFunction: Running CustomMakeBuilder:CopySource
SampleFunctionFunction: Running CustomMakeBuilder:MakeBuild
SampleFunctionFunction: Current Artifacts Directory : /Users/nr18/workspace/prive/golang-sample-multiple/.aws-sam/build/SampleFunctionFunction
cd ../../ && GOOS=linux CGO_ENABLED=0 go build -o /Users/nr18/workspace/prive/golang-sample-multiple/.aws-sam/build/SampleFunctionFunction/bootstrap ./functions/sample-function

Build Failed
Error: CustomMakeBuilder:MakeBuild - Make Failed: go: go.mod file not found in current directory or any parent directory; see 'go help modules'
make: *** [build-SampleFunctionFunction] Error 1
```

### Additional Details

Template

```yaml
AWSTemplateFormatVersion: 2010-09-09
Transform: AWS::Serverless-2016-10-31
Description: |-
Sample Serverless Application Model using golang with shared modules
Resources:
SampleFunctionFunction:
Type: AWS::Serverless::Function
Properties:
Architectures: [ arm64 ]
Runtime: provided.al2
CodeUri: ./functions/sample-function
Handler: bootstrap
Timeout: 300
```

go.work

```go
go 1.21.1

use (
./models
./functions/sample-function
)
```

models/go.mod

```go
module example.com/models

go 1.21.1
```

models/main.go

```go
package models

type Person struct {
Name string
}

func New(name string) *Person {
return &Person{Name: name}
}
```

functions/sample-function/go.mod

```go
module example.com/functions/sample-function

go 1.21.1

require (
github.com/aws/aws-lambda-go v1.41.0 // indirect
github.com/aws/aws-sdk-go-v2 v1.21.1 // indirect
github.com/aws/aws-sdk-go-v2/config v1.18.44 // indirect
github.com/aws/aws-sdk-go-v2/credentials v1.13.42 // indirect
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.13.12 // indirect
github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.42 // indirect
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.36 // indirect
github.com/aws/aws-sdk-go-v2/internal/ini v1.3.44 // indirect
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.36 // indirect
github.com/aws/aws-sdk-go-v2/service/sso v1.15.1 // indirect
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.17.2 // indirect
github.com/aws/aws-sdk-go-v2/service/sts v1.23.1 // indirect
github.com/aws/smithy-go v1.15.0 // indirect
github.com/sirupsen/logrus v1.9.3 // indirect
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8 // indirect
)
```

functions/sample-function/main.go

```go
package main

import (
"context"
"example.com/models"
"fmt"
"github.com/aws/aws-lambda-go/lambda"
"github.com/aws/aws-sdk-go-v2/aws"
"github.com/aws/aws-sdk-go-v2/config"
log "github.com/sirupsen/logrus"
)

func main() {
log.SetFormatter(&log.JSONFormatter{})
log.SetLevel(log.DebugLevel)

cfg, err := config.LoadDefaultConfig(context.TODO())
if err != nil {
log.Printf("error: %v", err)
return
}

lambda.Start(New(cfg).Handler)
}

func New(config aws.Config) *Lambda {
return &Lambda{
config: config,
}
}

type Lambda struct {
ctx context.Context
config aws.Config
}

type Request struct{}
type Response struct{}

// Handler of the AWSLambda function.
func (x *Lambda) Handler(ctx context.Context, request Request) (Response, error) {
person := models.New("John Doe")
fmt.Printf("Name: %s\n", person.Name)
return Response{}, nil
}
```

Build output

```shell
Building codeuri: /Users/nr18/workspace/prive/golang-sample-multiple/functions/sample-function runtime: provided.al2 metadata: {} architecture: arm64 functions: SampleFunctionFunction
SampleFunctionFunction: Running CustomMakeBuilder:CopySource
SampleFunctionFunction: Running CustomMakeBuilder:MakeBuild
SampleFunctionFunction: Current Artifacts Directory : /Users/nr18/workspace/prive/golang-sample-multiple/.aws-sam/build/SampleFunctionFunction
GOOS=linux CGO_ENABLED=0 go build -o bootstrap

Build Failed
Error: CustomMakeBuilder:MakeBuild - Make Failed: lambda.go:5:2: no required module provides package example.com/models; to add it:
go get example.com/models
make: *** [build-SampleFunctionFunction] Error 1
```

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.