Skip to content

Commit a3a6d52

Browse files
authored
chore: merge develop to master (aws#488)
2 parents 870bdd3 + 11ca9d1 commit a3a6d52

File tree

94 files changed

+7430
-672
lines changed

Some content is hidden

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

94 files changed

+7430
-672
lines changed

DESIGN.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,11 @@
1+
# Overview
2+
3+
SAM is called by the CloudFormation Service. CloudFormation recognises the `Transform: AWS::Serverless-2016-10-31` header and invokes the SAM translator. This will then take your SAM template and expand it
4+
into a full fledged CloudFormation Template. The CloudFormation Template that is produced from SAM is the template that is executed by CloudFormation to create/update/delete AWS resources.
5+
6+
The entry point for SAM starts in the Translator class [here](https://github.com/awslabs/serverless-application-model/blob/develop/samtranslator/translator/translator.py#L29), where SAM iterates through the
7+
template and acts on `AWS::Serverless::*` Type Resources.
8+
19
# Design decisions
210

311
Document design decisions here.

DEVELOPMENT_GUIDE.rst

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,4 +71,14 @@ Tests are also a documentation of the success and failure cases, which is crucia
7171
.. _excellent cheatsheet: http://python-future.org/compatible_idioms.html
7272
.. _pyenv: https://github.com/pyenv/pyenv
7373
.. _tox: http://tox.readthedocs.io/en/latest/
74-
.. _installation instructions: https://github.com/pyenv/pyenv#installation
74+
.. _installation instructions: https://github.com/pyenv/pyenv#installation
75+
76+
Profiling
77+
---------
78+
79+
Install snakeviz `pip install snakeviz`
80+
81+
```
82+
python -m cProfile -o sam_profile_results bin/sam-translate.py translate --input-file=tests/translator/input/alexa_skill.yaml --output-file=cfn-template.json
83+
snakeviz sam_profile_results
84+
```

bin/sam-translate.py

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
#!/usr/bin/env python2
2+
3+
"""Convert SAM templates to CloudFormation templates.
4+
5+
Known limitations: cannot transform CodeUri pointing at local directory.
6+
7+
Usage:
8+
sam-translate.py --input-file=sam-template.yaml [--output-file=<o>]
9+
10+
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+
14+
"""
15+
import json
16+
import os
17+
18+
import boto3
19+
from docopt import docopt
20+
21+
from samtranslator.public.translator import ManagedPolicyLoader
22+
from samtranslator.translator.transform import transform
23+
from samtranslator.yaml_helper import yaml_parse
24+
25+
cli_options = docopt(__doc__)
26+
iam_client = boto3.client('iam')
27+
cwd = os.getcwd()
28+
29+
30+
def get_input_output_file_paths():
31+
input_file_option = cli_options.get('--input-file')
32+
output_file_option = cli_options.get('--output-file')
33+
input_file_path = os.path.join(cwd, input_file_option)
34+
output_file_path = os.path.join(cwd, output_file_option)
35+
36+
return input_file_path, output_file_path
37+
38+
39+
def main():
40+
input_file_path, output_file_path = get_input_output_file_paths()
41+
42+
with open(input_file_path, 'r') as f:
43+
sam_template = yaml_parse(f)
44+
45+
cloud_formation_template = transform(
46+
sam_template, {}, ManagedPolicyLoader(iam_client))
47+
cloud_formation_template_prettified = json.dumps(
48+
cloud_formation_template, indent=2)
49+
50+
with open(output_file_path, 'w') as f:
51+
f.write(cloud_formation_template_prettified)
52+
53+
print('Wrote transformed CloudFormation template to: ' + output_file_path)
54+
55+
56+
if __name__ == '__main__':
57+
main()

docs/cloudformation_compatibility.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ Kinesis
9191
Property Name Intrinsic(s) Supported Reasons
9292
======================== ================================== ========================
9393
Stream All
94+
Queue All
9495
StartingPosition All
9596
BatchSize All
9697
======================== ================================== ========================
@@ -103,6 +104,7 @@ DynamoDB
103104
Stream All
104105
StartingPosition All
105106
BatchSize All
107+
SSESpecification All
106108
======================== ================================== ========================
107109

108110
Api

docs/globals.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,9 @@ presently.
8080
BinaryMediaTypes:
8181
Cors:
8282
83+
SimpleTable:
84+
SSESpecification
85+
8386
Implicit APIs
8487
~~~~~~~~~~~~~
8588

docs/internals/generated_resources.rst

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,33 @@ AWS::Lambda::Permissions MyFunction\ **MyTrigger**\ Permission
220220
AWS::Lambda::EventSourceMapping MyFunction\ **MyTrigger**
221221
================================== ================================
222222

223+
SQS
224+
^^^^^^^
225+
226+
Example:
227+
228+
.. code:: yaml
229+
230+
MyFunction:
231+
Type: AWS::Serverless::Function
232+
Properties:
233+
...
234+
Events:
235+
MyTrigger:
236+
Type: SQS
237+
Properties:
238+
Queue: arn:aws:sqs:us-east-1:123456789012:my-queue
239+
...
240+
241+
Additional generated resources:
242+
243+
================================== ================================
244+
CloudFormation Resource Type Logical ID
245+
================================== ================================
246+
AWS::Lambda::Permissions MyFunction\ **MyTrigger**\ Permission
247+
AWS::Lambda::EventSourceMapping MyFunction\ **MyTrigger**
248+
================================== ================================
249+
223250
DynamoDb
224251
^^^^^^^^
225252

docs/policy_templates_data/policy_templates.json

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1132,6 +1132,113 @@
11321132
"Resource": "*"
11331133
}]
11341134
}
1135+
},
1136+
"MobileAnalyticsWriteOnlyAccessPolicy": {
1137+
"Description": "Gives write only permissions to put event data for all application resources",
1138+
"Parameters": {},
1139+
"Definition": {
1140+
"Statement": [
1141+
{
1142+
"Effect": "Allow",
1143+
"Action": [
1144+
"mobileanalytics:PutEvents"
1145+
],
1146+
"Resource": "*"
1147+
}
1148+
]
1149+
}
1150+
},
1151+
"PinpointEndpointAccessPolicy": {
1152+
"Description": "Gives permissions to get and update endpoints for a Pinpoint application",
1153+
"Parameters": {
1154+
"PinpointApplicationId": {
1155+
"Description": "The id of your Pinpoint application"
1156+
}
1157+
},
1158+
"Definition": {
1159+
"Statement": [
1160+
{
1161+
"Effect": "Allow",
1162+
"Action": [
1163+
"mobiletargeting:GetEndpoint",
1164+
"mobiletargeting:UpdateEndpoint",
1165+
"mobiletargeting:UpdateEndpointsBatch"
1166+
],
1167+
"Resource": {
1168+
"Fn::Sub": [
1169+
"arn:${AWS::Partition}:mobiletargeting:${AWS::Region}:${AWS::AccountId}:apps/${pinpointApplicationId}/endpoints/*",
1170+
{
1171+
"pinpointApplicationId": {
1172+
"Ref": "PinpointApplicationId"
1173+
}
1174+
}
1175+
]
1176+
}
1177+
}
1178+
]
1179+
}
1180+
},
1181+
"FirehoseWritePolicy": {
1182+
"Description": "Gives permission to write to a Kinesis Firehose Delivery Stream",
1183+
"Parameters": {
1184+
"DeliveryStreamName": {
1185+
"Description": "Name of Kinesis Firehose Delivery Stream"
1186+
}
1187+
},
1188+
"Definition": {
1189+
"Statement": [
1190+
{
1191+
"Effect": "Allow",
1192+
"Action": [
1193+
"firehose:PutRecord",
1194+
"firehose:PutRecordBatch"
1195+
],
1196+
"Resource": {
1197+
"Fn::Sub": [
1198+
"arn:${AWS::Partition}:firehose:${AWS::Region}:${AWS::AccountId}:deliverystream/${deliveryStreamName}",
1199+
{
1200+
"deliveryStreamName": {
1201+
"Ref": "DeliveryStreamName"
1202+
}
1203+
}
1204+
]
1205+
}
1206+
}
1207+
]
1208+
}
1209+
},
1210+
"FirehoseCrudPolicy": {
1211+
"Description": "Gives permission to create, write to, update, and delete a Kinesis Firehose Delivery Stream",
1212+
"Parameters": {
1213+
"DeliveryStreamName": {
1214+
"Description": "Name of Kinesis Firehose Delivery Stream"
1215+
}
1216+
},
1217+
"Definition": {
1218+
"Statement": [
1219+
{
1220+
"Effect": "Allow",
1221+
"Action": [
1222+
"firehose:CreateDeliveryStream",
1223+
"firehose:DeleteDeliveryStream",
1224+
"firehose:DescribeDeliveryStream",
1225+
"firehose:PutRecord",
1226+
"firehose:PutRecordBatch",
1227+
"firehose:UpdateDestination"
1228+
],
1229+
"Resource": {
1230+
"Fn::Sub": [
1231+
"arn:${AWS::Partition}:firehose:${AWS::Region}:${AWS::AccountId}:deliverystream/${deliveryStreamName}",
1232+
{
1233+
"deliveryStreamName": {
1234+
"Ref": "DeliveryStreamName"
1235+
}
1236+
}
1237+
]
1238+
}
1239+
}
1240+
]
1241+
}
11351242
}
11361243
}
11371244
}

