aws-sam-cli
aws-sam-cli copied to clipboard
BUG: HttpApiCorsConfiguration AllowOrigins does not support CommaDelimitedList parameter locally
Description:
I've just hit this as well but spotted a slightly different behavior between cloudformation and SAM.
The following will not work when run via SAM locally
Parameters:
GatewayCorsOrigins:
Type: CommaDelimitedList
Default: []
Resources:
ApiGatewayApi:
Type: AWS::Serverless::HttpApi
Properties:
CorsConfiguration:
AllowMethods:
- OPTIONS
- GET
- POST
AllowOrigins: !Ref GatewayCorsOrigins
AllowHeaders:
- Authorization
The logs output CORS Property AllowOrigins was not fully resolved. Will proceed as if the Property was not defined.
However, if I change AllowOrigins: !Ref GatewayCorsOrigins
for:
AllowOrigins:
- !Ref GatewayCorsOrigins
Then SAM local will work with the CORs configuration BUT CloudFormation will not deploy anything.
Steps to reproduce:
Create a template file with a parameter defining the cors origins like so:
Parameters:
GatewayCorsOrigins:
Type: CommaDelimitedList
Default: []
Resources:
ApiGatewayApi:
Type: AWS::Serverless::HttpApi
Properties:
CorsConfiguration:
AllowMethods:
- OPTIONS
- GET
- POST
AllowOrigins: !Ref GatewayCorsOrigins
AllowHeaders:
- Authorization
Observed result:
CORs does not work locally: CORS Property AllowOrigins was not fully resolved. Will proceed as if the Property was not defined.
Expected result:
CORs would work for the defined origins.
Additional environment details (Ex: Windows, Mac, Amazon Linux etc)
- OS: Linux - Fedora
-
sam --version
: SAM CLI, version 1.50.0 - AWS region: N/A
NOTE: This may be similar to #3719 but I raised a separate issue in case the use of parameters was the issue I'm facing vs support for multiple origins.
Thanks for reporting this issue. I've tried to re-produce it with following template & function.
template
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Globals:
Function:
Timeout: 3
Parameters:
GatewayCorsOrigins:
Type: CommaDelimitedList
Default: []
Resources:
HelloWorldFunction:
Type: AWS::Serverless::Function
Properties:
CodeUri: hello_world/
Handler: app.lambda_handler
Runtime: python3.9
Events:
HelloWorld:
Type: HttpApi
Properties:
ApiId: ApiGatewayApi
Path: /hello
Method: get
ApiGatewayApi:
Type: AWS::Serverless::HttpApi
Properties:
CorsConfiguration:
AllowMethods:
- OPTIONS
- GET
- POST
AllowOrigins: !Ref GatewayCorsOrigins
AllowHeaders:
- Authorization
function code:
import json
def lambda_handler(event, context):
return {
"statusCode": 200,
"body": json.dumps({
"message": "hello world",
}),
}
And after running sam local start-api
I am making the following curl
call and I am getting following result;
curl 'http://localhost:3000/hello' -X 'OPTIONS' -i
HTTP/1.0 200 OK
Access-Control-Allow-Origin:
Access-Control-Allow-Methods: GET,OPTIONS,POST
Access-Control-Allow-Headers: Authorization
Content-Length: 0
Server: Werkzeug/1.0.1 Python/3.8.13
Date: Thu, 07 Jul 2022 14:32:03 GMT
If I update default values for GatewayCorsOrigins
I am getting list of origins in the header above.
Please let me know if I am missing something here.
Thanks!
The only different I can imagine is that I'm using golang instead of python, but I wouldn't expect that to make a different to the gateway and CORs
That shouldn't make a difference, what is the response you got when you try to invoke it locally?
Closing as it's most likely that I'm holding sam cli wrong.
Running into this still.
Template:
Resources:
ApiGatewayApi:
Type: AWS::Serverless::HttpApi
Properties:
StageName: "example-stage"
CorsConfiguration:
AllowMethods:
- OPTIONS
- GET
- POST
AllowOrigins: !Ref GatewayCorsOrigins
AllowHeaders:
- Authorization
cURL response:
curl 'http://localhost:3001/hello' -X 'OPTIONS' -i
HTTP/1.0 200 OK
Access-Control-Allow-Methods: GET,OPTIONS,POST
Access-Control-Allow-Headers: Authorization
Content-Length: 0
Server: Werkzeug/1.0.1 Python/3.7.10
Date: Fri, 22 Jul 2022 17:26:30 GMT
The main difference in curl output between https://github.com/aws/aws-sam-cli/issues/4026#issuecomment-1177717814 and mine is Access-Control-Allow-Origin:
is not returned in my output.
I can replicate the Access-Control-Allow-Origin:
response if I don't include GatewayCorsOrigins
parameter in the parameter overrides flag.
If I include --parameter-overrides="GatewayCorsOrigins='http://localhost:3000'
, then I get the behavior I originally described of no Access-Control-Allow-Origin
header and the message CORS Property AllowOrigins was not fully resolved. Will proceed as if the Property was not defined.
in the sam logs.
Changing the AllowOrigins:
value will fix this but break the deployment.
https://github.com/gauntface/aws-cli-cors-issue is an reduced case of what I'm trying to do.
If you run make serverdefault
you'll get the empty Access Control Allow Origin header, if you run make serverparams
you'll not get the header.
It seems like this may be a flag parsing issue, but I'm not sure how to debug this (i.e. can sam print the final values it uses)?
I'm having this issue as well.
sam --version
SAM CLI, version 1.110.0
I think CommaDelimitedList
combined with !Ref
should transform a strings for instance "http://domain1, http://domain2"
into ["http://domain1", "http://domain2"]
. This doesn't work using sam local start-api
.
https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/parameters-section-structure.html#parameters-section-structure-properties
CommaDelimitedList An array of literal strings that are separated by commas. The total number of strings should be one more than the total number of commas. Also, each member string is space trimmed.
For example, users could specify "test,dev,prod", and a Ref would result in ["test","dev","prod"].
Therefor the error CORS Property AllowOrigins was not fully resolved. Will proceed as if the Property was not defined.
shows up. This more or less blocks me on local development because I'm dependent on CORS. If I deploy this it works as intended.
It's pretty easy to reproduce:
# Simple "sam init"
# Output: https://app.warp.dev/block/j5SwgAAQCg2bv9GN7uJAxP
> git clone [email protected]:EloB/aws-sam-cli-command.git
> cd aws-sam-cli-command/
> sam local start-api
Initializing the lambda functions containers.
Local image is up-to-date
Using local image: public.ecr.aws/lambda/nodejs:18-rapid-x86_64.
Mounting /Users/ollebroms/Documents/sam-app/hello-world as /var/task:ro,delegated, inside runtime container
Containers Initialization is done.
CORS Property AllowOrigins was not fully resolved. Will proceed as if the Property was not defined.
# ...
Attempt 1, failed using parameters
> sam local start-api --parameter-overrides CorsAllowedOrigins="https://www.google.com"
Initializing the lambda functions containers.
Local image is up-to-date
Using local image: public.ecr.aws/lambda/nodejs:18-rapid-x86_64.
Mounting /Users/ollebroms/Documents/sam-app/hello-world as /var/task:ro,delegated, inside runtime container
Containers Initialization is done.
CORS Property AllowOrigins was not fully resolved. Will proceed as if the Property was not defined.
# ...
Attempt 2, failed using default value as string
Goto template.yaml file and uncomment Default: "https://www.google.com"
or run provided git patch.
> git apply <<EOF
diff --git a/template.yaml b/template.yaml
index aeaa32a..ea43120 100644
--- a/template.yaml
+++ b/template.yaml
@@ -9,7 +9,7 @@ Parameters:
CorsAllowedOrigins:
Type: CommaDelimitedList
# Uncomment the following to set the default value. Then rerun sam local start-api.
- # Default: "https://www.google.com"
+ Default: "https://www.google.com"
# Default: ["https://www.google.com"]
Description: The list of allowed origins for CORS
EOF
> sam local start-api
Initializing the lambda functions containers.
Local image is up-to-date
Using local image: public.ecr.aws/lambda/nodejs:18-rapid-x86_64.
Mounting /Users/ollebroms/Documents/sam-app/hello-world as /var/task:ro,delegated, inside runtime container
Containers Initialization is done.
CORS Property AllowOrigins was not fully resolved. Will proceed as if the Property was not defined.
# ...
Attempt 3, works when providing default as array of strings
Goto template.yaml file and uncomment Default: ["https://www.google.com"]
or run provided script.
I think this indicates that sam local start-api
isn't transforming that !Ref
correctly. According to the json schema for Cloudformation this shouldn't be allowed to enter but it makes the CORS to work.
> git checkout -- .
> git apply <<EOF
diff --git a/template.yaml b/template.yaml
index aeaa32a..af8d0b8 100644
--- a/template.yaml
+++ b/template.yaml
@@ -10,7 +10,7 @@ Parameters:
Type: CommaDelimitedList
# Uncomment the following to set the default value. Then rerun sam local start-api.
# Default: "https://www.google.com"
- # Default: ["https://www.google.com"]
+ Default: ["https://www.google.com"]
Description: The list of allowed origins for CORS
# More info about Globals: https://github.com/awslabs/serverless-application-model/blob/master/docs/globals.rst
EOF
# Also build if you want to be able to fetch. Don't forget to remove folder between attempts.
> sam local start-api
Initializing the lambda functions containers.
Local image is up-to-date
Using local image: public.ecr.aws/lambda/nodejs:18-rapid-x86_64.
Mounting /Users/ollebroms/Documents/sam-app/hello-world as /var/task:ro,delegated, inside runtime container
Containers Initialization is done.
Mounting HelloWorldFunction at http://127.0.0.1:3000/hello [GET, OPTIONS]
# ...
@jfuss @mildaniel I've made some testing regarding this. Any comments on my comment above? I'm a bit worried about this being stale for 2 years.
Any Python developer who can help with my PR to fix this above? I have little to none experience with Python. I'm a JavaScript/TypeScript developer.