Finishing up my website using AWS SAM
Lab 67
Services Covered
-
SAM AWS SAM
Lab description
Second part of my Cloud Resume Challenge SAM deployment. I’ve already deployed the website, API and Lambda. I will finish up the template by creating a DynamoDB table, two Lambda functions, one for updating the visitors count and second for getting the latest value. The deployment will be moved to more of a CI/CD kind of manner that is GitHub actions, so whenever I commit new code the workflow will initiate AWS SAM Build & Deploy as well as two test run within the workflow.
Lab date
25-10-2021
Prerequisites
- AWS account,
- SAM CLI installed
- Recommended: aws-vault
- Docker installed, for local Lambda functions testing purposes
Lab steps
- In the SAM template I create a new DynamoDB resource:
DynamoDBTable: Type: AWS::DynamoDB::Table Properties: TableName: cloud-resume-challenge BillingMode: PAY_PER_REQUEST AttributeDefinitions: - AttributeName: "ID" AttributeType: "S" KeySchema: - AttributeName: "ID" KeyType: "HASH"
- Then I created two Lambda functions:
GetCountFunction: Type: AWS::Serverless::Function Properties: CodeUri: get-function/ Handler: app.lambda_handler Runtime: python3.9 Architectures: - x86_64 Events: HelloWorld: Type: Api Properties: Path: /get Method: get PutCountFunction: Type: AWS::Serverless::Function Properties: Policies: - DynamoDBCrudPolicy: TableName: cloud-resume-challenge CodeUri: put-function/ Handler: app.lambda_handler Runtime: python3.9 Architectures: - x86_64 Events: HelloWorld: Type: Api Properties: Path: /put Method: get
- For testing purposes I run the code locally using the sam local invoke command that created a Docker Image
sam build && aws-vault exec sam-user --no-session -- sam local invoke PutCountFunction
- The index.html need a JavaScript that would fetch the latest count from the DynamoDB table.
<script type = "text/javascript"> var apiUrl = "https://.eu-north-1.amazonaws.com/Prod/put"; fetch(apiUrl) .then(() => fetch("https://<<YOUR_API>>.eu-north-1.amazonaws.com/Prod/get")) .then(response => response.json()) .then(data =>{ document.getElementById('body').innerHTML = data console.log(data)}); </script>
- I’ve set up the CI/CD pipeline on GitHub Actions. The pipeline activates on me pushing the code starting with SAM validation, Build and Deploy. I included two test so called integration test which is just a simple curl command chain and a end to end JavaScript test :
name: SAM Validate, Test, Build, Deploy on: push: branches: [ main ] jobs: build-and-deploy-infra: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - uses: actions/setup-python@v2 with: python-version: '3.9' - uses: aws-actions/setup-sam@v1 - uses: aws-actions/configure-aws-credentials@v1 with: aws-access-key-id: ${{ secrets.ACCESS_KEY }} aws-secret-access-key: ${{ secrets.SECRET_ACCESS_KEY }} aws-region: eu-north-1 - name: SAM Validate run: | sam validate - name: SAM Build run: | sam build - name: SAM Deploy run: | sam deploy --no-confirm-changeset --no-fail-on-empty-changeset integration-test-backend: needs: build-and-deploy-infra runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - run: make integration-test end-to-end-test: needs: integration-test-backend runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - uses: actions/setup-node@v2 with: node-version: 14 - run: cd tests/end-to-end-test && npm install && node index.js