docs/safe_lambda_deployments.rst

Lines changed: 21 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,14 @@ Safe Lambda deployments
33

44
.. contents::
55

6-
Pushing to production can be nerve-racking even if you have 100% unit test coverage and state-of-art full CD system.
6+
Pushing to production can be nerve-wracking even if you have 100% unit test coverage and a state-of-art full CD system.
77
It is a good practice to expose your new code to a small percentage of production traffic, run tests, watch for alarms
88
and dial up traffic as you gain more confidence. The goal is to minimize production impact as much as possible.
99

1010
To enable traffic shifting deployments for Lambda functions, we will use Lambda Aliases, which can balance incoming
1111
traffic between two different versions of your function, based on preassigned weights. Before deployment,
1212
the alias sends 100% of invokes to the version used in production. During deployment, we will upload the code to Lambda,
13-
publish a new version, send a small percentage of traffic to new version, monitor, and validate before shifting
13+
publish a new version, send a small percentage of traffic to the new version, monitor, and validate before shifting
1414
100% of traffic to the new version. You can do this manually by calling Lambda APIs or let AWS CodeDeploy automate
1515
it for you. CodeDeploy will shift traffic, monitor alarms, run validation logic and even trigger an automatic rollback
1616
if something goes wrong.
@@ -32,24 +32,24 @@ Instant traffic shifting using Lambda Aliases
3232
---------------------------------------------
3333

