├── .github ├── ISSUE_TEMPLATE │ ├── bug_report.md │ └── feature_request.md └── workflows │ ├── primary.yml │ └── secondary.yml ├── .gitignore ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── lambda_function.py ├── lambdas ├── __init__.py ├── add │ ├── __init__.py │ ├── add.py │ └── requirements.txt ├── cleaninput │ ├── __init__.py │ ├── cleaninput.py │ └── requirements.txt ├── divide │ ├── __init__.py │ ├── divide.py │ └── requirements.txt ├── multiply │ ├── __init__.py │ ├── multiply.py │ └── requirements.txt ├── requirements.txt └── subtract │ ├── __init__.py │ ├── requirements.txt │ └── subtract.py ├── requirements.txt ├── sm_def.yaml ├── template.yaml └── tests ├── requirements.txt └── unit └── lambdas ├── test_add.py ├── test_cleaninput.py ├── test_divide.py ├── test_multiply.py └── test_subtract.py /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: "[ISSUE] " 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **To Reproduce** 14 | Steps to reproduce the behavior: 15 | 1. Go to '...' 16 | 2. Click on '....' 17 | 3. Scroll down to '....' 18 | 4. See error 19 | 20 | **Expected behavior** 21 | A clear and concise description of what you expected to happen. 22 | 23 | **Screenshots** 24 | If applicable, add screenshots to help explain your problem. 25 | 26 | **Versions (please complete the following information):** 27 | - SAM 28 | - Python 29 | 30 | **Additional context** 31 | Add any other context about the problem here. 32 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: "[FEATURE REQUEST] " 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /.github/workflows/primary.yml: -------------------------------------------------------------------------------- 1 | name: SAM Validate, Build, Test, Deploy 2 | on: 3 | push: 4 | branches: [ main ] 5 | 6 | jobs: 7 | sam-validate-build-test-deploy: 8 | runs-on: ubuntu-latest 9 | outputs: 10 | env-name: ${{ steps.env-name.outputs.environment }} 11 | steps: 12 | - uses: actions/checkout@v2 13 | - name: Install Dependencies with Apt Get 14 | run: | 15 | sudo apt-get update 16 | sudo apt-get install python3.8 jq -y 17 | - name: Install Pip Dependencies for CI 18 | run: | 19 | pip3 install pytest 20 | - name: Configure AWS credentials 21 | id: creds 22 | uses: aws-actions/configure-aws-credentials@v1 23 | with: 24 | aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} 25 | aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} 26 | # aws-session-token: ${{ secrets.AWS_SESSION_TOKEN }} 27 | aws-region: ${{ secrets.AWS_REGION }} 28 | - name: SAM Validate 29 | run: | 30 | sam validate 31 | - name: Configure variables 32 | shell: bash 33 | id: vars 34 | env: 35 | REPO: ${{ github.repository }} 36 | HASH: ${{ github.sha }} 37 | REF: ${{ github.ref }} 38 | run: | 39 | # Set variables 40 | BRANCH=${REF#refs/heads/} 41 | REPOSITORY=`echo $REPO | tr "/" "-"` 42 | ENVIRONMENT=$BRANCH-$REPOSITORY-${{ secrets.AWS_REGION }} 43 | # In this step we are setting variables and persistenting them 44 | # into the environment so that they can be utilized in other steps 45 | echo "::set-output name=branch::$BRANCH" 46 | echo "::set-output name=repository::$REPOSITORY" 47 | echo "::set-output name=environment::$ENVIRONMENT" 48 | # Output variables to ensure their values are set correctly when ran 49 | echo "The region is ${{ secrets.AWS_REGION }}" 50 | echo "The repository is $REPOSITORY" 51 | echo "The environment is $ENVIRONMENT" 52 | echo "The branch is $BRANCH" 53 | - name: SAM Build 54 | run: | 55 | sam build 56 | - name: Run unit tests 57 | run: | 58 | python3 -m pytest -s -vvv ./tests/unit/ 59 | - name: SAM Deploy 60 | run: | 61 | # Create S3 Bucket to store code 62 | aws s3api head-bucket --bucket "${{ steps.vars.outputs.environment }}" 2>/dev/null \ 63 | || aws s3 mb s3://${{ steps.vars.outputs.environment }} 64 | # Run SAM Deploy 65 | sam deploy --template-file .aws-sam/build/template.yaml \ 66 | --stack-name ${{ steps.vars.outputs.environment }} \ 67 | --s3-bucket ${{ steps.vars.outputs.environment }} \ 68 | --parameter-overrides \ 69 | 'ParameterKey=Name,ParameterValue=example \ 70 | ParameterKey=Version,ParameterValue=${{ steps.vars.outputs.version }}' \ 71 | --capabilities CAPABILITY_IAM CAPABILITY_NAMED_IAM 72 | -------------------------------------------------------------------------------- /.github/workflows/secondary.yml: -------------------------------------------------------------------------------- 1 | name: SAM Validate, Build, Test 2 | on: 3 | pull_request: 4 | branches: [ main ] 5 | 6 | jobs: 7 | sam-validate-build-test: 8 | runs-on: ubuntu-latest 9 | outputs: 10 | env-name: ${{ steps.env-name.outputs.environment }} 11 | steps: 12 | - uses: actions/checkout@v2 13 | - name: Install Dependencies with Apt Get 14 | run: | 15 | sudo apt-get update 16 | sudo apt-get install python3.8 jq -y 17 | - name: Install Pip Dependencies 18 | run: | 19 | pip3 install pytest 20 | - name: Configure AWS credentials 21 | id: creds 22 | uses: aws-actions/configure-aws-credentials@v1 23 | with: 24 | aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} 25 | aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} 26 | # aws-session-token: ${{ secrets.AWS_SESSION_TOKEN }} 27 | aws-region: ${{ secrets.AWS_REGION }} 28 | - name: SAM Validate 29 | run: | 30 | sam validate 31 | - name: Configure variables 32 | shell: bash 33 | id: vars 34 | env: 35 | REPO: ${{ github.repository }} 36 | HASH: ${{ github.sha }} 37 | REF: ${{ github.ref }} 38 | run: | 39 | # In this step we are setting variables and persistenting them 40 | # into the environment so that they can be utilized in other steps 41 | BRANCH=${REF#refs/heads/} 42 | REGION=$(cat ./config.json | jq -r .region) 43 | ENVIRONMENT=`echo $REPO | tr "/" "-"` 44 | BUCKET_NAME=$BRANCH-$ENVIRONMENT 45 | echo "::set-output name=environment::$ENVIRONMENT" 46 | echo "::set-output name=region::$REGION" 47 | echo "::set-output name=bucket_name::$BUCKET_NAME" 48 | echo "The environment is $ENVIRONMENT" 49 | echo "The region is $REGION" 50 | echo "The bucket_name is $BUCKET_NAME" 51 | echo "The branch is $BRANCH" 52 | - name: SAM Build 53 | run: | 54 | sam build 55 | - name: Run unit tests 56 | run: | 57 | python3 -m pytest -s -vvv ./tests/unit/ -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .aws-sam 2 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | ## Code of Conduct 2 | This project has adopted the [Amazon Open Source Code of Conduct](https://aws.github.io/code-of-conduct). 3 | For more information see the [Code of Conduct FAQ](https://aws.github.io/code-of-conduct-faq) or contact 4 | opensource-codeofconduct@amazon.com with any additional questions or comments. 5 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing Guidelines 2 | 3 | Thank you for your interest in contributing to our project. Whether it's a bug report, new feature, correction, or additional 4 | documentation, we greatly value feedback and contributions from our community. 5 | 6 | Please read through this document before submitting any issues or pull requests to ensure we have all the necessary 7 | information to effectively respond to your bug report or contribution. 8 | 9 | 10 | ## Reporting Bugs/Feature Requests 11 | 12 | We welcome you to use the GitHub issue tracker to report bugs or suggest features. 13 | 14 | When filing an issue, please check existing open, or recently closed, issues to make sure somebody else hasn't already 15 | reported the issue. Please try to include as much information as you can. Details like these are incredibly useful: 16 | 17 | * A reproducible test case or series of steps 18 | * The version of our code being used 19 | * Any modifications you've made relevant to the bug 20 | * Anything unusual about your environment or deployment 21 | 22 | 23 | ## Contributing via Pull Requests 24 | Contributions via pull requests are much appreciated. Before sending us a pull request, please ensure that: 25 | 26 | 1. You are working against the latest source on the *main* branch. 27 | 2. You check existing open, and recently merged, pull requests to make sure someone else hasn't addressed the problem already. 28 | 3. You open an issue to discuss any significant work - we would hate for your time to be wasted. 29 | 30 | To send us a pull request, please: 31 | 32 | 1. Fork the repository. 33 | 2. Modify the source; please focus on the specific change you are contributing. If you also reformat all the code, it will be hard for us to focus on your change. 34 | 3. Ensure local tests pass. 35 | 4. Commit to your fork using clear commit messages. 36 | 5. Send us a pull request, answering any default questions in the pull request interface. 37 | 6. Pay attention to any automated CI failures reported in the pull request, and stay involved in the conversation. 38 | 39 | GitHub provides additional document on [forking a repository](https://help.github.com/articles/fork-a-repo/) and 40 | [creating a pull request](https://help.github.com/articles/creating-a-pull-request/). 41 | 42 | 43 | ## Finding contributions to work on 44 | Looking at the existing issues is a great way to find something to contribute on. As our projects, by default, use the default GitHub issue labels (enhancement/bug/duplicate/help wanted/invalid/question/wontfix), looking at any 'help wanted' issues is a great place to start. 45 | 46 | 47 | ## Code of Conduct 48 | This project has adopted the [Amazon Open Source Code of Conduct](https://aws.github.io/code-of-conduct). 49 | For more information see the [Code of Conduct FAQ](https://aws.github.io/code-of-conduct-faq) or contact 50 | opensource-codeofconduct@amazon.com with any additional questions or comments. 51 | 52 | 53 | ## Security issue notifications 54 | If you discover a potential security issue in this project we ask that you notify AWS/Amazon Security via our [vulnerability reporting page](http://aws.amazon.com/security/vulnerability-reporting/). Please do **not** create a public github issue. 55 | 56 | 57 | ## Licensing 58 | 59 | See the [LICENSE](LICENSE) file for our project's licensing. We will ask you to confirm the licensing of your contribution. 60 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of 4 | this software and associated documentation files (the "Software"), to deal in 5 | the Software without restriction, including without limitation the rights to 6 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 7 | the Software, and to permit persons to whom the Software is furnished to do so. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 10 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 11 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 12 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 13 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 14 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 15 | 16 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # GitHub Actions SAM Deployment Example 2 | The purpose of this repository is to illustrate a GitHub Actions pipeline deploying a SAM template. 3 | 4 | In this particular example we are deploying Amazon API Gateway, AWS StateMachine, AWS Lambda Functions, and corresponding IAM Roles. 5 | 6 | ## How it Works 7 | 8 | There are two workflows `sam-validate-build-test-deploy` and `sam-validate-build-test`. 9 | 10 | In this repository's current configuration, deployment only occurs when changes land into the `main` branch. This is seen within the `.github/workflows/sam-validate-build-test-deploy.yml` file: 11 | ``` 12 | on: 13 | push: 14 | branches: [ main ] 15 | ``` 16 | 17 | For all `other branches`, we will run the `sam-validate-build-test` workflow when pull requests are created. This ensures that the code they are looking to merge passes the `sam validate` and `sam build` steps. 18 | ``` 19 | on: 20 | pull_request: 21 | branches: [ main ] 22 | ``` 23 | 24 | ## How To Configure 25 | * Fork this repo and update the code and SAM template to reflect the code you are looking to deploy. 26 | * Within the Repository settings for your fork or repo, create the following `Secrets` to configure the permissions to be used by the GitHub Actions pipeline: 27 | ``` 28 | AWS_ACCESS_KEY_ID 29 | AWS_SECRET_ACCESS_KEY 30 | AWS_SESSION_TOKEN 31 | AWS_REGION 32 | ``` 33 | 34 | Please note the `AWS_SESSION_TOKEN` is optional, but preferable. -------------------------------------------------------------------------------- /lambda_function.py: -------------------------------------------------------------------------------- 1 | from __future__ import print_function 2 | 3 | import json 4 | 5 | print('Loading function') 6 | 7 | 8 | def lambda_handler(event, context): 9 | print("Hello World" + event) 10 | return event['key1'] 11 | -------------------------------------------------------------------------------- /lambdas/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/aws-sam-github-actions-example/6d976298a4f65410adb11142934a766078af4ad0/lambdas/__init__.py -------------------------------------------------------------------------------- /lambdas/add/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/aws-sam-github-actions-example/6d976298a4f65410adb11142934a766078af4ad0/lambdas/add/__init__.py -------------------------------------------------------------------------------- /lambdas/add/add.py: -------------------------------------------------------------------------------- 1 | # Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | # SPDX-License-Identifier: MIT-0 3 | 4 | import json 5 | 6 | def lambda_handler(event, context): 7 | print(event) 8 | first = event['input']['first'] 9 | second = event['input']['second'] 10 | third = event['input']['third'] 11 | result = event['input']['result'] 12 | 13 | print(f"FIRST: {first}, SECOND: {second}, THIRD: {third}") 14 | 15 | result = int(result) + int(second) 16 | 17 | print(f"RESULT: {result}") 18 | 19 | response = { 20 | "first": first, 21 | "second": second, 22 | "third": third, 23 | "result": int(result) 24 | } 25 | 26 | event['input'] = response 27 | 28 | return event['input'] 29 | -------------------------------------------------------------------------------- /lambdas/add/requirements.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/aws-sam-github-actions-example/6d976298a4f65410adb11142934a766078af4ad0/lambdas/add/requirements.txt -------------------------------------------------------------------------------- /lambdas/cleaninput/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/aws-sam-github-actions-example/6d976298a4f65410adb11142934a766078af4ad0/lambdas/cleaninput/__init__.py -------------------------------------------------------------------------------- /lambdas/cleaninput/cleaninput.py: -------------------------------------------------------------------------------- 1 | # Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | # SPDX-License-Identifier: MIT-0 3 | 4 | import json 5 | 6 | def lambda_handler(event, context): 7 | print(event) 8 | input_vals = event['input'] 9 | 10 | values = input_vals['input'].split(" ") 11 | 12 | input_massaged = { 13 | "first": values[0], 14 | "second": values[1], 15 | "third": values[2] 16 | } 17 | 18 | event['input'] = input_massaged 19 | 20 | return event 21 | -------------------------------------------------------------------------------- /lambdas/cleaninput/requirements.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/aws-sam-github-actions-example/6d976298a4f65410adb11142934a766078af4ad0/lambdas/cleaninput/requirements.txt -------------------------------------------------------------------------------- /lambdas/divide/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/aws-sam-github-actions-example/6d976298a4f65410adb11142934a766078af4ad0/lambdas/divide/__init__.py -------------------------------------------------------------------------------- /lambdas/divide/divide.py: -------------------------------------------------------------------------------- 1 | import json 2 | 3 | def lambda_handler(event, context): 4 | print(event) 5 | first = event['input']['first'] 6 | second = event['input']['second'] 7 | third = event['input']['third'] 8 | result = event['input']['result'] 9 | 10 | print(f"FIRST: {first}, SECOND: {second}, THIRD: {third}") 11 | 12 | result = int(result) / int(second) 13 | 14 | print(f"RESULT: {result}") 15 | 16 | response = { 17 | "first": first, 18 | "second": second, 19 | "third": third, 20 | "result": int(result) 21 | } 22 | 23 | event['input'] = response 24 | 25 | return event['input'] -------------------------------------------------------------------------------- /lambdas/divide/requirements.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/aws-sam-github-actions-example/6d976298a4f65410adb11142934a766078af4ad0/lambdas/divide/requirements.txt -------------------------------------------------------------------------------- /lambdas/multiply/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/aws-sam-github-actions-example/6d976298a4f65410adb11142934a766078af4ad0/lambdas/multiply/__init__.py -------------------------------------------------------------------------------- /lambdas/multiply/multiply.py: -------------------------------------------------------------------------------- 1 | 2 | # Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | # SPDX-License-Identifier: MIT-0 4 | 5 | import json 6 | 7 | def lambda_handler(event, context): 8 | print(event) 9 | first = event['input']['input']['first'] 10 | second = event['input']['input']['second'] 11 | third = event['input']['input']['third'] 12 | 13 | print(f"FIRST: {first}, SECOND: {second}, THIRD: {third}") 14 | 15 | result = int(first) * int(second) * int(third) 16 | 17 | print(f"RESULT: {result}") 18 | 19 | response = { 20 | "first": first, 21 | "second": second, 22 | "third": third, 23 | "result": int(result) 24 | } 25 | 26 | event['input'] = response 27 | 28 | print(event['input']) 29 | 30 | return event['input'] 31 | -------------------------------------------------------------------------------- /lambdas/multiply/requirements.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/aws-sam-github-actions-example/6d976298a4f65410adb11142934a766078af4ad0/lambdas/multiply/requirements.txt -------------------------------------------------------------------------------- /lambdas/requirements.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/aws-sam-github-actions-example/6d976298a4f65410adb11142934a766078af4ad0/lambdas/requirements.txt -------------------------------------------------------------------------------- /lambdas/subtract/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/aws-sam-github-actions-example/6d976298a4f65410adb11142934a766078af4ad0/lambdas/subtract/__init__.py -------------------------------------------------------------------------------- /lambdas/subtract/requirements.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/aws-sam-github-actions-example/6d976298a4f65410adb11142934a766078af4ad0/lambdas/subtract/requirements.txt -------------------------------------------------------------------------------- /lambdas/subtract/subtract.py: -------------------------------------------------------------------------------- 1 | # Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | # SPDX-License-Identifier: MIT-0 3 | 4 | import json 5 | 6 | def lambda_handler(event, context): 7 | print(event) 8 | first = event['input']['first'] 9 | second = event['input']['second'] 10 | third = event['input']['third'] 11 | result = event['input']['result'] 12 | 13 | print(f"FIRST: {first}, SECOND: {second}, THIRD: {third}") 14 | 15 | result = int(result) - int(first) 16 | 17 | print(f"RESULT: {result}") 18 | 19 | response = { 20 | "first": first, 21 | "second": second, 22 | "third": third, 23 | "result": int(result) 24 | } 25 | 26 | event['input'] = response 27 | 28 | return event['input'] 29 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/aws-sam-github-actions-example/6d976298a4f65410adb11142934a766078af4ad0/requirements.txt -------------------------------------------------------------------------------- /sm_def.yaml: -------------------------------------------------------------------------------- 1 | Comment: CalculationStateMachine 2 | StartAt: CleanInput 3 | States: 4 | CleanInput: 5 | Type: Task 6 | Resource: 'arn:aws:states:::lambda:invoke' 7 | Parameters: 8 | FunctionName: ${CleanInputLambdaFunction} 9 | Payload: 10 | input.$: $ 11 | Next: Multiply 12 | Multiply: 13 | Type: Task 14 | Resource: 'arn:aws:states:::lambda:invoke' 15 | Parameters: 16 | FunctionName: ${MultiplyLambdaFunction} 17 | Payload: 18 | input.$: $.Payload 19 | Next: Choice 20 | Choice: 21 | Type: Choice 22 | Choices: 23 | - 24 | Variable: $.Payload.result 25 | NumericGreaterThanEquals: 20 26 | Next: Subtract 27 | Default: Fail 28 | Subtract: 29 | Type: Task 30 | Resource: 'arn:aws:states:::lambda:invoke' 31 | Parameters: 32 | FunctionName: ${SubtractLambdaFunction} 33 | Payload: 34 | input.$: $.Payload 35 | Next: Add 36 | Fail: 37 | Type: Fail 38 | Cause: Number Too Small 39 | Error: NumberTooSmallError 40 | Add: 41 | Type: Task 42 | Resource: 'arn:aws:states:::lambda:invoke' 43 | Parameters: 44 | FunctionName: ${AddLambdaFunction} 45 | Payload: 46 | input.$: $.Payload 47 | Next: Divide 48 | Divide: 49 | Type: Task 50 | Resource: 'arn:aws:states:::lambda:invoke' 51 | Parameters: 52 | FunctionName: ${DivideLambdaFunction} 53 | Payload: 54 | input.$: $.Payload 55 | End: true 56 | -------------------------------------------------------------------------------- /template.yaml: -------------------------------------------------------------------------------- 1 | AWSTemplateFormatVersion: '2010-09-09' 2 | Transform: AWS::Serverless-2016-10-31 3 | Description: A bare bones example of deploying an API Gateway API with one Lambda using an OpenAPI 3.0.1 example spec file as in-line yaml. 4 | 5 | Parameters: 6 | 7 | Name: 8 | Type: String 9 | Description: The name of the API to create, also used as the stack name. 10 | 11 | Resources: 12 | 13 | Api: 14 | Type: AWS::Serverless::Api 15 | Properties: 16 | Name: !Ref Name 17 | StageName: live 18 | OpenApiVersion: 3.0.1 19 | DefinitionBody: 20 | openapi: 3.0.1 21 | info: 22 | title: Hello World API 23 | description: This is a swagger example. 24 | contact: 25 | email: you@your-company.com 26 | license: 27 | name: Apache 2.0 28 | url: http://www.apache.org/licenses/LICENSE-2.0.html 29 | version: 1.0.0 30 | paths: 31 | /hello/world: 32 | get: 33 | summary: get hello world 34 | description: | 35 | Invokes hello world lambda function example. 36 | responses: 37 | "200": 38 | description: search results matching criteria 39 | "400": 40 | description: bad input parameter 41 | x-amazon-apigateway-integration: 42 | uri: 43 | Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${AddLambdaFunction.Arn}/invocations 44 | responses: 45 | default: 46 | statusCode: "200" 47 | passthroughBehavior: when_no_match 48 | httpMethod: POST 49 | contentHandling: CONVERT_TO_TEXT 50 | type: aws_proxy 51 | 52 | AddLambdaFunction: 53 | Type: AWS::Serverless::Function 54 | Properties: 55 | Handler: add.lambda_handler 56 | Runtime: python3.8 57 | CodeUri: ./lambdas/add 58 | Description: Add 59 | AutoPublishAlias: live 60 | 61 | CleanInputLambdaFunction: 62 | Type: AWS::Serverless::Function 63 | Properties: 64 | Handler: cleaninput.lambda_handler 65 | Runtime: python3.8 66 | CodeUri: ./lambdas/cleaninput 67 | Description: Clean Input 68 | AutoPublishAlias: live 69 | 70 | DivideLambdaFunction: 71 | Type: AWS::Serverless::Function 72 | Properties: 73 | Handler: divide.lambda_handler 74 | Runtime: python3.8 75 | CodeUri: ./lambdas/divide 76 | Description: Divide 77 | AutoPublishAlias: live 78 | 79 | MultiplyLambdaFunction: 80 | Type: AWS::Serverless::Function 81 | Properties: 82 | Handler: multiply.lambda_handler 83 | Runtime: python3.8 84 | CodeUri: ./lambdas/multiply 85 | Description: Multiply 86 | AutoPublishAlias: live 87 | 88 | SubtractLambdaFunction: 89 | Type: AWS::Serverless::Function 90 | Properties: 91 | Handler: subtract.lambda_handler 92 | Runtime: python3.8 93 | CodeUri: ./lambdas/subtract 94 | Description: Subtract 95 | AutoPublishAlias: live 96 | 97 | StateMachine: 98 | Type: AWS::Serverless::StateMachine 99 | Properties: 100 | Name: !Sub statemachine-${AWS::StackName} 101 | DefinitionUri: sm_def.yaml 102 | DefinitionSubstitutions: 103 | AddLambdaFunction: !Ref AddLambdaFunction 104 | CleanInputLambdaFunction: !Ref CleanInputLambdaFunction 105 | DivideLambdaFunction: !Ref DivideLambdaFunction 106 | MultiplyLambdaFunction: !Ref MultiplyLambdaFunction 107 | SubtractLambdaFunction: !Ref SubtractLambdaFunction 108 | Role: !GetAtt StateMachineRole.Arn 109 | 110 | StateMachineRole: 111 | Type: AWS::IAM::Role 112 | Properties: 113 | RoleName: !Sub statemachine-role-${AWS::StackName} 114 | AssumeRolePolicyDocument: 115 | Version: "2012-10-17" 116 | Statement: 117 | - Effect: Allow 118 | Principal: 119 | Service: states.amazonaws.com 120 | Action: sts:AssumeRole 121 | ManagedPolicyArns: 122 | - arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole 123 | 124 | InvokeFunctionPolicy: 125 | Type: AWS::IAM::Policy 126 | Properties: 127 | PolicyName: !Sub statemachine-invoke-function-policy-${AWS::StackName} 128 | Roles: 129 | - !Ref StateMachineRole 130 | PolicyDocument: 131 | Version: 2012-10-17 132 | Statement: 133 | - Effect: Allow 134 | Action: 135 | - lambda:InvokeFunction 136 | Resource: '*' 137 | -------------------------------------------------------------------------------- /tests/requirements.txt: -------------------------------------------------------------------------------- 1 | boto3 2 | pytest -------------------------------------------------------------------------------- /tests/unit/lambdas/test_add.py: -------------------------------------------------------------------------------- 1 | # Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | # SPDX-License-Identifier: MIT-0 3 | 4 | import os 5 | import sys 6 | 7 | sys.path.append( 8 | os.path.realpath( 9 | os.path.join( 10 | os.path.dirname(__file__), 11 | os.path.pardir, 12 | os.path.pardir, 13 | os.path.pardir, 14 | "lambdas", 15 | "add" 16 | ) 17 | ) 18 | ) 19 | 20 | from add import lambda_handler 21 | 22 | def test_add(): 23 | event = { 24 | "input": { 25 | "first": "1", 26 | "second": "20", 27 | "third": "3", 28 | "result": 59 29 | } 30 | } 31 | 32 | # actual function call 33 | actual_response = lambda_handler( 34 | event=event, 35 | context={} 36 | ) 37 | 38 | # expected response 39 | expected_response = { 40 | 'first': '1', 41 | 'second': '20', 42 | 'third': '3', 43 | 'result': 79 44 | } 45 | 46 | assert(actual_response == expected_response) 47 | -------------------------------------------------------------------------------- /tests/unit/lambdas/test_cleaninput.py: -------------------------------------------------------------------------------- 1 | # Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | # SPDX-License-Identifier: MIT-0 3 | 4 | import os 5 | import sys 6 | 7 | sys.path.append( 8 | os.path.realpath( 9 | os.path.join( 10 | os.path.dirname(__file__), 11 | os.path.pardir, 12 | os.path.pardir, 13 | os.path.pardir, 14 | "lambdas", 15 | "cleaninput" 16 | ) 17 | ) 18 | ) 19 | 20 | from cleaninput import lambda_handler 21 | 22 | def test_cleaninput(): 23 | event = { 24 | 'input': { 25 | 'input': '1 20 3' 26 | } 27 | } 28 | 29 | # actual function call 30 | actual_response = lambda_handler( 31 | event=event, 32 | context={} 33 | ) 34 | 35 | # expected response 36 | expected_response = { 37 | 'input': { 38 | 'first': '1', 39 | 'second': '20', 40 | 'third': '3' 41 | } 42 | } 43 | 44 | assert(actual_response == expected_response) 45 | -------------------------------------------------------------------------------- /tests/unit/lambdas/test_divide.py: -------------------------------------------------------------------------------- 1 | # Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | # SPDX-License-Identifier: MIT-0 3 | 4 | import os 5 | import sys 6 | 7 | sys.path.append( 8 | os.path.realpath( 9 | os.path.join( 10 | os.path.dirname(__file__), 11 | os.path.pardir, 12 | os.path.pardir, 13 | os.path.pardir, 14 | "lambdas", 15 | "divide" 16 | ) 17 | ) 18 | ) 19 | 20 | from divide import lambda_handler 21 | 22 | def test_divide(): 23 | event = { 24 | "input": { 25 | "first": "1", 26 | "second": "20", 27 | "third": "3", 28 | "result": 59 29 | } 30 | } 31 | 32 | # actual function call 33 | actual_response = lambda_handler( 34 | event=event, 35 | context={} 36 | ) 37 | 38 | # expected response 39 | expected_response = { 40 | 'first': '1', 41 | 'second': '20', 42 | 'third': '3', 43 | 'result': 2 44 | } 45 | 46 | assert(actual_response == expected_response) 47 | -------------------------------------------------------------------------------- /tests/unit/lambdas/test_multiply.py: -------------------------------------------------------------------------------- 1 | # Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | # SPDX-License-Identifier: MIT-0 3 | 4 | import os 5 | import sys 6 | 7 | sys.path.append( 8 | os.path.realpath( 9 | os.path.join( 10 | os.path.dirname(__file__), 11 | os.path.pardir, 12 | os.path.pardir, 13 | os.path.pardir, 14 | "lambdas", 15 | "multiply" 16 | ) 17 | ) 18 | ) 19 | 20 | from multiply import lambda_handler 21 | 22 | def test_multiply(): 23 | event = { 24 | "input": { 25 | "input": { 26 | "first": "1", 27 | "second": "20", 28 | "third": "3", 29 | "result": 59 30 | } 31 | } 32 | } 33 | 34 | # actual function call 35 | actual_response = lambda_handler( 36 | event=event, 37 | context={} 38 | ) 39 | 40 | # expected response 41 | expected_response = { 42 | 'first': '1', 43 | 'second': '20', 44 | 'third': '3', 45 | 'result': 60 46 | } 47 | 48 | assert(actual_response == expected_response) 49 | -------------------------------------------------------------------------------- /tests/unit/lambdas/test_subtract.py: -------------------------------------------------------------------------------- 1 | # Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | # SPDX-License-Identifier: MIT-0 3 | 4 | import os 5 | import sys 6 | 7 | sys.path.append( 8 | os.path.realpath( 9 | os.path.join( 10 | os.path.dirname(__file__), 11 | os.path.pardir, 12 | os.path.pardir, 13 | os.path.pardir, 14 | "lambdas", 15 | "subtract" 16 | ) 17 | ) 18 | ) 19 | 20 | from subtract import lambda_handler 21 | 22 | def test_subtract(): 23 | event = { 24 | "input": { 25 | "first": "1", 26 | "second": "20", 27 | "third": "3", 28 | "result": 59 29 | } 30 | } 31 | 32 | # actual function call 33 | actual_response = lambda_handler( 34 | event=event, 35 | context={} 36 | ) 37 | 38 | # expected response 39 | expected_response = { 40 | 'first': '1', 41 | 'second': '20', 42 | 'third': '3', 43 | 'result': 58 44 | } 45 | 46 | assert(actual_response == expected_response) 47 | --------------------------------------------------------------------------------