Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add ephemeralStorage option to lambda config #4680

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,10 @@ spec:
app: simple
environments:
FOO: bar
# ephemeralStorage is optional value. If you define a ephemeral storage to lambda, you can
# use this field. The value must be in between 512 to 10240 MB.
ephemeralStorage:
size: 512
# vpcConfig is optional value. If you define a vpc configuration to lambda, you can
# use this field.
vpcConfig:
Expand Down
10 changes: 9 additions & 1 deletion pkg/app/piped/platformprovider/lambda/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,9 @@
}
input.Architectures = architectures
}
if fm.Spec.EphemeralStorage != nil {
input.EphemeralStorage.Size = aws.Int32(fm.Spec.EphemeralStorage.Size)
}

Check warning on line 131 in pkg/app/piped/platformprovider/lambda/client.go

View check run for this annotation

Codecov / codecov/patch

pkg/app/piped/platformprovider/lambda/client.go#L129-L131

Added lines #L129 - L131 were not covered by tests
if fm.Spec.VPCConfig != nil {
input.VpcConfig = &types.VpcConfig{
SecurityGroupIds: fm.Spec.VPCConfig.SecurityGroupIDs,
Expand Down Expand Up @@ -179,7 +182,9 @@
Variables: fm.Spec.Environments,
},
}

if fm.Spec.EphemeralStorage != nil {
input.EphemeralStorage.Size = aws.Int32(fm.Spec.EphemeralStorage.Size)
}

Check warning on line 187 in pkg/app/piped/platformprovider/lambda/client.go

View check run for this annotation

Codecov / codecov/patch

pkg/app/piped/platformprovider/lambda/client.go#L185-L187

