Skip to content

Commit

Permalink
feature: use cookbook v4.2 (#20)
Browse files Browse the repository at this point in the history
Co-authored-by: Ran Isenberg <[email protected]>
  • Loading branch information
ran-isenberg and Ran Isenberg authored Oct 22, 2023
1 parent e4c91b4 commit bb4744a
Show file tree
Hide file tree
Showing 74 changed files with 1,524 additions and 587 deletions.
14 changes: 11 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,18 +71,25 @@ The documentation provides information about CDK deployment, makefile commands,
![design](https://github.com/ran-isenberg/cookiecutter-serverless-python/blob/main/media/design.png?raw=true)
<br></br>


#### **Monitoring Design**
![monitoring_design](https://github.com/ran-isenberg/aws-lambda-handler-cookbook/blob/main/docs/media/monitoring_design.png?raw=true)
<br></br>

### **Features**

- Python Serverless service with a recommended file structure.
- CDK infrastructure with infrastructure tests and security tests.
- CI/CD pipelines based on Github actions that deploys to AWS with python linters, complexity checks and style formatters.
- CI/CD pipeline deploys to dev/staging and production environment with different gates between each environment
- Makefile for simple developer experience.
- The AWS Lambda handler embodies Serverless best practices and has all the bells and whistles for a proper production ready handler.
- AWS Lambda handler uses [AWS Lambda Powertools](https://awslabs.github.io/aws-lambda-powertools-python/).
- AWS Lambda handler uses [AWS Lambda Powertools](https://docs.powertools.aws.dev/lambda-python/).
- AWS Lambda handler 3 layer architecture: handler layer, logic layer and data access layer
- Features flags and configuration based on AWS AppConfig
- Idempotent API
- Unit, infrastructure, security, integration and E2E tests.
- CloudWatch dashboards - High level and low level including CloudWatch alarms
- Unit, infrastructure, security, integration and end to end tests.
<br></br>

## CDK Deployment
Expand All @@ -107,7 +114,8 @@ The utilities cover multiple aspect of a production-ready service, including:
- [Dynamic Configuration & feature flags](https://www.ranthebuilder.cloud/post/aws-lambda-cookbook-part-6-feature-flags-configuration-best-practices)
- [Start Your AWS Serverless Service With Two Clicks](https://www.ranthebuilder.cloud/post/aws-lambda-cookbook-part-7-how-to-use-the-aws-lambda-cookbook-github-template-project)
- [CDK Best practices](https://github.com/ran-isenberg/aws-lambda-handler-cookbook)
- [Idempotent API](https://www.ranthebuilder.cloud/post/serverless-api-idempotency-with-aws-lambda-powertools-and-cdk)
- [Serverless Monitoring](https://www.ranthebuilder.cloud/post/how-to-effortlessly-monitor-serverless-applications-with-cloudwatch-part-one)
- [API Idempotency](https://www.ranthebuilder.cloud/post/serverless-api-idempotency-with-aws-lambda-powertools-and-cdk)

<br></br>
### Makefile Commands
Expand Down
18 changes: 2 additions & 16 deletions hooks/post_gen_project.py
Original file line number Diff line number Diff line change
@@ -1,24 +1,10 @@
import os
from pathlib import Path
import subprocess

def main():
print("Running 'git init'")
subprocess.run(['git', 'init'], check=True)

print("Running 'pip install --upgrade pip pre-commit poetry'")
subprocess.run(['pip', 'install', '--upgrade', 'pip', 'pre-commit', 'poetry'], check=True)

print("Running 'pre-commit install'")

subprocess.run(['pre-commit', 'install'], check=True)

print("Running 'poetry config --local virtualenvs.in-project true'")
subprocess.run(['poetry', 'config', '--local', 'virtualenvs.in-project', 'true'], check=True)

print("Running 'poetry install'")
subprocess.run(['poetry', 'install'], check=True)

print("Initializing project")
subprocess.run(['make', 'dev'], check=True)
print("Project successfully initialized")
return

Expand Down
Binary file added media/monitoring_design.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion {{cookiecutter.repo_name}}/.flake8
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[flake8]
exclude = .eggs, setup.py, example, .cdk,out, .git, dist, *.md, *.yaml, *.txt, *.ini
exclude = .eggs, setup.py, example, .cdk,out, .git, dist, *.md, *.yaml, *.txt, *.ini, build, cdk.json, cdk.context.json, cdk.out, node_modules
ignore = E203, E266, W503, BLK100, W291, I004
max-line-length = 150
max-complexity = 15
12 changes: 12 additions & 0 deletions {{cookiecutter.repo_name}}/.github/FUNDING.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# These are supported funding model platforms

github: ran-isenberg
patreon: # Replace with a single Patreon username
open_collective: # Replace with a single Open Collective username
ko_fi: # Replace with a single Ko-fi username
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
liberapay: # Replace with a single Liberapay username
issuehunt: # Replace with a single IssueHunt username
otechie: # Replace with a single Otechie username
custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']
16 changes: 14 additions & 2 deletions {{cookiecutter.repo_name}}/.github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,28 @@ updates:
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "weekly"
interval: "monthly"
commit-message:
prefix: chore
include: scope

- package-ecosystem: "pip"
directory: "/"
schedule:
interval: "weekly"
interval: "monthly"
target-branch: "main"
commit-message:
prefix: chore
include: scope

- package-ecosystem: "npm"
directory: "/"
schedule:
interval: "weekly"
target-branch: "develop"
commit-message:
prefix: chore
include: scope
allow:
# Allow updates for AWS CDK
- dependency-name: "aws-cdk"
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ jobs:

steps:
- name: Checkout repository
uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4.1.0

# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
name: Comment when opened

permissions:
issues: write
checks: read
contents: read

on:
issues:
types:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
# This workflow will install Python dependencies, run tests and lint with a single version of Python
# For more information see: https://help.github.com/actions/language-and-framework-guides/using-python-with-github-actions
name: Main Branch - Serverless Service CI/CD

permissions:
contents: read

env:
NODE_VERSION: "18"
PYTHON_VERSION: "3.11"
AWS_REGION: "us-east-1"

on:
workflow_dispatch:

push:
branches: [main]

jobs:
staging:
runs-on: ubuntu-latest
environment: staging
permissions:
id-token: write # required for requesting the JWT (GitHub OIDC)
steps:
- run: |
echo "🎉 The job was automatically triggered by a ${{ env.EVENT_NAME }} event." >> $GITHUB_STEP_SUMMARY
echo "🐧 This job is now running on a ${{ env.OS_NAME }} ${{env.OS_ARCH}} server hosted by GitHub!" >> $GITHUB_STEP_SUMMARY
echo "🔎 The name of your branch is ${{ env.BRANCH_NAME }} and your repository is ${{ env.REPO_NAME }}." >> $GITHUB_STEP_SUMMARY
env:
EVENT_NAME: ${{ github.event_name}}
OS_NAME: ${{ runner.os }}
OS_ARCH: ${{runner.arch }}
BRANCH_NAME: ${{ github.ref }}
REPO_NAME: ${{ github.repository }}
- name: Check out repository code
uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4.1.0
- name: Install poetry
run: pipx install poetry
- name: Set up Python
uses: actions/setup-python@65d7f2d534ac1bc67fcd62888c5f4f3d2cb2b236 # v4.7.1
with:
python-version: ${{ env.PYTHON_VERSION }}
cache: "poetry" # NOTE: poetry must be installed before this step, or else cache doesn't work
- name: Set up Node
uses: actions/setup-node@5e21ff4d9bc1a8cf6de233a3057d20ec6b3fb69d # v3.8.1
with:
node-version: ${{ env.NODE_VERSION }}
cache: "npm"
- name: Install dependencies
run: make dev
# NOTE: unit tests are connecting to AWS to instantiate boto3 clients/resources
# once that's discussed we can move unit and infra tests as part of the fast quality standards
# see https://github.com/ran-isenberg/serverless-python-demo/pull/38#discussion_r1299372169
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@010d0da01d0b5a38af31e9c3470dbfdabdecca3a # v4.0.1
with:
role-to-assume: ${{ secrets['AWS_ROLE'] }}
role-session-name: ${{ env.SESSION_NAME }}
aws-region: ${{ env.AWS_REGION }}
env:
SESSION_NAME: "github-${{github.sha}}-staging"
- name: Deploy to AWS
run: make deploy
env:
ENVIRONMENT: staging # Custom environment variable
# NOTE: these run unit and integration tests
# we can look into coverage collection only later to make it faster and less brittle (--collect-only)
- name: Code coverage tests
run: make coverage-tests
env:
ENVIRONMENT: staging # Custom environment variable
- name: Codecov
uses: codecov/codecov-action@eaaf4bedf32dbdc6b720b63067d99c4d77d6047d # v3.1.4
with:
files: ./coverage.xml
fail_ci_if_error: false # optional (default = false)
verbose: false # optional (default = false)
- name: Run E2E tests
run: make e2e
env:
ENVIRONMENT: staging # Custom environment variable

production:
runs-on: ubuntu-latest
needs: [staging]
environment: production
permissions:
id-token: write # required for requesting the JWT (GitHub OIDC)
steps:
- run: |
echo "🎉 The job was automatically triggered by a ${{ env.EVENT_NAME }} event." >> $GITHUB_STEP_SUMMARY
echo "🐧 This job is now running on a ${{ env.OS_NAME }} ${{env.OS_ARCH}} server hosted by GitHub!" >> $GITHUB_STEP_SUMMARY
echo "🔎 The name of your branch is ${{ env.BRANCH_NAME }} and your repository is ${{ env.REPO_NAME }}." >> $GITHUB_STEP_SUMMARY
env:
EVENT_NAME: ${{ github.event_name}}
OS_NAME: ${{ runner.os }}
OS_ARCH: ${{runner.arch }}
BRANCH_NAME: ${{ github.ref }}
REPO_NAME: ${{ github.repository }}
- name: Check out repository code
uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4.1.0
- name: Install poetry
run: pipx install poetry
- name: Set up Python
uses: actions/setup-python@65d7f2d534ac1bc67fcd62888c5f4f3d2cb2b236 # v4.7.1
with:
python-version: ${{ env.PYTHON_VERSION }}
cache: "poetry" # NOTE: poetry must be installed before this step, or else cache doesn't work
- name: Set up Node
uses: actions/setup-node@5e21ff4d9bc1a8cf6de233a3057d20ec6b3fb69d # v3.8.1
with:
node-version: ${{ env.NODE_VERSION }}
cache: "npm"
- name: Install dependencies
run: make dev
# NOTE: unit tests are connecting to AWS to instantiate boto3 clients/resources
# once that's discussed we can move unit and infra tests as part of the fast quality standards
# see https://github.com/ran-isenberg/serverless-python-demo/pull/38#discussion_r1299372169
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@010d0da01d0b5a38af31e9c3470dbfdabdecca3a # v4.0.1
with:
role-to-assume: ${{ secrets['AWS_ROLE'] }}
role-session-name: ${{ env.SESSION_NAME }}
aws-region: ${{ env.AWS_REGION }}
env:
SESSION_NAME: "github-${{github.sha}}-production"
- name: Deploy to AWS
run: make deploy
env:
ENVIRONMENT: production # Custom environment variable

publish_github_pages:
runs-on: ubuntu-latest
needs: [production]
permissions:
contents: write # for docs push
if: contains('refs/heads/main', github.ref)
steps:
- name: Check out repository code
uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4.1.0
- name: Set up Python
uses: actions/setup-python@65d7f2d534ac1bc67fcd62888c5f4f3d2cb2b236 # v4.7.1
with:
python-version: ${{ env.PYTHON_VERSION }}
- name: Set up Node
uses: actions/setup-node@5e21ff4d9bc1a8cf6de233a3057d20ec6b3fb69d # v3.8.1
with:
node-version: ${{ env.NODE_VERSION }}
cache: "npm"
- name: Install dependencies
run: make dev
- name: Generate docs
run: |
poetry run mkdocs gh-deploy --force
104 changes: 104 additions & 0 deletions {{cookiecutter.repo_name}}/.github/workflows/pr-serverless-service.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
# This workflow will install Python dependencies, run tests and lint with a single version of Python
# For more information see: https://help.github.com/actions/language-and-framework-guides/using-python-with-github-actions
name: PR - Serverless Service CI/CD

permissions:
contents: read

env:
NODE_VERSION: "18"
PYTHON_VERSION: "3.11"
AWS_REGION: "us-east-1"

on:
workflow_dispatch:

pull_request:
branches: [main]

jobs:
quality_standards:
runs-on: ubuntu-latest
steps:
- run: |
echo "🎉 The job was automatically triggered by a ${{ env.EVENT_NAME }} event." >> $GITHUB_STEP_SUMMARY
echo "🐧 This job is now running on a ${{ env.OS_NAME }} ${{env.OS_ARCH}} server hosted by GitHub!" >> $GITHUB_STEP_SUMMARY
echo "🔎 The name of your branch is ${{ env.BRANCH_NAME }} and your repository is ${{ env.REPO_NAME }}." >> $GITHUB_STEP_SUMMARY
env:
EVENT_NAME: ${{ github.event_name}}
OS_NAME: ${{ runner.os }}
OS_ARCH: ${{runner.arch }}
BRANCH_NAME: ${{ github.ref }}
REPO_NAME: ${{ github.repository }}
- name: Check out repository code
uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4.1.0
- name: Install poetry
run: pipx install poetry
- name: Set up Python
uses: actions/setup-python@65d7f2d534ac1bc67fcd62888c5f4f3d2cb2b236 # v4.7.1
with:
python-version: ${{ env.PYTHON_VERSION }}
cache: "poetry" # NOTE: poetry must be installed before this step, or else cache doesn't work
- name: Install dependencies
run: make dev
- name: pre commit
run: make pre-commit
- name: Formatting and Linting
run: make lint
- name: Complexity scan
run: make complex
tests:
needs: quality_standards
runs-on: ubuntu-latest
environment: dev
permissions:
id-token: write # required for requesting the JWT (GitHub OIDC)
steps:
- name: Check out repository code
uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4.1.0
- name: Install poetry
run: pipx install poetry
- name: Set up Python
uses: actions/setup-python@65d7f2d534ac1bc67fcd62888c5f4f3d2cb2b236 # v4.7.1
with:
python-version: ${{ env.PYTHON_VERSION }}
cache: "poetry" # NOTE: poetry must be installed before this step, or else cache doesn't work
- name: Set up Node
uses: actions/setup-node@5e21ff4d9bc1a8cf6de233a3057d20ec6b3fb69d # v3.8.1
with:
node-version: ${{ env.NODE_VERSION }}
cache: "npm"
- name: Install dependencies
run: make dev
# NOTE: unit tests are connecting to AWS to instantiate boto3 clients/resources
# once that's discussed we can move unit and infra tests as part of the fast quality standards
# see https://github.com/ran-isenberg/serverless-python-demo/pull/38#discussion_r1299372169
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@010d0da01d0b5a38af31e9c3470dbfdabdecca3a # v4.0.1
with:
role-to-assume: ${{ secrets.AWS_ROLE }}
role-session-name: ${{ env.SESSION_NAME }}
aws-region: ${{ env.AWS_REGION }}
env:
SESSION_NAME: "github-${{github.sha}}-dev"
- name: Unit tests
run: make unit
- name: Infrastructure tests
run: make infra-tests
- name: Deploy to AWS
run: make deploy
# NOTE: these run unit and integration tests
# we can look into coverage collection only later to make it faster and less brittle (--collect-only)
- name: Code coverage tests
run: make coverage-tests
- name: Codecov
uses: codecov/codecov-action@eaaf4bedf32dbdc6b720b63067d99c4d77d6047d # v3.1.4
with:
files: ./coverage.xml
fail_ci_if_error: false # optional (default = false)
verbose: false # optional (default = false)
- name: Run E2E tests
run: make e2e
- name: Destroy stack
if: always()
run: make destroy
Loading

0 comments on commit bb4744a

Please sign in to comment.