diff --git a/.changelog/4418.txt b/.changelog/4418.txt new file mode 100644 index 00000000000..01a623897f5 --- /dev/null +++ b/.changelog/4418.txt @@ -0,0 +1,3 @@ +```release-note:improvement +plugin/aws: Add CORS configuration to lambda-function-url releaser +``` diff --git a/builtin/aws/lambda/function_url/releaser.go b/builtin/aws/lambda/function_url/releaser.go index 4e357d4f982..8e4b900ef8e 100644 --- a/builtin/aws/lambda/function_url/releaser.go +++ b/builtin/aws/lambda/function_url/releaser.go @@ -15,14 +15,15 @@ import ( "github.com/aws/aws-sdk-go/service/lambda" validation "github.com/go-ozzo/ozzo-validation/v4" "github.com/hashicorp/go-hclog" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" + "github.com/hashicorp/waypoint-plugin-sdk/component" "github.com/hashicorp/waypoint-plugin-sdk/docs" "github.com/hashicorp/waypoint-plugin-sdk/framework/resource" sdk "github.com/hashicorp/waypoint-plugin-sdk/proto/gen" "github.com/hashicorp/waypoint-plugin-sdk/terminal" "github.com/hashicorp/waypoint/builtin/aws/utils" - "google.golang.org/grpc/codes" - "google.golang.org/grpc/status" ) type Releaser struct { @@ -293,7 +294,19 @@ func (r *Releaser) resourceFunctionUrlCreate( functionUrlAuthType = strings.ToUpper(r.config.AuthType) } - cors := lambda.Cors{} + corsCfg := r.config.Cors + if corsCfg == nil { + corsCfg = &ReleaserConfigCors{} + } + + cors := lambda.Cors{ + AllowCredentials: corsCfg.AllowCredentials, + AllowHeaders: corsCfg.AllowHeaders, + AllowMethods: corsCfg.AllowMethods, + AllowOrigins: corsCfg.AllowOrigins, + ExposeHeaders: corsCfg.ExposeHeaders, + MaxAge: corsCfg.MaxAge, + } step := sg.Add("Creating Lambda URL...") defer step.Abort() @@ -324,7 +337,7 @@ func (r *Releaser) resourceFunctionUrlCreate( return err } else { // compare remote config to incoming config - if functionUrlAuthType != *gfc.AuthType { + if functionUrlAuthType != *gfc.AuthType || !reflect.DeepEqual(&cors, gfc.Cors) { shouldUpdate = true } else { step.Update("Reusing existing Lambda URL: %q", *gfc.FunctionUrl) @@ -424,6 +437,41 @@ type ReleaserConfig struct { AuthType string `hcl:"auth_type,optional"` // Only permitted if AuthType is "AWS_IAM" otherwise defaults to "*" Principal string `hcl:"principal,optional"` + // Configuration options for function url CORS + Cors *ReleaserConfigCors `hcl:"cors,block"` +} + +// Based on the Cors type from the AWS SDK, but with our HCL mappings. +// https://pkg.go.dev/github.com/aws/aws-sdk-go/service/lambda#Cors +type ReleaserConfigCors struct { + // Whether to allow cookies or other credentials in requests to your function + // URL. The default is false. + AllowCredentials *bool `hcl:"allow_credentials,optional"` + + // The HTTP headers that origins can include in requests to your function URL. + // For example: Date, Keep-Alive, X-Custom-Header. + AllowHeaders []*string `hcl:"allow_headers,optional"` + + // The HTTP methods that are allowed when calling your function URL. For example: + // GET, POST, DELETE, or the wildcard character (*). + AllowMethods []*string `hcl:"allow_methods,optional"` + + // The origins that can access your function URL. You can list any number of + // specific origins, separated by a comma. For example: https://www.example.com, + // http://localhost:60905. + // + // Alternatively, you can grant access to all origins using the wildcard character + // (*). + AllowOrigins []*string `hcl:"allow_origins,optional"` + + // The HTTP headers in your function response that you want to expose to origins + // that call your function URL. For example: Date, Keep-Alive, X-Custom-Header. + ExposeHeaders []*string `hcl:"expose_headers,optional"` + + // The maximum amount of time, in seconds, that web browsers can cache results + // of a preflight request. By default, this is set to 0, which means that the + // browser doesn't cache results. + MaxAge *int64 `hcl:"max_age,optional"` } func (r *Releaser) Status( @@ -480,6 +528,9 @@ func (r *Releaser) Documentation() (*docs.Documentation, error) { release { use "lambda-function-url" { auth_type = "NONE" + cors { + allow_methods = ["*"] + } } } `) @@ -505,6 +556,44 @@ release { docs.Default("*"), ) + doc.SetField( + "cors", + "CORS configuration for the function URL", + docs.Default("NONE"), + docs.SubFields(func(d *docs.SubFieldDoc) { + d.SetField( + "allow_credentials", + "Whether to allow cookies or other credentials in requests to your function URL.", + docs.Default("false"), + ) + d.SetField( + "allow_headers", + "The HTTP headers that origins can include in requests to your function URL. For example: Date, Keep-Alive, X-Custom-Header.", + docs.Default("[]"), + ) + d.SetField( + "allow_methods", + "The HTTP methods that are allowed when calling your function URL. For example: GET, POST, DELETE, or the wildcard character (*).", + docs.Default("[]"), + ) + d.SetField( + "allow_origins", + "The origins that can access your function URL. You can list any number of specific origins, separated by a comma. You can grant access to all origins using the wildcard character (*).", + docs.Default("[]"), + ) + d.SetField( + "expose_headers", + "The HTTP headers in your function response that you want to expose to origins that call your function URL. For example: Date, Keep-Alive, X-Custom-Header.", + docs.Default("[]"), + ) + d.SetField( + "max_age", + "The maximum amount of time, in seconds, that web browsers can cache results of a preflight request.", + docs.Default("0"), + ) + }), + ) + return doc, nil } diff --git a/embedJson/gen/releasemanager-lambda-function-url.json b/embedJson/gen/releasemanager-lambda-function-url.json index cfa85f765ec..d18503db8d8 100644 --- a/embedJson/gen/releasemanager-lambda-function-url.json +++ b/embedJson/gen/releasemanager-lambda-function-url.json @@ -1,6 +1,6 @@ { "description": "Create an AWS Lambda function URL", - "example": "release {\n\tuse \"lambda-function-url\" {\n\t\tauth_type = \"NONE\"\n\t}\n}", + "example": "release {\n\tuse \"lambda-function-url\" {\n\t\tauth_type = \"NONE\"\n\t\tcors {\n\t\t\tallow_methods = [\"*\"]\n\t\t}\n\t}\n}", "input": "lambda.Deployment", "mappers": null, "name": "lambda-function-url", @@ -17,6 +17,91 @@ "Example": "", "SubFields": null }, + { + "Field": "cors", + "Type": "function_url.ReleaserConfigCors", + "Synopsis": "CORS configuration for the function URL", + "Summary": "", + "Optional": false, + "Default": "NONE", + "EnvVar": "", + "Category": true, + "Example": "", + "SubFields": [ + { + "Field": "allow_credentials", + "Type": "bool", + "Synopsis": "Whether to allow cookies or other credentials in requests to your function URL.", + "Summary": "", + "Optional": true, + "Default": "false", + "EnvVar": "", + "Category": false, + "Example": "", + "SubFields": null + }, + { + "Field": "allow_headers", + "Type": "list of string", + "Synopsis": "The HTTP headers that origins can include in requests to your function URL. For example: Date, Keep-Alive, X-Custom-Header.", + "Summary": "", + "Optional": true, + "Default": "[]", + "EnvVar": "", + "Category": false, + "Example": "", + "SubFields": null + }, + { + "Field": "allow_methods", + "Type": "list of string", + "Synopsis": "The HTTP methods that are allowed when calling your function URL. For example: GET, POST, DELETE, or the wildcard character (*).", + "Summary": "", + "Optional": true, + "Default": "[]", + "EnvVar": "", + "Category": false, + "Example": "", + "SubFields": null + }, + { + "Field": "allow_origins", + "Type": "list of string", + "Synopsis": "The origins that can access your function URL. You can list any number of specific origins, separated by a comma. You can grant access to all origins using the wildcard character (*).", + "Summary": "", + "Optional": true, + "Default": "[]", + "EnvVar": "", + "Category": false, + "Example": "", + "SubFields": null + }, + { + "Field": "expose_headers", + "Type": "list of string", + "Synopsis": "The HTTP headers in your function response that you want to expose to origins that call your function URL. For example: Date, Keep-Alive, X-Custom-Header.", + "Summary": "", + "Optional": true, + "Default": "[]", + "EnvVar": "", + "Category": false, + "Example": "", + "SubFields": null + }, + { + "Field": "max_age", + "Type": "int64", + "Synopsis": "The maximum amount of time, in seconds, that web browsers can cache results of a preflight request.", + "Summary": "", + "Optional": true, + "Default": "0", + "EnvVar": "", + "Category": false, + "Example": "", + "SubFields": null + } + ] + }, { "Field": "principal", "Type": "string", diff --git a/website/content/partials/components/releasemanager-lambda-function-url.mdx b/website/content/partials/components/releasemanager-lambda-function-url.mdx index c3e4524ddd9..98d936880f0 100644 --- a/website/content/partials/components/releasemanager-lambda-function-url.mdx +++ b/website/content/partials/components/releasemanager-lambda-function-url.mdx @@ -13,6 +13,9 @@ Create an AWS Lambda function URL. release { use "lambda-function-url" { auth_type = "NONE" + cors { + allow_methods = ["*"] + } } } ``` @@ -35,6 +38,58 @@ The AuthType parameter determines how Lambda authenticates or authorizes request - **Optional** - Default: NONE +#### cors (category) + +CORS configuration for the function URL. + +##### cors.allow_credentials + +Whether to allow cookies or other credentials in requests to your function URL. + +- Type: **bool** +- **Optional** +- Default: false + +##### cors.allow_headers + +The HTTP headers that origins can include in requests to your function URL. For example: Date, Keep-Alive, X-Custom-Header. + +- Type: **list of string** +- **Optional** +- Default: [] + +##### cors.allow_methods + +The HTTP methods that are allowed when calling your function URL. For example: GET, POST, DELETE, or the wildcard character (\*). + +- Type: **list of string** +- **Optional** +- Default: [] + +##### cors.allow_origins + +The origins that can access your function URL. You can list any number of specific origins, separated by a comma. You can grant access to all origins using the wildcard character (\*). + +- Type: **list of string** +- **Optional** +- Default: [] + +##### cors.expose_headers + +The HTTP headers in your function response that you want to expose to origins that call your function URL. For example: Date, Keep-Alive, X-Custom-Header. + +- Type: **list of string** +- **Optional** +- Default: [] + +##### cors.max_age + +The maximum amount of time, in seconds, that web browsers can cache results of a preflight request. + +- Type: **int64** +- **Optional** +- Default: 0 + #### principal The principal to use when auth_type is `AWS_IAM`.