From 568454941018928a9f61073aa2673bbd67a84035 Mon Sep 17 00:00:00 2001 From: suryabulusu Date: Thu, 25 Aug 2022 18:43:59 +0530 Subject: [PATCH 01/10] inits ci cd setup --- app/internal/db.py | 7 ++++++- app/main.py | 23 ++++++++++++++++++----- app/requirements.txt | 24 ++++++++++++++++++++++++ 3 files changed, 48 insertions(+), 6 deletions(-) create mode 100644 app/requirements.txt diff --git a/app/internal/db.py b/app/internal/db.py index e4a0077..189b8c5 100644 --- a/app/internal/db.py +++ b/app/internal/db.py @@ -2,7 +2,12 @@ from dotenv import load_dotenv import os -load_dotenv(".env.local") +# when running app locally -- use load_dotenv +# when running app via gh actions -- variables already exist via secrets +# so no need to load_dotenv +# checking only for secret key as of now +if "DYNAMODB_SECRET_KEY" not in os.environ: + load_dotenv("../.env.local") def initialize_db(): diff --git a/app/main.py b/app/main.py index 469a6fb..2b90717 100644 --- a/app/main.py +++ b/app/main.py @@ -1,5 +1,6 @@ -import uvicorn from fastapi import FastAPI +from fastapi.middleware.cors import CORSMiddleware +from mangum import Mangum from internal.db import initialize_db @@ -12,7 +13,20 @@ app = FastAPI() -app.mount("/static", StaticFiles(directory="app/static"), name="static") +origins = [ + "http://localhost:5050", + "https://report-staging.avantifellows.org", + "https://reporting.avantifellows.org", +] + +app.add_middleware( + CORSMiddleware, + allow_origins=origins, + allow_methods=["*"], + allow_headers=["*"], +) + +app.mount("/static", StaticFiles(directory="static"), name="static") db = initialize_db() @@ -29,8 +43,7 @@ @app.get("/") def index(): - return "Hello World!" + return "Hello World! Welcome to Reporting Engine!" -if __name__ == "__main__": - uvicorn.run("main:app", host="0.0.0.0", port=5050, log_level="info", reload=True) +handler = Mangum(app) diff --git a/app/requirements.txt b/app/requirements.txt new file mode 100644 index 0000000..10810a7 --- /dev/null +++ b/app/requirements.txt @@ -0,0 +1,24 @@ +anyio==3.6.1 +autopep8==1.6.0 +boto3==1.24.35 +botocore==1.27.35 +click==8.1.3 +fastapi==0.79.0 +h11==0.13.0 +idna==3.3 +Jinja2==3.1.2 +jmespath==1.0.1 +MarkupSafe==2.1.1 +pycodestyle==2.8.0 +pydantic==1.9.1 +python-dateutil==2.8.2 +python-dotenv==0.20.0 +s3transfer==0.6.0 +six==1.16.0 +sniffio==1.2.0 +starlette==0.19.1 +toml==0.10.2 +typing_extensions==4.3.0 +urllib3==1.26.10 +uvicorn==0.18.2 +mangum==0.14.1 From b09d4712b15e39a23defb6f9475f0e8977e65cb1 Mon Sep 17 00:00:00 2001 From: suryabulusu Date: Thu, 25 Aug 2022 18:47:55 +0530 Subject: [PATCH 02/10] deletes internal --- .github/workflows/deploy_to_prod.yml | 43 +++++++++++++++++++++++ .github/workflows/deploy_to_staging.yml | 43 +++++++++++++++++++++++ internal/__init__.py | 0 internal/__main__.py | 36 ------------------- internal/student_quiz_reports.py | 30 ---------------- requirements.txt | 1 + templates/prod.yaml | 46 +++++++++++++++++++++++++ templates/staging.yaml | 46 +++++++++++++++++++++++++ 8 files changed, 179 insertions(+), 66 deletions(-) create mode 100644 .github/workflows/deploy_to_prod.yml create mode 100644 .github/workflows/deploy_to_staging.yml delete mode 100644 internal/__init__.py delete mode 100644 internal/__main__.py delete mode 100644 internal/student_quiz_reports.py create mode 100644 templates/prod.yaml create mode 100644 templates/staging.yaml diff --git a/.github/workflows/deploy_to_prod.yml b/.github/workflows/deploy_to_prod.yml new file mode 100644 index 0000000..6fd3a33 --- /dev/null +++ b/.github/workflows/deploy_to_prod.yml @@ -0,0 +1,43 @@ +# This workflow will update the code for the production environment + +on: + pull_request: + push: + branches: ["release"] + +name: Deploy to production + +jobs: + build_and_deploy: + name: Deploy + environment: + name: Production + + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v2 + + - name: Set up Python + uses: actions/setup-python@v2 + + - name: Set up SAM + uses: aws-actions/setup-sam@v1 + + - name: Configure AWS Credentials + 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 + + - name: Build + run: sam build --use-container -t templates/prod.yaml + + - name: Deploy + env: + DYNAMODB_URL: ${{ secrets.DYNAMODB_URL }} + DYNAMODB_REGION: ${{ secrets.DYNAMODB_REGION }} + DYNAMODB_ACCESS_KEY: ${{ secrets.DYNAMODB_ACCESS_KEY }} + DYNAMODB_SECRET_KEY: ${{ secrets.DYNAMODB_SECRET_KEY }} + run: sam deploy --stack-name ReportingProduction --s3-bucket reporting-engine-production --no-confirm-changeset --no-fail-on-empty-changeset --region ap-south-1 --capabilities CAPABILITY_IAM --parameter-overrides DynamodbUrl=$DYNAMODB_URL DynamodbRegion=$DYNAMODB_REGION DynamodbAccessKey=$DYNAMODB_ACCESS_KEY DynamodbSecretKey=$DYNAMODB_SECRET_KEY \ No newline at end of file diff --git a/.github/workflows/deploy_to_staging.yml b/.github/workflows/deploy_to_staging.yml new file mode 100644 index 0000000..ee300ec --- /dev/null +++ b/.github/workflows/deploy_to_staging.yml @@ -0,0 +1,43 @@ +# This workflow will update the code for the staging environment + +on: + pull_request: + push: + branches: ["main"] + +name: Deploy to staging + +jobs: + build_and_deploy: + name: Deploy + environment: + name: Staging + + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v2 + + - name: Set up Python + uses: actions/setup-python@v2 + + - name: Set up SAM + uses: aws-actions/setup-sam@v1 + + - name: Configure AWS Credentials + 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 + + - name: Build + run: sam build --use-container -t templates/staging.yaml + + - name: Deploy + env: + DYNAMODB_URL: ${{ secrets.DYNAMODB_URL }} + DYNAMODB_REGION: ${{ secrets.DYNAMODB_REGION }} + DYNAMODB_ACCESS_KEY: ${{ secrets.DYNAMODB_ACCESS_KEY }} + DYNAMODB_SECRET_KEY: ${{ secrets.DYNAMODB_SECRET_KEY }} + run: sam deploy --stack-name ReportingStaging --s3-bucket reporting-engine-staging --no-confirm-changeset --no-fail-on-empty-changeset --region ap-south-1 --capabilities CAPABILITY_IAM --parameter-overrides DynamodbUrl=$DYNAMODB_URL DynamodbRegion=$DYNAMODB_REGION DynamodbAccessKey=$DYNAMODB_ACCESS_KEY DynamodbSecretKey=$DYNAMODB_SECRET_KEY \ No newline at end of file diff --git a/internal/__init__.py b/internal/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/internal/__main__.py b/internal/__main__.py deleted file mode 100644 index e1427c2..0000000 --- a/internal/__main__.py +++ /dev/null @@ -1,36 +0,0 @@ -from student_quiz_reports import ( - generate_student_quiz_reports, - drop_student_quiz_reports, -) -import boto3 -from dotenv import load_dotenv - -import os - -load_dotenv(".env.local") - - -def initialize_db(): - ddb = boto3.resource( - "dynamodb", - endpoint_url=os.environ.get("DYNAMODB_URL"), - region_name=os.environ.get("DYNAMODB_REGION"), - aws_access_key_id=os.environ.get("DYNAMODB_ACCESS_KEY"), - aws_secret_access_key=os.environ.get("DYNAMODB_SECRET_KEY"), - ) - - return ddb - - -def generate_tables(): - ddb = initialize_db() - generate_student_quiz_reports(ddb) - - -def drop_tables(): - ddb = initialize_db() - drop_student_quiz_reports(ddb) - - -if __name__ == "__main__": - generate_tables() diff --git a/internal/student_quiz_reports.py b/internal/student_quiz_reports.py deleted file mode 100644 index a803abd..0000000 --- a/internal/student_quiz_reports.py +++ /dev/null @@ -1,30 +0,0 @@ -def generate_student_quiz_reports(ddb): - ddb.create_table( - TableName="student_quiz_reports", - AttributeDefinitions=[ - {"AttributeName": "id", "AttributeType": "S"}, - {"AttributeName": "quiz_id", "AttributeType": "S"}, - {"AttributeName": "student_id", "AttributeType": "S"}, - ], - KeySchema=[{"AttributeName": "id", "KeyType": "HASH"}], - GlobalSecondaryIndexes=[ - { - "IndexName": "quiz_id", - "KeySchema": [ - {"AttributeName": "quiz_id", "KeyType": "HASH"}, - {"AttributeName": "student_id", "KeyType": "RANGE"}, - ], - "Projection": { - "ProjectionType": "ALL", - }, - }, - ], - BillingMode="PAY_PER_REQUEST", - ProvisionedThroughput={"ReadCapacityUnits": 10, "WriteCapacityUnits": 10}, - ) - print("Successfully created Student Quiz Reports Table") - - -def drop_student_quiz_reports(ddb): - table = ddb.Table("student_quiz_reports") - table.delete() diff --git a/requirements.txt b/requirements.txt index 8c197de..10810a7 100644 --- a/requirements.txt +++ b/requirements.txt @@ -21,3 +21,4 @@ toml==0.10.2 typing_extensions==4.3.0 urllib3==1.26.10 uvicorn==0.18.2 +mangum==0.14.1 diff --git a/templates/prod.yaml b/templates/prod.yaml new file mode 100644 index 0000000..0bd2ceb --- /dev/null +++ b/templates/prod.yaml @@ -0,0 +1,46 @@ +AWSTemplateFormatVersion: "2010-09-09" +Transform: AWS::Serverless-2016-10-31 +Description: Reporting Engine - Production - FastAPI on Lambda + +Parameters: + DynamodbUrl: + Type: String + Description: Url of Dynamodb instance + DynamodbRegion: + Type: String + Description: Region of Dynamodb instance + DynamodbAccessKey: + Type: String + Description: Access key credentials of Dynamodb instance + DynamodbSecretKey: + Type: String + Description: Secret key credentials of Dynamodb instance + +Resources: + Function: + Type: AWS::Serverless::Function + Properties: + FunctionName: "ReportingProduction" + CodeUri: ../app + Handler: main.handler + Runtime: python3.9 + Environment: + Variables: + DYNAMODB_URL: !Ref DynamodbUrl + DYNAMODB_REGION: !Ref DynamodbRegion + DYNAMODB_ACCESS_KEY: !Ref DynamodbAccessKey + DYNAMODB_SECRET_KEY: !Ref DynamodbSecretKey + Events: + Api: + Type: HttpApi + Properties: + ApiId: !Ref Api + + Api: + Type: AWS::Serverless::HttpApi + +Outputs: + ApiUrl: + Description: URL of your API + Value: + Fn::Sub: "https://${Api}.execute-api.${AWS::Region}.${AWS::URLSuffix}/" \ No newline at end of file diff --git a/templates/staging.yaml b/templates/staging.yaml new file mode 100644 index 0000000..fa6b919 --- /dev/null +++ b/templates/staging.yaml @@ -0,0 +1,46 @@ +AWSTemplateFormatVersion: "2010-09-09" +Transform: AWS::Serverless-2016-10-31 +Description: Reporting Engine - Staging - FastAPI on Lambda + +Parameters: + DynamodbUrl: + Type: String + Description: Url of Dynamodb instance + DynamodbRegion: + Type: String + Description: Region of Dynamodb instance + DynamodbAccessKey: + Type: String + Description: Access key credentials of Dynamodb instance + DynamodbSecretKey: + Type: String + Description: Secret key credentials of Dynamodb instance + +Resources: + Function: + Type: AWS::Serverless::Function + Properties: + FunctionName: "ReportingStaging" + CodeUri: ../app + Handler: main.handler + Runtime: python3.9 + Environment: + Variables: + DYNAMODB_URL: !Ref DynamodbUrl + DYNAMODB_REGION: !Ref DynamodbRegion + DYNAMODB_ACCESS_KEY: !Ref DynamodbAccessKey + DYNAMODB_SECRET_KEY: !Ref DynamodbSecretKey + Events: + Api: + Type: HttpApi + Properties: + ApiId: !Ref Api + + Api: + Type: AWS::Serverless::HttpApi + +Outputs: + ApiUrl: + Description: URL of your API + Value: + Fn::Sub: "https://${Api}.execute-api.${AWS::Region}.${AWS::URLSuffix}/" \ No newline at end of file From 5bdd39331c6994fee4b33a659488ef8470c4d050 Mon Sep 17 00:00:00 2001 From: suryabulusu Date: Thu, 25 Aug 2022 18:55:15 +0530 Subject: [PATCH 03/10] prod deployment only for release push --- .github/workflows/deploy_to_prod.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/deploy_to_prod.yml b/.github/workflows/deploy_to_prod.yml index 6fd3a33..6e80881 100644 --- a/.github/workflows/deploy_to_prod.yml +++ b/.github/workflows/deploy_to_prod.yml @@ -1,7 +1,6 @@ # This workflow will update the code for the production environment on: - pull_request: push: branches: ["release"] From 9f64d3cb7976c143e77d27495d879a6565446365 Mon Sep 17 00:00:00 2001 From: suryabulusu Date: Mon, 29 Aug 2022 16:36:07 +0530 Subject: [PATCH 04/10] minor bug in template path --- app/routers/reports.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/routers/reports.py b/app/routers/reports.py index 025bdc5..ec768bb 100644 --- a/app/routers/reports.py +++ b/app/routers/reports.py @@ -23,7 +23,7 @@ def __init__( self, student_quiz_reports_controller: StudentQuizReportController ) -> None: self.__student_quiz_reports_controller = student_quiz_reports_controller - self._templates = Jinja2Templates(directory="app/templates") + self._templates = Jinja2Templates(directory="templates") @property def router(self): From 6e6ad366a8906df1cc6f637addc6b0c7f129c7e3 Mon Sep 17 00:00:00 2001 From: suryabulusu Date: Mon, 29 Aug 2022 16:36:31 +0530 Subject: [PATCH 05/10] updates readme --- README.md | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index fd27443..04d6ea5 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ Welcome to the AF Reporting Engine! -## Installation and First Run +## Installation and First Run (via Docker) 0. Install pre-commit hooks in the repo ``` @@ -30,10 +30,14 @@ python generate_table This will create the the `student_quiz_reports` table. -## Accessing things +### Accessing things DynamoDB Admin: localhost:8001 Reporting FastAPI Server: localhost:5050 (docs and API tryout at localhost:5050/docs) DynamoDB server: localhost:8000 (we won't access this directly) + + +## Connect with DynamoDB Server + From a9ec7280e22d14dba6f96398e45030281044af92 Mon Sep 17 00:00:00 2001 From: Surya Bulusu Date: Thu, 1 Sep 2022 10:15:06 +0530 Subject: [PATCH 06/10] Split long command to multiple lines Co-authored-by: Deepansh Mathur --- .github/workflows/deploy_to_prod.yml | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/.github/workflows/deploy_to_prod.yml b/.github/workflows/deploy_to_prod.yml index 6e80881..f6e589d 100644 --- a/.github/workflows/deploy_to_prod.yml +++ b/.github/workflows/deploy_to_prod.yml @@ -39,4 +39,16 @@ jobs: DYNAMODB_REGION: ${{ secrets.DYNAMODB_REGION }} DYNAMODB_ACCESS_KEY: ${{ secrets.DYNAMODB_ACCESS_KEY }} DYNAMODB_SECRET_KEY: ${{ secrets.DYNAMODB_SECRET_KEY }} - run: sam deploy --stack-name ReportingProduction --s3-bucket reporting-engine-production --no-confirm-changeset --no-fail-on-empty-changeset --region ap-south-1 --capabilities CAPABILITY_IAM --parameter-overrides DynamodbUrl=$DYNAMODB_URL DynamodbRegion=$DYNAMODB_REGION DynamodbAccessKey=$DYNAMODB_ACCESS_KEY DynamodbSecretKey=$DYNAMODB_SECRET_KEY \ No newline at end of file +run: > + sam deploy + --stack-name ReportingProduction + --s3-bucket reporting-engine-production + --no-confirm-changeset + --no-fail-on-empty-changeset + --region ap-south-1 + --capabilities CAPABILITY_IAM + --parameter-overrides + DynamodbUrl=$DYNAMODB_URL + DynamodbRegion=$DYNAMODB_REGION + DynamodbAccessKey=$DYNAMODB_ACCESS_KEY + DynamodbSecretKey=$DYNAMODB_SECRET_KEY \ No newline at end of file From b6c89b07545fa92b36c3a77f8783bc6d45742b28 Mon Sep 17 00:00:00 2001 From: suryabulusu Date: Thu, 1 Sep 2022 10:19:44 +0530 Subject: [PATCH 07/10] updates readme --- README.md | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 04d6ea5..ef9cb18 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ Welcome to the AF Reporting Engine! -## Installation and First Run (via Docker) +## Setting up the Reporting Engine locally 0. Install pre-commit hooks in the repo ``` @@ -40,4 +40,20 @@ DynamoDB server: localhost:8000 (we won't access this directly) ## Connect with DynamoDB Server +0. Install pre-commit hooks in the repo +``` +pip install pre-commit +pre-commit install +``` +1. Obtain credentials to replace local keys in `.env.local` file from repository owners. + +2. Run the following to get app at `localhost:5050/docs` +``` +cd app; uvicorn main:app --port 5050 --reload +``` +### Deployment +We deploy our FastAPI instance on AWS Lambda which is triggered via an API Gateway. In order to automate the process, we use AWS SAM, which creates the stack required for deployment and updates it as needed with just a couple of commands and without having to do anything manually on the AWS GUI. Refer to this [blog](https://www.eliasbrange.dev/posts/deploy-fastapi-on-aws-part-1-lambda-api-gateway/) post for more details. + +The actual deployment happens through Github Actions. Look at `.github/workflows/deploy_to_staging.yml` to understand the deployment to Staging and `.github/workflows/deploy_to_prod.yml` for Production. +The details of the AWS Lambda instances are described in `templates/prod.yaml` and `templates/staging.yaml`. \ No newline at end of file From 6bacf4f277f3eeca6678d516424be1acb92cb192 Mon Sep 17 00:00:00 2001 From: suryabulusu Date: Thu, 1 Sep 2022 11:37:58 +0530 Subject: [PATCH 08/10] removes cors --- app/internal/db.py | 4 +++- app/main.py | 14 -------------- 2 files changed, 3 insertions(+), 15 deletions(-) diff --git a/app/internal/db.py b/app/internal/db.py index 189b8c5..1694f30 100644 --- a/app/internal/db.py +++ b/app/internal/db.py @@ -6,7 +6,9 @@ # when running app via gh actions -- variables already exist via secrets # so no need to load_dotenv # checking only for secret key as of now -if "DYNAMODB_SECRET_KEY" not in os.environ: +if not all(key in os.environ for key in + ["DYNAMODB_URL", "DYNAMODB_REGION", + "DYNAMODB_ACCESS_KEY", "DYNAMODB_SECRET_KEY"]): load_dotenv("../.env.local") diff --git a/app/main.py b/app/main.py index 2b90717..4b1cccc 100644 --- a/app/main.py +++ b/app/main.py @@ -1,5 +1,4 @@ from fastapi import FastAPI -from fastapi.middleware.cors import CORSMiddleware from mangum import Mangum from internal.db import initialize_db @@ -13,19 +12,6 @@ app = FastAPI() -origins = [ - "http://localhost:5050", - "https://report-staging.avantifellows.org", - "https://reporting.avantifellows.org", -] - -app.add_middleware( - CORSMiddleware, - allow_origins=origins, - allow_methods=["*"], - allow_headers=["*"], -) - app.mount("/static", StaticFiles(directory="static"), name="static") db = initialize_db() From f252aa7cc13f7ff1b8085bb06564082639cc93a2 Mon Sep 17 00:00:00 2001 From: suryabulusu Date: Thu, 1 Sep 2022 11:38:57 +0530 Subject: [PATCH 09/10] removes unneccessary comment --- app/internal/db.py | 1 - 1 file changed, 1 deletion(-) diff --git a/app/internal/db.py b/app/internal/db.py index 1694f30..1073aa9 100644 --- a/app/internal/db.py +++ b/app/internal/db.py @@ -5,7 +5,6 @@ # when running app locally -- use load_dotenv # when running app via gh actions -- variables already exist via secrets # so no need to load_dotenv -# checking only for secret key as of now if not all(key in os.environ for key in ["DYNAMODB_URL", "DYNAMODB_REGION", "DYNAMODB_ACCESS_KEY", "DYNAMODB_SECRET_KEY"]): From c0bd4db00a3f2d1ab5715f4bd0fb7bc155618168 Mon Sep 17 00:00:00 2001 From: suryabulusu Date: Tue, 6 Sep 2022 13:10:06 +0530 Subject: [PATCH 10/10] changes aws region --- .github/workflows/deploy_to_prod.yml | 2 +- .github/workflows/deploy_to_staging.yml | 16 ++++++++++++++-- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/.github/workflows/deploy_to_prod.yml b/.github/workflows/deploy_to_prod.yml index f6e589d..8853f77 100644 --- a/.github/workflows/deploy_to_prod.yml +++ b/.github/workflows/deploy_to_prod.yml @@ -28,7 +28,7 @@ jobs: with: aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} - aws-region: us-east-1 + aws-region: ap-south-1 - name: Build run: sam build --use-container -t templates/prod.yaml diff --git a/.github/workflows/deploy_to_staging.yml b/.github/workflows/deploy_to_staging.yml index ee300ec..b4d2ffe 100644 --- a/.github/workflows/deploy_to_staging.yml +++ b/.github/workflows/deploy_to_staging.yml @@ -29,7 +29,7 @@ jobs: with: aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} - aws-region: us-east-1 + aws-region: ap-south-1 - name: Build run: sam build --use-container -t templates/staging.yaml @@ -40,4 +40,16 @@ jobs: DYNAMODB_REGION: ${{ secrets.DYNAMODB_REGION }} DYNAMODB_ACCESS_KEY: ${{ secrets.DYNAMODB_ACCESS_KEY }} DYNAMODB_SECRET_KEY: ${{ secrets.DYNAMODB_SECRET_KEY }} - run: sam deploy --stack-name ReportingStaging --s3-bucket reporting-engine-staging --no-confirm-changeset --no-fail-on-empty-changeset --region ap-south-1 --capabilities CAPABILITY_IAM --parameter-overrides DynamodbUrl=$DYNAMODB_URL DynamodbRegion=$DYNAMODB_REGION DynamodbAccessKey=$DYNAMODB_ACCESS_KEY DynamodbSecretKey=$DYNAMODB_SECRET_KEY \ No newline at end of file + run: > + sam deploy + --stack-name ReportingStaging + --s3-bucket reporting-engine-staging + --no-confirm-changeset + --no-fail-on-empty-changeset + --region ap-south-1 + --capabilities CAPABILITY_IAM + --parameter-overrides + DynamodbUrl=$DYNAMODB_URL + DynamodbRegion=$DYNAMODB_REGION + DynamodbAccessKey=$DYNAMODB_ACCESS_KEY + DynamodbSecretKey=$DYNAMODB_SECRET_KEY \ No newline at end of file