Added lines #L185 - L187 were not covered by tests
_, err = c.client.CreateFunction(ctx, input)
if err != nil {
return fmt.Errorf("failed to create Lambda function %s: %w", fm.Spec.Name, err)
Expand Down Expand Up @@ -278,6 +283,9 @@
if fm.Spec.Handler != "" {
configInput.Handler = aws.String(fm.Spec.Handler)
}
if fm.Spec.EphemeralStorage != nil {
configInput.EphemeralStorage.Size = aws.Int32(fm.Spec.EphemeralStorage.Size)
}

Check warning on line 288 in pkg/app/piped/platformprovider/lambda/client.go

View check run for this annotation

Codecov / codecov/patch

pkg/app/piped/platformprovider/lambda/client.go#L286-L288

Added lines #L286 - L288 were not covered by tests
if fm.Spec.VPCConfig != nil {
configInput.VpcConfig = &types.VpcConfig{
SecurityGroupIds: fm.Spec.VPCConfig.SecurityGroupIDs,
Expand Down
55 changes: 37 additions & 18 deletions pkg/app/piped/platformprovider/lambda/function.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,11 @@ const (
functionManifestKind = "LambdaFunction"
// Memory and Timeout lower and upper limit as noted via
// https://docs.aws.amazon.com/sdk-for-go/api/service/lambda/#UpdateFunctionConfigurationInput
memoryLowerLimit = 1
timeoutLowerLimit = 1
timeoutUpperLimit = 900
memoryLowerLimit = 1
timeoutLowerLimit = 1
timeoutUpperLimit = 900
ephemeralStorageLowerLimit = 512
ephemeralStorageUpperLimit = 10240
)

type FunctionManifest struct {
Expand All @@ -56,21 +58,22 @@ func (fm *FunctionManifest) validate() error {

// FunctionManifestSpec contains configuration for LambdaFunction.
type FunctionManifestSpec struct {
Name string `json:"name"`
Role string `json:"role"`
ImageURI string `json:"image"`
S3Bucket string `json:"s3Bucket"`
S3Key string `json:"s3Key"`
S3ObjectVersion string `json:"s3ObjectVersion"`
SourceCode SourceCode `json:"source"`
Handler string `json:"handler"`
Architectures []Architecture `json:"architectures,omitempty"`
Runtime string `json:"runtime"`
Memory int32 `json:"memory"`
Timeout int32 `json:"timeout"`
Tags map[string]string `json:"tags,omitempty"`
Environments map[string]string `json:"environments,omitempty"`
VPCConfig *VPCConfig `json:"vpcConfig,omitempty"`
Name string `json:"name"`
Role string `json:"role"`
ImageURI string `json:"image"`
S3Bucket string `json:"s3Bucket"`
S3Key string `json:"s3Key"`
S3ObjectVersion string `json:"s3ObjectVersion"`
SourceCode SourceCode `json:"source"`
Handler string `json:"handler"`
Architectures []Architecture `json:"architectures,omitempty"`
EphemeralStorage *EphemeralStorage `json:"ephemeralStorage,omitempty"`
Runtime string `json:"runtime"`
Memory int32 `json:"memory"`
Timeout int32 `json:"timeout"`
Tags map[string]string `json:"tags,omitempty"`
Environments map[string]string `json:"environments,omitempty"`
VPCConfig *VPCConfig `json:"vpcConfig,omitempty"`
}

type VPCConfig struct {
Expand Down Expand Up @@ -100,6 +103,11 @@ func (fmp FunctionManifestSpec) validate() error {
return fmt.Errorf("architecture is invalid: %w", err)
}
}
if fmp.EphemeralStorage != nil {
if err := fmp.EphemeralStorage.validate(); err != nil {
return fmt.Errorf("ephemeral storage is invalid: %w", err)
}
}
if fmp.Role == "" {
return fmt.Errorf("role is missing")
}
Expand Down Expand Up @@ -139,6 +147,17 @@ func (a Architecture) validate() error {
return nil
}

type EphemeralStorage struct {
Size int32 `json:"size,omitempty"`
}

func (es EphemeralStorage) validate() error {
if es.Size < ephemeralStorageLowerLimit || es.Size > ephemeralStorageUpperLimit {
return fmt.Errorf("ephemeral storage is out of range")
}
return nil
}

func loadFunctionManifest(path string) (FunctionManifest, error) {
data, err := os.ReadFile(path)
if err != nil {
Expand Down
49 changes: 49 additions & 0 deletions pkg/app/piped/platformprovider/lambda/function_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,36 @@ func TestParseFunctionManifest(t *testing.T) {
},
wantErr: false,
},
{
name: "correct config for LambdaFunction with specifying ephemeral storage",
data: `{
"apiVersion": "pipecd.dev/v1beta1",
"kind": "LambdaFunction",
"spec": {
"name": "SimpleFunction",
"role": "arn:aws:iam::xxxxx:role/lambda-role",
"memory": 128,
"timeout": 5,
"image": "ecr.region.amazonaws.com/lambda-simple-function:v0.0.1",
"ephemeralStorage": {
size: 512
}
}
}`,
wantSpec: FunctionManifest{
Kind: "LambdaFunction",
APIVersion: "pipecd.dev/v1beta1",
Spec: FunctionManifestSpec{
Name: "SimpleFunction",
Role: "arn:aws:iam::xxxxx:role/lambda-role",
Memory: 128,
Timeout: 5,
ImageURI: "ecr.region.amazonaws.com/lambda-simple-function:v0.0.1",
EphemeralStorage: &EphemeralStorage{Size: 512},
},
},
wantErr: false,
},
{
name: "correct config for LambdaFunction with specifying vpc config",
data: `{
Expand Down Expand Up @@ -170,6 +200,25 @@ func TestParseFunctionManifest(t *testing.T) {
"timeout": 1000,
"image": "ecr.region.amazonaws.com/lambda-simple-function:v0.0.1"
}
}`,
wantSpec: FunctionManifest{},
wantErr: true,
},
{
name: "invalid ephemeral storage value",
data: `{
"apiVersion": "pipecd.dev/v1beta1",
"kind": "LambdaFunction",
"spec": {
"name": "SimpleFunction",
"role": "arn:aws:iam::xxxxx:role/lambda-role",
"memory": 128,
"timeout": 5,
"image": "ecr.region.amazonaws.com/lambda-simple-function:v0.0.1",
"ephemeralStorage": {
size: 511
}
}
}`,
wantSpec: FunctionManifest{},
wantErr: true,
Expand Down
Loading