Skip to content

Commit

Permalink
New Features for API, Function & SimpleTable # 248, #252, #265
Browse files Browse the repository at this point in the history
* API
  * CORS
  * Regional endpoints
  * Binary media types
  * Logging, Metrics & CacheTTL (MethodSettings)

* Function
  * Per-Function Concurrency (ReservedConcurrentExecutions)

* SimpleTable:
  * Tags
  * TableName

* Refer to resources generated by API:
  * `!Ref MyApi.Stage` => Ref the Stage generated by SAM
  * `!Ref MyApi.Deployment` => Ref the Deployment resource generated by SAM
  • Loading branch information
sanathkr committed Mar 12, 2018
1 parent 9b15248 commit 629ddf2
Show file tree
Hide file tree
Showing 7 changed files with 220 additions and 72 deletions.
60 changes: 49 additions & 11 deletions docs/globals.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ Globals Section

.. contents::

Lambda functions within a SAM template tend to have shared configuration such as Runtime, Memory,
VPC Settings, Environment Variables etc. Instead of duplicating this information in every function, you can
write them once in the ``Globals`` section and let all Functions inhert it.
Resources in a SAM template tend to have shared configuration such as Runtime, Memory,
VPC Settings, Environment Variables, Cors etc. Instead of duplicating this information in every resource, you can
write them once in the ``Globals`` section and let all resources inhert it.

Example:

Expand Down Expand Up @@ -44,23 +44,65 @@ inherited TABLE_NAME. ``ThumbnailFunction`` inherits all the Globals properties

Supported Resources
-------------------
Properties of ``AWS::Serverless::Function`` are only supported in Globals section presently.
Properties of ``AWS::Serverless::Function`` and ``AWS::Serverless::Api`` are only supported in Globals section
presently.

.. code:: yaml
Globals:
Function:
# Properties of AWS::Serverless::Function
Following properties of ``AWS::Serverless::Function`` are **not** supported in Globals section. We made the explicitly
# Some properties of AWS::Serverless::Function
Handler:
Runtime:
CodeUri:
DeadLetterQueue:
Description:
MemorySize:
Timeout:
VpcConfig:
Environment:
Tags:
Tracing:
KmsKeyArn:
AutoPublishAlias:
DeploymentPreference:
Api:
# Some properties of AWS::Serverless::Api
# Also works with Implicit APIs
Name:
DefinitionUri:
CacheClusterEnabled:
CacheClusterSize:
Variables:
EndpointConfiguration:
MethodSettings:
BinaryMediaTypes:
Cors:
Implicit APIs
~~~~~~~~~~~~~

APIs created by SAM when you have an API declared in the ``Events`` section are called "Implicit APIs". You can use
Globals to override all properties of Implicit APIs as well.

Unsupported Properties
~~~~~~~~~~~~~~~~~~~~~~

Following properties of are **not** supported in Globals section. We made the explicitly
call to not support them because it either made the template hard to understand or opens scope for potential security
issues.

**AWS::Serverless::Function:**
* Role
* Policies
* FunctionName
* Events

**AWS::Serverless::Api:**
* StageName
* DefinitionBody

Overridable
-----------

