Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
124 changes: 81 additions & 43 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,15 @@

The goal of this project is to build, configure, and automate the deployment of a simple serverless application on AWS. Created a health check endpoint that logs requests and stores them in a database, with a CI/CD pipeline to manage deployments for both staging and production environments, fully provisioned via Terraform and deployed automatically using GitHub Actions.

## Prerequisites
- An AWS account and IAM user with rights to create IAM, Lambda, API Gateway, DynamoDB, CloudWatch.
- Local toolchain:
- Terraform v1.2+
- GitHub repo secrets (Repository > Settings > Secrets):
- `AWS_ACCESS_KEY_ID`
- `AWS_SECRET_ACCESS_KEY`
- `AWS_REGION` (e.g. `us-east-1`)

## Architectural desig

### Core Components
Expand All @@ -14,6 +23,8 @@ The goal of this project is to build, configure, and automate the deployment of

Each environment (staging, prod) is isolated by naming convention and Terraform variables.

[Live Demo Link](https://www.loom.com/share/3b1a44b435724293b7be8953ed51ae27)

### Runtime Request Flow

1. _Client_: sends a GET or POST request to:
Expand Down Expand Up @@ -60,6 +71,7 @@ https://<api-id>.execute-api.<region>.amazonaws.com/health
| Terraform vars | `staging.tfvars` | `prod.tfvars` |
| Lambda | `staging-health-check-function` | `prod-health-check-function` |
| DynamoDB | `staging-requests-db` | `prod-requests-db` |
| S3 Bucket | `serverless-health-check-api/staging/tfstate` | `serverless-health-check-api/prod/tfstate`|
| API Gateway | `staging-health-check-api` | `prod-health-check-api` |
| Approval | None | Required |

Expand All @@ -80,50 +92,76 @@ Each Lambda function has one dedicated IAM role with:
- No credentials committed to repository








create hello lambda funtion using Python

![](/svrhecheck.drawio.png)

## Setup

_Repository Structure_

```text
.
├── .github
│ └── workflows
│ ├── deploy.yml
│ └── destroy.yml
├── lambda
│ └── lambda_function.py
├── terraform
│ ├── provider.tf
│ ├── variables.tf
│ ├── main.tf
│ ├── iam.tf
│ ├── lambda.tf
│ ├── apigw.tf
│ ├── outputs.tf
│ ├── staging.tfvars
│ ├── prod.tfvars
│ ├── backend-prod.tfvars
│ └── backend-staging.tfvars
└── README.md

- Create the lambda function, run the python funtion locally using VS Code Run Button, import boto3, logging,json, os, uuid.
- Resource names follows _env-resource-name_

## How to trigger deployments

_Manual for test_
- terraform init -backend-config=backend-staging.tfvars for staging environment
- terraform init -backend-config=backend-prod.tfvars for prod environment
- terraform plan -backend-config=backend-staging.tfvars for staging environment
- terraform plan -backend-config=backend-prod.tfvars for prod environment
- terraform apply -var-file="staging.tfvars"
- terraform apply -var-file="prod.tfvars"
- terraform destroy -backend-config=backend-staging.tfvars for staging environment
- terraform destroy -backend-config=backend-prod.tfvars for prod environment

_GitHub Action CICD_
### Staging
1. Push to branch `staging` (or open a PR merging into `staging` and merge).
2. GitHub Action will automatically:
- `terraform init`
- `terraform plan -var-file="staging.tfvars"`
- `terraform apply` (auto-approved)

### Production
1. Push to branch `main` (or merge PR into `main`).
2. Workflow will run and wait for **manual approval** in the `production` environment (configure environment reviewers in Settings).
3. Approve in GitHub UI → workflow will `apply` the `prod.tfvars` plan.

### Trigger Destroy CICD pipeline
Manually trigger the terraform destroy workflow in GitHub UI -> actions -> destroy.yaml

## Testing the /health endpoint

After deployment, Terraform outputs the API endpoint. You can fetch it:
- From the Actions run logs (last step runs `terraform output -json`)

Example curl (replace `<API_ENDPOINT>` with the `api_endpoint` output):
```
# Hello lambda function
def lambda_handler(event, context):
name = event.get("name", "World")
message = f"Hello, {name}!"

return {
"statusCode": 200,
"body": message
}

# Run the funtion locally for testing
if __name__ == "__main__":
test_event = {"name": "Emmanuel Ogah"}
result = lambda_handler(test_event, None)
print(result)
```

Run the python funtion locally using VS Code Run Button
- Click the “Run Python File” button in the top right corner.
# GET
curl "https://nrbefv9bcj.execute-api.us-east-1.amazonaws.com/health"

```
# Output
{"status": "healthy", "message": "Request processed and saved.", "id": "0fb4fa88-64a1-440d-84b1-5a6d4354364b"}

{'statusCode': 200, 'body': 'Hello, Emmanuel Ogah!'}"
```

- Create the terraform folder structure

- Deploy with: terraform init then terraform apply -var-file="staging.tfvars" (or prod.tfvars)


endpoint - https://nrbefv9bcj.execute-api.us-east-1.amazonaws.com/health



terraform init -backend-config=backend-staging.tfvars for staging environment

terraform init -backend-config=backend-prod.tfvars for prod environment
```
Binary file added svrhecheck.drawio.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file removed terraform/lambda_package/staging-lambda.zip
Binary file not shown.