This project demonstrates the integration of OpenID Connect (OIDC) between AWS and GitHub for secure, automated infrastructure deployment using Terraform. The project deploys a simple web application, along with a monitoring stack consisting of Prometheus, Grafana, Loki, and Promtail for observability, and Locust for load testing.
The infrastructure is defined using Terraform, and the deployment is automated via a GitHub Actions workflow that leverages OIDC for authentication with AWS, eliminating the need for long-lived credentials.
- Application: A Python Flask app deployed on AWS (likely ECS or similar).
- Monitoring Stack:
- Prometheus: Collects metrics from the application (e.g., request counts, response times) and node exporters (system metrics like CPU, memory). It scrapes data from configured targets at regular intervals.
- Grafana: Visualizes metrics from Prometheus in dashboards. It provides customizable charts and alerts based on the collected data.
- Loki: Aggregates and stores logs from the application and infrastructure. It indexes logs for efficient querying.
- Promtail: Ships logs from containers and files to Loki. It tails log files and sends them to the Loki server.
- Load Testing: Locust for performance testing.
- Infrastructure as Code: Terraform manages AWS resources.
Before running this project, ensure you have:
- An AWS account with appropriate permissions.
Follow these steps to set up and run the project:
- Go to the original repository.
- Click the "Fork" button in the top-right corner.
- Start a codespace in your forked repository.
To enable secure authentication from GitHub Actions to AWS:
-
In your AWS account, create an IAM OIDC provider for GitHub:
- Go to IAM > Identity Providers.
- Create a new provider with the following details:
- Provider type: OpenID Connect.
- Provider URL:
https://token.actions.githubusercontent.com. - Audience:
sts.amazonaws.com.
-
Create an IAM role that trusts the OIDC provider:
-
Create a new IAM role with the following trust policy:
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Federated": "arn:aws:iam::YOUR_AWS_ACCOUNT_ID:oidc-provider/token.actions.githubusercontent.com" }, "Action": "sts:AssumeRoleWithWebIdentity", "Condition": { "StringEquals": { "token.actions.githubusercontent.com:aud": "sts.amazonaws.com" }, "StringLike": { "token.actions.githubusercontent.com:sub": [ "repo:YOUR_USERNAME/oidc_fii:refs/heads/main", "repo:YOUR_USERNAME/oidc_fii:refs/heads/main" ] } } } ] } -
Attach policies to the role that grant necessary permissions: AdministratorAccess.
-
-
Note the ARN of this IAM role; you'll need it for the next step.
In your forked GitHub repository:
- Go to Settings > Secrets and variables > Actions.
- Add the following secrets:
ROLE_TO_ASSUME: The ARN of the IAM role created in step 2.AWS_REGION: Region for the GitHub Actions AWS session (API calls are not limited to this region). Default workload regions:eu-west-1Session 3 (var.main_aws_region),eu-west-2DR primary (var.aws_region),eu-west-3DR secondary (var.dr_secondary_region).
-
In the AWS Management Console, create a new S3 bucket:
- Bucket name: Choose a unique name (e.g.,
your-username-oidc-fii-state). - Region: same as the
regioninprovider.tfbackend "s3"(currentlyeu-north-1in this repo—can differ from workload regionseu-west-1/eu-west-2/eu-west-3).
- Bucket name: Choose a unique name (e.g.,
-
In the
provider.tffile, replaceYOUR_BUCKET_NAMEwith your actual S3 bucket name.
- Open
.github/workflows/terraform.yml. - Uncomment all steps except the "Terraform Destroy" step (which should remain commented out for now).
-
Add all changes:
git add -A
-
Commit the changes:
git commit -m "Setup OIDC and configure Terraform" -
Push to your forked repository:
git push origin main
After pushing the changes, the GitHub Actions workflow will automatically trigger:
- The pipeline will authenticate with AWS using OIDC.
- Terraform will initialize, plan, and apply the infrastructure.
- The application, monitoring stack, and load testing setup will be deployed.
Monitor the Actions tab in your GitHub repository for the workflow progress.
Once the pipeline completes successfully, the following URLs will be output at the end of the pipeline logs:
- Application URL: The URL to access the deployed Flask app.
- Grafana URL: Access the Grafana dashboard for monitoring.
- Locust URL: Access the Locust web interface for load testing.
The app dashboard is automatically imported. In Grafana, additionally import the following dashboards manually:
- Node Exporter Dashboard (ID: 1860): Monitors the app instance's system metrics (CPU, memory, disk, etc.). Import from the JSON file at
monitoring/grafana/provisioning/dashboards/node.json. - cAdvisor Dashboard (ID: 19908): Monitors container metrics. Import from the JSON file at
monitoring/grafana/provisioning/dashboards/app.json.
In Grafana, you can set up alerts for key metrics:
- Node Dashboard (%CPU Alert): Create an alert rule for CPU usage exceeding 80%. Go to the Node Exporter dashboard, select a CPU panel, and configure an alert condition based on the CPU usage metric.
- Application Dashboard (Requests per Minute Alert): Create an alert rule for requests per minute exceeding a threshold (e.g., 100). Select the requests panel and set up an alert based on the request rate metric.
Alerts can be configured to send notifications via email, Slack, or other channels.
To destroy the infrastructure:
- Uncomment the "Terraform Destroy" step in
.github/workflows/terraform.yml. - Commit and push the change to trigger the destroy workflow.
- Ensure your AWS account has the necessary permissions for the resources being created.
- Check the GitHub Actions logs for any errors during deployment.
- Verify that the OIDC setup is correct by checking the IAM role trust relationships.
Feel free to fork, modify, and submit pull requests. For issues, please open a GitHub issue in the repository.
This project is licensed under the MIT License.