Skip to content

Commit cccb0c9

Browse files
authored
chore: merge pull request #898 from awslabs/release/v1.11.0
chore: merge release/v1.11.0 into master
2 parents 62d69cb + f7969bf commit cccb0c9

File tree

116 files changed

+8493
-289
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

116 files changed

+8493
-289
lines changed

HOWTO.md

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,15 @@ resources for you.
1414
The remainder of this document explains how to write SAM templates and
1515
deploy them via AWS CloudFormation.
1616

17-
## Writing SAM Template
17+
## Getting started with the SAM Template
1818
Check out the [latest specification](versions/2016-10-31.md) for details on how to write a SAM template
1919

20+
21+
You could also use the [aws-sam-cli](https://github.com/awslabs/aws-sam-cli) to get started
22+
23+
```shell
24+
$ sam init --runtime python3.7
25+
```
2026
## Packing Artifacts
2127
Before you can deploy a SAM template, you should first upload your Lambda
2228
function code zip and API's OpenAPI File to S3. Set the `CodeUri` and
@@ -47,9 +53,22 @@ packaged template that can be readily deployed to CloudFormation.
4753
$ aws cloudformation package \
4854
--template-file /path_to_template/template.yaml \
4955
--s3-bucket bucket-name \
56+
--s3-prefix appname/branchname/version
57+
--output-template-file packaged-template.yaml
58+
```
59+
60+
Or using the aws-sam-cli
61+
62+
```bash
63+
$ sam package \
64+
--template-file /path_to_template/template.yaml \
65+
--s3-bucket bucket-name \
66+
--s3-prefix appname/branchname/version
5067
--output-template-file packaged-template.yaml
5168
```
5269

70+
71+
5372
The packaged template will look something like this:
5473
```YAML
5574
MyLambdaFunction:
@@ -80,7 +99,16 @@ $ aws cloudformation deploy \
8099
--capabilities CAPABILITY_IAM
81100
```
82101

83-
Refer to the [documentation](http://docs.aws.amazon.com/cli/latest/reference/cloudformation/deploy/index.html) for more details.
102+
Or using aws-sam-cli
103+
104+
```bash
105+
$ sam deploy \
106+
--template-file /path_to_template/packaged-template.yaml \
107+
--stack-name my-new-stack
108+
--capabilities CAPABILITY_IAM
109+
```
110+
111+
Refer to the [cloudformation documentation](http://docs.aws.amazon.com/cli/latest/reference/cloudformation/deploy/index.html) and [samcli](https://github.com/awslabs/aws-sam-cli) for more details.
84112

85113
## Using Intrinsic Functions
86114
CloudFormation provides handy functions that you can use to generate values at runtime. These are called [Intrinsic Functions](http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference.html). Since SAM is deployed using CloudFormation, you can use these intrinsic functions within SAM as well. Here are some examples:

bin/sam-translate.py

Lines changed: 87 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,42 +5,91 @@
55
Known limitations: cannot transform CodeUri pointing at local directory.
66
77
Usage:
8-
sam-translate.py --input-file=sam-template.yaml [--output-file=<o>]
8+
sam-translate.py --template-file=sam-template.yaml [--verbose] [--output-template=<o>]
9+
sam-translate.py package --template-file=sam-template.yaml --s3-bucket=my-bucket [--verbose] [--output-template=<o>]
10+
sam-translate.py deploy --template-file=sam-template.yaml --s3-bucket=my-bucket --capabilities=CAPABILITY_NAMED_IAM --stack-name=my-stack [--verbose] [--output-template=<o>]
911
1012
Options:
11-
--input-file=<i> Location of SAM template to transform.
12-
--output-file=<o> Location to store resulting CloudFormation template [default: cfn-template.json].
13+
--template-file=<i> Location of SAM template to transform [default: template.yaml].
14+
--output-template=<o> Location to store resulting CloudFormation template [default: transformed-template.json].
15+
--s3-bucket=<s> S3 bucket to use for SAM artifacts when using the `package` command
16+
--capabilities=<c> Capabilities
17+
--stack-name=<n> Unique name for your CloudFormation Stack
18+
--verbose Enables verbose logging
1319
1420
"""
1521
import json
22+
import logging
1623
import os
24+
import platform
25+
import subprocess
26+
import sys
1727

1828
import boto3
1929
from docopt import docopt
2030

31+
my_path = os.path.dirname(os.path.abspath(__file__))
32+
sys.path.insert(0, my_path + '/..')
33+
2134
from samtranslator.public.translator import ManagedPolicyLoader
2235
from samtranslator.translator.transform import transform
2336
from samtranslator.yaml_helper import yaml_parse
2437
from samtranslator.model.exceptions import InvalidDocumentException
2538

26-
39+
LOG = logging.getLogger(__name__)
2740
cli_options = docopt(__doc__)
2841
iam_client = boto3.client('iam')
2942
cwd = os.getcwd()
3043

44+
if cli_options.get('--verbose'):
45+
logging.basicConfig(level=logging.DEBUG)
46+
else:
47+
logging.basicConfig()
48+
49+
def execute_command(command, args):
50+
try:
51+
aws_cmd = 'aws' if platform.system().lower() != 'windows' else 'aws.cmd'
52+
command_with_args = [aws_cmd, 'cloudformation', command] + list(args)
53+
54+
LOG.debug("Executing command: %s", command_with_args)
55+
56+
subprocess.check_call(command_with_args)
57+
58+
LOG.debug("Command successful")
59+
except subprocess.CalledProcessError as e:
60+
# Underlying aws command will print the exception to the user
61+
LOG.debug("Exception: %s", e)
62+
sys.exit(e.returncode)
63+
3164

3265
def get_input_output_file_paths():
33-
input_file_option = cli_options.get('--input-file')
34-
output_file_option = cli_options.get('--output-file')
66+
input_file_option = cli_options.get('--template-file')
67+
output_file_option = cli_options.get('--output-template')
3568
input_file_path = os.path.join(cwd, input_file_option)
3669
output_file_path = os.path.join(cwd, output_file_option)
3770

3871
return input_file_path, output_file_path
3972

4073

41-
def main():
42-
input_file_path, output_file_path = get_input_output_file_paths()
74+
def package(input_file_path, output_file_path):
75+
template_file = input_file_path
76+
package_output_template_file = input_file_path + '._sam_packaged_.yaml'
77+
s3_bucket = cli_options.get('--s3-bucket')
78+
args = [
79+
'--template-file',
80+
template_file,
81+
'--output-template-file',
82+
package_output_template_file,
83+
'--s3-bucket',
84+
s3_bucket
85+
]
4386

87+
execute_command('package', args)
88+
89+
return package_output_template_file
90+
91+
92+
def transform_template(input_file_path, output_file_path):
4493
with open(input_file_path, 'r') as f:
4594
sam_template = yaml_parse(f)
4695

@@ -56,10 +105,37 @@ def main():
56105
print('Wrote transformed CloudFormation template to: ' + output_file_path)
57106
except InvalidDocumentException as e:
58107
errorMessage = reduce(lambda message, error: message + ' ' + error.message, e.causes, e.message)
59-
print(errorMessage)
108+
LOG.error(errorMessage)
60109
errors = map(lambda cause: cause.message, e.causes)
61-
print(errors)
110+
LOG.error(errors)
111+
112+
113+
def deploy(template_file):
114+
capabilities = cli_options.get('--capabilities')
115+
stack_name = cli_options.get('--stack-name')
116+
args = [
117+
'--template-file',
118+
template_file,
119+
'--capabilities',
120+
capabilities,
121+
'--stack-name',
122+
stack_name
123+
]
124+
125+
execute_command('deploy', args)
126+
127+
return package_output_template_file
62128

63129

64130
if __name__ == '__main__':
65-
main()
131+
input_file_path, output_file_path = get_input_output_file_paths()
132+
133+
if cli_options.get('package'):
134+
package_output_template_file = package(input_file_path, output_file_path)
135+
transform_template(package_output_template_file, output_file_path)
136+
elif cli_options.get('deploy'):
137+
package_output_template_file = package(input_file_path, output_file_path)
138+
transform_template(package_output_template_file, output_file_path)
139+
deploy(output_file_path)
140+
else:
141+
transform_template(input_file_path, output_file_path)

docs/globals.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ Currently, the following resources and properties are being supported:
6868
AutoPublishAlias:
6969
DeploymentPreference:
7070
PermissionsBoundary:
71+
ReservedConcurrentExecutions:
7172
7273
Api:
7374
# Properties of AWS::Serverless::Api
@@ -82,6 +83,7 @@ Currently, the following resources and properties are being supported:
8283
BinaryMediaTypes:
8384
MinimumCompressionSize:
8485
Cors:
86+
GatewayResponses:
8587
AccessLogSetting:
8688
CanarySetting:
8789
TracingEnabled:

docs/safe_lambda_deployments.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,7 @@ resource:
156156
Action:
157157
- "codedeploy:PutLifecycleEventHookExecutionStatus"
158158
Resource:
159-
!Sub 'arn:aws:codedeploy:${AWS::Region}:${AWS::AccountId}:deploymentgroup:${ServerlessDeploymentApplication}/*'
159+
!Sub 'arn:${AWS::Partition}:codedeploy:${AWS::Region}:${AWS::AccountId}:deploymentgroup:${ServerlessDeploymentApplication}/*'
160160
- Version: "2012-10-17"
161161
Statement:
162162
- Effect: "Allow"
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
exports.handler = async (event) => {
2+
return {
3+
statusCode: 200,
4+
body: JSON.stringify(event),
5+
headers: {}
6+
}
7+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
AWSTemplateFormatVersion: '2010-09-09'
2+
Transform: AWS::Serverless-2016-10-31
3+
Description: API Gateway with AWS IAM Authorizer
4+
Resources:
5+
MyApi:
6+
Type: AWS::Serverless::Api
7+
Properties:
8+
StageName: Prod
9+
Auth:
10+
DefaultAuthorizer: AWS_IAM
11+
InvokeRole: CALLER_CREDENTIALS
12+
13+
MyFunction:
14+
Type: AWS::Serverless::Function
15+
Properties:
16+
CodeUri: .
17+
Handler: index.handler
18+
Runtime: nodejs8.10
19+
Events:
20+
GetRoot:
21+
Type: Api
22+
Properties:
23+
RestApiId: !Ref MyApi
24+
Path: /
25+
Method: get
26+
27+
Outputs:
28+
ApiURL:
29+
Description: "API URL"
30+
Value: !Sub 'https://${MyApi}.execute-api.${AWS::Region}.amazonaws.com/Prod/'

examples/2016-10-31/api_cognito_auth/template.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ Resources:
131131
Action: lambda:InvokeFunction
132132
FunctionName: !GetAtt PreSignupLambdaFunction.Arn
133133
Principal: cognito-idp.amazonaws.com
134-
SourceArn: !Sub 'arn:aws:cognito-idp:${AWS::Region}:${AWS::AccountId}:userpool/${MyCognitoUserPool}'
134+
SourceArn: !Sub 'arn:${AWS::Partition}:cognito-idp:${AWS::Region}:${AWS::AccountId}:userpool/${MyCognitoUserPool}'
135135
# TODO: Add a CognitoUserPool Event Source to SAM to create this permission for you.
136136
# Events:
137137
# CognitoUserPoolPreSignup:
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
AWSTemplateFormatVersion: "2010-09-09"
2+
Transform: AWS::Serverless-2016-10-31
3+
Description: Simple webservice deomnstrating gateway responses.
4+
5+
Resources:
6+
MyApi:
7+
Type: AWS::Serverless::Api
8+
Properties:
9+
StageName: Prod
10+
GatewayResponses:
11+
DEFAULT_4xx:
12+
ResponseParameters:
13+
Headers:
14+
Access-Control-Expose-Headers: "'WWW-Authenticate'"
15+
Access-Control-Allow-Origin: "'*'"
16+
17+
GetFunction:
18+
Type: AWS::Serverless::Function
19+
Properties:
20+
Handler: index.get
21+
Runtime: nodejs6.10
22+
InlineCode: module.exports = async () => throw new Error('Check out the response headers!')
23+
Events:
24+
GetResource:
25+
Type: Api
26+
Properties:
27+
Path: /error
28+
Method: get
29+
RestApiId: !Ref MyApi
30+
Outputs:
31+
ApiURL:
32+
Description: "API endpoint URL for Prod environment"
33+
Value: !Sub "https://${MyApi}.execute-api.${AWS::Region}.amazonaws.com/Prod/error/"

examples/2016-10-31/inline_swagger/template.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ Resources:
1818
httpMethod: POST
1919
type: aws_proxy
2020
uri:
21-
Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${MyLambdaFunction.Arn}/invocations
21+
Fn::Sub: arn:${AWS::Partition}:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${MyLambdaFunction.Arn}/invocations
2222
responses: {}
2323

2424

examples/2016-10-31/lambda_safe_deployments/template.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ Resources:
2828
Action:
2929
- "codedeploy:PutLifecycleEventHookExecutionStatus"
3030
Resource:
31-
!Sub 'arn:aws:codedeploy:${AWS::Region}:${AWS::AccountId}:deploymentgroup:${ServerlessDeploymentApplication}/*'
31+
!Sub 'arn:${AWS::Partition}:codedeploy:${AWS::Region}:${AWS::AccountId}:deploymentgroup:${ServerlessDeploymentApplication}/*'
3232
- Version: "2012-10-17"
3333
Statement:
3434
- Effect: "Allow"

0 commit comments

Comments
 (0)