3434
Every Lambda function can have any number of Versions and Aliases
35-
associated with them. Versions are immutable snapshot of function
35+
associated with them. Versions are immutable snapshots of a function
3636
including code & configuration. If you are familiar with git, they are
37-
similar to commits. It is a good practice in general to publish a new
37+
similar to commits. In general, it is a good practice to publish a new
3838
version every time you update your function code. When you invoke a
39-
specific version (using function name + version number combination) you
40-
are guaranteed to get the same code & configuration irrespective of
39+
specific version (using the function name + version number combination) you
40+
are guaranteed to get the same code & configuration irrespective of the
4141
state of the function. This protects you against accidentally updating
4242
production code.
4343

4444
To effectively use the versions, you should create an Alias which is
4545
literally a pointer to a version. Aliases have a name and an ARN similar
46-
to the function and accepted by the Invoke APIs. If you invoke an Alias,
46+
to the function and are accepted by the Invoke APIs. If you invoke an Alias,
4747
Lambda will in turn invoke the version that the Alias is pointing to.
4848

4949
In production, you will first update your function code, publish a new
50-
version, invoke the version directly to run tests against it, and after
51-
you are satisfied flip the Alias to point to the new version. Traffic
52-
will instantly shift from using your old version to the new version.
50+
version, invoke the version directly to run tests against it, and, after
51+
you are satisfied, flip the Alias to point to the new version. Traffic
52+
will instantly shift from using your old version to using the new version.
5353

5454
SAM provides a simple primitive to do this for you. Add the following
5555
property to your ``AWS::Serverless::Function`` resource:
@@ -61,10 +61,10 @@ property to your ``AWS::Serverless::Function`` resource:
6161
This will:
6262

6363
- Create an Alias with ``<alias-name>``
64-
- Creates & publishes a Lambda version with the latest code & configuration
65-
derived from ``CodeUri`` property
64+
- Create & publish a Lambda version with the latest code & configuration
65+
derived from the ``CodeUri`` property
6666
- Point the Alias to the latest published version
67-
- Point all event sources to the Alias & not the function
67+
- Point all event sources to the Alias & not to the function
6868
- When the ``CodeUri`` property of ``AWS::Serverless::Function`` changes,
6969
SAM will automatically publish a new version & point the alias to the
7070
new version
@@ -79,8 +79,8 @@ In other words, your traffic will shift "instantly" to your new code.
7979
Traffic shifting using CodeDeploy
8080
----------------------------------
8181