Expand Down Expand Up @@ -148,7 +190,3 @@ SecurityGroupIds of VpcConfig will be set to ``["sg-first", "sg-123", "sg-456"]`
SecurityGroupIds:
- sg-first
10 changes: 9 additions & 1 deletion examples/2016-10-31/api_swagger_cors/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,15 @@ exports.handler = function(event, context, callback) {

callback(null, {
statusCode: '200',
body: "Hello world"
body: "Hello world",
headers: {
// This is ALSO required for CORS to work. When browsers issue cross origin requests, they make a
// preflight request (HTTP Options) which is responded automatically based on SAM configuration.
// But the actual HTTP request (GET/POST etc) also needs to contain the AllowOrigin header.
//
// NOTE: This value is *not* double quoted: ie. "'www.example.com'" is wrong
"Access-Control-Allow-Origin": "https://www.example.com"
}
});

}
58 changes: 0 additions & 58 deletions examples/2016-10-31/api_swagger_cors/swagger.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -26,35 +26,6 @@ paths:
passthroughBehavior: when_no_match
httpMethod: POST
type: aws_proxy
options:
consumes:
- application/json
produces:
- application/json
responses:
'200':
description: 200 response
schema:
$ref: "#/definitions/Empty"
headers:
Access-Control-Allow-Origin:
type: string
Access-Control-Allow-Methods:
type: string
Access-Control-Allow-Headers:
type: string
x-amazon-apigateway-integration:
responses:
default:
statusCode: 200
responseParameters:
method.response.header.Access-Control-Allow-Methods: "'DELETE,GET,HEAD,OPTIONS,PATCH,POST,PUT'"
method.response.header.Access-Control-Allow-Headers: "'Content-Type,Authorization,X-Amz-Date,X-Api-Key,X-Amz-Security-Token'"
method.response.header.Access-Control-Allow-Origin: "'*'"
passthroughBehavior: when_no_match
requestTemplates:
application/json: "{\"statusCode\": 200}"
type: mock
/{proxy+}:
x-amazon-apigateway-any-method:
x-amazon-apigateway-auth:
Expand All @@ -72,35 +43,6 @@ paths:
Fn::Sub: "arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${LambdaFunction.Arn}/invocations"
httpMethod: POST
type: aws_proxy
options:
consumes:
- application/json
produces:
- application/json
responses:
'200':
description: 200 response
schema:
$ref: "#/definitions/Empty"
headers:
Access-Control-Allow-Origin:
type: string
Access-Control-Allow-Methods:
type: string
Access-Control-Allow-Headers:
type: string
x-amazon-apigateway-integration:
responses:
default:
statusCode: 200
responseParameters:
method.response.header.Access-Control-Allow-Methods: "'DELETE,GET,HEAD,OPTIONS,PATCH,POST,PUT'"
method.response.header.Access-Control-Allow-Headers: "'Content-Type,Authorization,X-Amz-Date,X-Api-Key,X-Amz-Security-Token'"
method.response.header.Access-Control-Allow-Origin: "'*'"
passthroughBehavior: when_no_match
requestTemplates:
application/json: "{\"statusCode\": 200}"
type: mock
definitions:
Empty:
type: object
Expand Down
5 changes: 5 additions & 0 deletions examples/2016-10-31/api_swagger_cors/template.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@ Resources:
Type: AWS::Serverless::Api
Properties:
StageName: Prod

# Allows www.example.com to call these APIs
# SAM will automatically add AllowMethods with a list of methods for this API
Cors: "'www.example.com'"

DefinitionBody:
'Fn::Transform':
Name: 'AWS::Include'
Expand Down
22 changes: 22 additions & 0 deletions examples/2016-10-31/implicit_api_settings/index.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

90 changes: 90 additions & 0 deletions examples/2016-10-31/implicit_api_settings/template.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
---
Transform: AWS::Serverless-2016-10-31

Globals:
Api:
# Allows www.example.com to call these APIs
# SAM will automatically add AllowMethods with a list of methods for this API
Cors: "'https://www.www.example.com'"

# API Gateway regional endpoints
EndpointConfiguration: REGIONAL

# Send/receive binary data through the APIs
BinaryMediaTypes:
# This is equivalent to image/gif when deployed
- image~1gif
- iimage~1png

# Logging, Metrics, Throttling, and all other Stage settings
MethodSettings: [{
# Turn on Info logging
"LoggingLevel": "INFO",

# Enable Metrics
"MetricsEnabled": True,

# Trace-level Logging
"DataTraceEnabled": True,

# On all Paths & methods
"ResourcePath": "/*",
"HttpMethod": "*",
}]

Resources:
LambdaFunction:
Type: AWS::Serverless::Function
Properties:
# Replace <bucket> with your bucket name
CodeUri: s3://<bucket>/code.zip
Handler: index.handler
Runtime: nodejs6.10
Events:
ProxyApiRoot:
Type: Api
Properties:
Path: /
Method: ANY
ProxyApiGreedy:
Type: Api
Properties:
Path: /{proxy+}
Method: ANY

####### Necessary for API Gateway Logging ########
# Add the CloudWatchRole and Account resource to your template to give API Gateway permissions write to CloudWatch logs
# https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-apigateway-account.html#aws-resource-apigateway-account-examples
#
# NOTE: This is a one time process. As long as you have this enabled once in a region, you can deploy other stacks
# without the need for each stack to create this role. As a good practice, create a separate stack altogether
# with just the API Gateway logging role so none of your application stacks need them.
ApiGwAccountConfig:
Type: "AWS::ApiGateway::Account"
Properties:
CloudWatchRoleArn: !GetAtt "ApiGatewayLoggingRole.Arn"
ApiGatewayLoggingRole:
Type: "AWS::IAM::Role"
Properties:
AssumeRolePolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Principal:
Service:
- "apigateway.amazonaws.com"
Action: "sts:AssumeRole"
Path: "/"
ManagedPolicyArns:
- !Sub "arn:${AWS::Partition}:iam::aws:policy/service-role/AmazonAPIGatewayPushToCloudWatchLogs"

Outputs:
ApiUrl:
Description: URL of your API endpoint
Value: !Join
- ''
- - https://
- !Ref ServerlessRestApi
- '.execute-api.'
- !Ref 'AWS::Region'
- '.amazonaws.com/Prod'
Loading

0 comments on commit 629ddf2

Please sign in to comment.