botocore.exceptions.NoRegionError: You must specify a region. GitHub Actions with CI/CD Pipeline with AWS

Question:

I am trying to reproduce, step-by-step, the instructions on this video "Cloud Resume Challenge Sprint (Sept, 2022) – Week 4" from youtube, https://youtu.be/wiyI0Ngn31o, on how to setup GitHub Actions with CD/CI pipeline for Backend testing with Python for SAM Deployment in AWS.

I have followed the video’s instructions, step-by-step; however, when I push my mail.yml file to the GitHub repository, I get the following error message from GitHub Actions:

Run pytest
============================= test session starts ==============================
platform linux -- Python 3.8.15, pytest-7.2.0, pluggy-1.0.0
rootdir: /home/runner/work/cloud-resume-challenge/cloud-resume-challenge
plugins: mock-3.10.0
collected 0 items / 1 error

==================================== ERRORS ====================================
_ ERROR collecting serverless-architecture-with-SAM/hello_world/tests/test_handler.py _
serverless-architecture-with-SAM/hello_world/tests/test_handler.py:6: in <module>
    from hello_world import app
serverless-architecture-with-SAM/hello_world/app.py:4: in <module>
    dynamodb = boto3.resource('dynamodb')
/opt/hostedtoolcache/Python/3.8.15/x64/lib/python3.8/site-packages/boto3/__init__.py:101: in resource
    return _get_default_session().resource(*args, **kwargs)
/opt/hostedtoolcache/Python/3.8.15/x64/lib/python3.8/site-packages/boto3/session.py:446: in resource
    client = self.client(
/opt/hostedtoolcache/Python/3.8.15/x64/lib/python3.8/site-packages/boto3/session.py:299: in client
    return self._session.create_client(
/opt/hostedtoolcache/Python/3.8.15/x64/lib/python3.8/site-packages/botocore/session.py:976: in create_client
    client = client_creator.create_client(
/opt/hostedtoolcache/Python/3.8.15/x64/lib/python3.8/site-packages/botocore/client.py:155: in create_client
    client_args = self._get_client_args(
/opt/hostedtoolcache/Python/3.8.15/x64/lib/python3.8/site-packages/botocore/client.py:485: in _get_client_args
    return args_creator.get_client_args(
/opt/hostedtoolcache/Python/3.8.15/x64/lib/python3.8/site-packages/botocore/args.py:92: in get_client_args
    final_args = self.compute_client_args(
/opt/hostedtoolcache/Python/3.8.15/x64/lib/python3.8/site-packages/botocore/args.py:205: in compute_client_args
    endpoint_config = self._compute_endpoint_config(
/opt/hostedtoolcache/Python/3.8.15/x64/lib/python3.8/site-packages/botocore/args.py:313: in _compute_endpoint_config
    return self._resolve_endpoint(**resolve_endpoint_kwargs)
/opt/hostedtoolcache/Python/3.8.15/x64/lib/python3.8/site-packages/botocore/args.py:418: in _resolve_endpoint
    return endpoint_bridge.resolve(
/opt/hostedtoolcache/Python/3.8.15/x64/lib/python3.8/site-packages/botocore/client.py:590: in resolve
    resolved = self.endpoint_resolver.construct_endpoint(
/opt/hostedtoolcache/Python/3.8.15/x64/lib/python3.8/site-packages/botocore/regions.py:229: in construct_endpoint
    result = self._endpoint_for_partition(
/opt/hostedtoolcache/Python/3.8.15/x64/lib/python3.8/site-packages/botocore/regions.py:277: in _endpoint_for_partition
    raise NoRegionError()
E   botocore.exceptions.NoRegionError: You must specify a region.
=========================== short test summary info ============================
ERROR serverless-architecture-with-SAM/hello_world/tests/test_handler.py - botocore.exceptions.NoRegionError: You must specify a region.
!!!!!!!!!!!!!!!!!!!! Interrupted: 1 error during collection !!!!!!!!!!!!!!!!!!!!
=============================== 1 error in 0.40s ===============================
Error: Process completed with exit code 2.

Here is a copy of my mail.yml file:

name: main
on: push


jobs:
  test-infra:
    runs-on: ubuntu-latest
    timeout-minutes: 2
    steps:
      - uses: actions/checkout@v2
      - uses: actions/setup-python@v1
        with:
          python-version: 3.8
      - name: Install dependencies
        run: |
          cd serverless-architecture-with-SAM/hello_world/tests
          python -m pip install --upgrade pip
          pip install -r requirements.txt
      - name: Run tests with pytest
        env:
          AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
          AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
          aws-region: us-east-1
        run: pytest

  build-and-deploy-infra:
    needs: test-infra
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - uses: actions/setup-python@v2
      - uses: aws-actions/setup-sam@v1
      - uses: aws-actions/configure-aws-credentials@v1
        with:
          aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
          aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
          aws-region: us-east-1
      - run: sam build
        working-directory: serverless-architecture-with-SAM
      - run: sam deploy --no-confirm-changeset --no-fail-on-empty-changeset
        working-directory: serverless-architecture-with-SAM

  deploy-site:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - uses: jakejarvis/s3-sync-action@master
        with:
          args: --delete
        env:
          AWS_S3_BUCKET: justinhenson-cloud-resume-website
          AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
          AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
          SOURCE_DIR: serverless-architecture-with-SAM/resume-site

Here is the file structure in my GitHub Repo: https://github.com/justin-henson/cloud-resume-challenge

account/cloud-resume-challenge
   .github/
       workflows/
           main.yml
   serverless-architecture-with-SAM/
       hello_world/
           tests/
               __init__.py
               requirements.txt
               test_handler.py
           __init__.py
           app.py
           requirements.txt
       resume-site/
           css/
           img/
           js/ 
           index.html
       Makefile
       README.md
       samconfig.toml
       template.yaml
   .gitignore

And the contents of my test_handler.py file:

import os
import re
import json
from unittest import mock

from hello_world import app

with open('serverless-architecture-with-SAM/template.yaml', 'r') as f:
    TABLENAME = re.search(r'TableName: (.*)?', f.read()).group(1)

@mock.patch.dict(os.environ, {"TABLENAME": TABLENAME})
def test_lambda_handler():
    # Check AWS creds
    assert "AWS_ACCESS_KEY_ID" in os.environ
    assert "AWS_SECRET_ACCESS_KEY" in os.environ

    ret = app.lambda_handler("", "")

    # Assert return keys
    assert "statusCode" in ret
    assert "headers" in ret
    assert "body" in ret

    # Check for CORS in Headers
    assert "Access-Control-Allow-Origin"  in ret["headers"]
    assert "Access-Control-Allow-Methods" in ret["headers"]
    assert "Access-Control-Allow-Headers" in ret["headers"]

    # Check status code
    if ret["statusCode"] == 200:
        assert "visit_count" in ret["body"]
        assert json.loads(ret["body"])["visit_count"].isnumeric()
    else:
        assert json.loads(ret["body"])["visit_count"] == -1

    return

I have tried adding the following to my test_handler.py file as mentioned in this question, but with no success:

os.environ['AWS_DEFAULT_REGION'] = 'your_region_name'
Asked By: Justin Henson

||

Answers:

On test-infra job’s environment variable section add AWS_DEFAULT_REGION: us-east-1

You define aws-region but AWS_DEFAULT_REGION is case sensitive.

Answered By: Mehmet Güngören