82-
For production deployments, you want a more controlled traffic shifting
83-
from old version to new version while monitoring alarms and triggering a
82+
For production deployments, you may want more controlled traffic shifting
83+
from an old version to a new version which monitors alarms and triggers a
8484
rollback if necessary. CodeDeploy is an AWS service which can do this
8585
for you. It uses Lambda Alias' ability to route a percentage of traffic
8686
to two different Lambda Versions. To use this feature, set the
@@ -174,14 +174,14 @@ CloudFormation, the following happens:
174174
- Before traffic shifting starts, CodeDeploy will invoke the **PreTraffic Hook** Lambda function. This Lambda function must call back to CodeDeploy with an explicit status of Success or Failure, via the PutLifecycleEventHookExecutionStatus_ API. On Failure, CodeDeploy will abort and report a failure back to CloudFormation. On Success, CodeDeploy will proceed with the specified traffic shifting. Here_ is a sample Lambda Hook function.
175175
- ``Type: Linear10PercentEvery10Minutes`` instructs CodeDeploy to start with 10% traffic on new version and add 10% every 10 minutes. It will complete traffic shifting in 100 minutes.
176176
- During traffic shifting, if any of the CloudWatch Alarms go to *Alarm* state, CodeDeploy will immediately flip the Alias back to old version and report a failure to CloudFormation.
177-
- After traffic shifting completes, CodeDeploy will invoke the **PostTraffic Hook** Lambda function. This is similar to PreTraffic Hook where the function must callback to CodeDeploy to report a Success or Failure. PostTraffic hook is a great place to run integration tests or other validation actions.
177+
- After traffic shifting completes, CodeDeploy will invoke the **PostTraffic Hook** Lambda function. This is similar to PreTraffic Hook where the function must callback to CodeDeploy to report a Success or a Failure. PostTraffic hook is a great place to run integration tests or other validation actions.
178178
- If everything went well, the Alias will be pointing to the new Lambda Version.
179179

180180
NOTE: Verify that your AWS SDK version supports PutLifecycleEventHookExecutionStatus. For example, Python requires SDK version 1.4.8 or newer.
181181

182182
.. _PutLifecycleEventHookExecutionStatus: https://docs.aws.amazon.com/codedeploy/latest/APIReference/API_PutLifecycleEventHookExecutionStatus.html
183183

184-
.. _Here: https://github.com/awslabs/serverless-application-model/blob/master/examples/2016-10-31/lambda_safe_deployments/preTrafficHook.js
184+
.. _Here: https://github.com/awslabs/serverless-application-model/blob/master/examples/2016-10-31/lambda_safe_deployments/src/preTrafficHook.js
185185

186186
Traffic Shifting Configurations
187187
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -207,8 +207,8 @@ They work as follows:
207207

208208
Ex: ``Linear10PercentEvery10Minutes`` will add 10 percentage of traffic every 10 minute to complete in 100 minutes.
209209

210-
- **CanaryXPercentYMinutes**: X percent of traffic will be routed to new Version once, and wait for Y minutes in this
211-
state before sending 100 percent of traffic to new version. Some people call this as Blue/Green deployment.
210+
- **CanaryXPercentYMinutes**: X percent of traffic will be routed to new version for Y minutes. After Y minutes,
211+
100 percent of traffic will be sent to new version. Some people call this as Blue/Green deployment.
212212

213213
Ex: ``Canary10Percent15Minutes`` will send 10 percent traffic to new version and 15 minutes later complete deployment
214214
by sending all traffic to new version.
@@ -254,8 +254,8 @@ Hooks are extremely powerful because:
254254
Function). So you can customize the hooks logic to the function that is being deployed.
255255

256256
NOTE: If the Hook functions are created by the same SAM template that is deployed, then make sure to turn off
257-
traffic shifting deployments for the hook functions. Also, the Role SAM generates for a Lambda Execution Role does not include all permissions needed for Per and Post hook functions, since it
258-
will not contain the necessary permissions to call the CodeDepoloy APIs or Invoke your new Lambda function for testing.
257+
traffic shifting deployments for the hook functions. Also, the Role SAM generates for a Lambda Execution Role does not include all permissions needed for Pre and Post hook functions, since it
258+
will not contain the necessary permissions to call the CodeDeploy APIs or Invoke your new Lambda function for testing.
259259
Instead, use the Policies_ attribute to provide the CodeDeploy and Lambda permissions needed. The example also shows a Policy that provides access to the CodeDeploy resource that SAM automatically generates.
260260
Finally, use the ``FunctionName`` property to control the exact name of the Lambda function CloudFormation creates. Otherwise, CloudFormation will create your Lambda function with the Stack name and a unique ID added as part of the name.
261261

examples/2016-10-31/api_backend/src/index.js

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,7 @@ const dynamo = new AWS.DynamoDB.DocumentClient();
66

77
const tableName = process.env.TABLE_NAME;
88

9-
const createResponse = (statusCode, body) => {
10-
11-
return {
12-
statusCode: statusCode,
13-
body: body
14-
}
15-
};
9+
const createResponse = (statusCode, body) => ({ statusCode, body });
1610

1711
exports.get = (event, context, callback) => {
1812

examples/2016-10-31/policy_templates/all_policy_templates.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@ Resources:
4949
- RekognitionWriteOnlyAccessPolicy:
5050
CollectionId: id
5151

52+
- RekognitionLabelsPolicy: {}
53+
5254
- SQSSendMessagePolicy:
5355
QueueName: name
5456

0 commit comments

Comments
 (0)