Introduction: Streamlining Website Deployment with GitOps and OIDC

As businesses increasingly turn to static websites for simplicity, security, and performance, ensuring an automated and secure deployment process is paramount. GitOps—a model combining Git with operations—allows us to define infrastructure and deployment processes in code. Integrating GitHub Actions for Continuous Integration/Continuous Deployment (CI/CD) and leveraging Terraform with OpenID Connect (OIDC) for secure cloud authentication offers a streamlined, scalable solution. This guide demonstrates how to securely deploy a static website on AWS using GitHub Actions, Terraform, and OIDC.

Prerequisites: AWS Configuration and GitHub Repository Setup

Before starting, ensure you have the following prerequisites:

  1. AWS Account: Ensure you have an active AWS account with IAM administrative access to configure permissions and roles.
  2. GitHub Repository: Set up a repository to store your Terraform code, website content, and GitHub Actions workflows.
  3. Terraform: Install Terraform locally and configure it to interact with AWS services.
  4. GitHub Actions Runner: Ensure your repository is set up for GitHub Actions by adding a basic workflow file.

AWS IAM Identity Provider: Enabling Secure GitHub Actions Access

To eliminate the need for long-lived AWS credentials in GitHub, configure OIDC between AWS and GitHub. This approach lets GitHub Actions assume roles in your AWS account securely.

  1. Create an OIDC Provider: Navigate to the IAM console and add an OpenID Connect provider for GitHub. Set the URL as https://token.actions.githubusercontent.com and select the appropriate audience (sts.amazonaws.com).
  2. Create a Trust Policy: Let GitHub assume roles using a trust policy, restricting it to specific repositories for enhanced security.

Backend and Infrastructure: Configuring S3 for Terraform State and Website Hosting

Terraform requires a backend to store the state file securely. AWS S3 is an ideal choice, offering durability and availability.

  1. S3 for Terraform State: Create an S3 bucket to store Terraform’s state file. Enable versioning to track state changes over time.
  2. S3 for Static Website Hosting: Create another S3 bucket for hosting the static website. Configure the bucket for static website hosting, ensuring the appropriate permissions and policies are in place to make your website publicly accessible.

resource “aws_s3_bucket” “website” {

  bucket = “my-website-bucket”

  acl    = “public-read”

  website {

    index_document = “index.html”

  }

}

IAM Roles and Policies: Granting Permissions for S3 and CloudFront Management

To manage your infrastructure via GitHub Actions, create IAM roles with the necessary permissions:

  1. IAM Role for GitHub Actions: Define an IAM role that allows GitHub Actions to perform operations such as creating S3 buckets and managing CloudFront distributions.
  2. Policies for S3 and CloudFront: Attach policies that allow managing S3 buckets and configuring CloudFront for content delivery.

{

  “Version”: “2012-10-17”,

  “Statement”: [

    {

      “Effect”: “Allow”,

      “Action”: [

        “s3:*”,

        “cloudfront:*”

      ],

      “Resource”: “*”

    }

  ]

}

Terraform Configuration: Provider, S3, CloudFront, and Output Definitions

Define your Terraform provider and resources for the static website:

  • Provider: Set the AWS provider with the region and profile configurations.
  • S3 Bucket: Create S3 resources for the Terraform state and static website.
  • CloudFront Distribution: Configure a CloudFront distribution to serve content from the S3 bucket with caching for performance.
  • Outputs: Provide outputs such as the S3 bucket URL and CloudFront distribution domain.

provider “aws” {

  region = “us-east-1”

}

resource “aws_s3_bucket” “website” {

  bucket = “my-static-website”

  acl    = “public-read”

}

resource “aws_cloudfront_distribution” “cdn” {

  origin {

    domain_name = aws_s3_bucket.website.bucket_regional_domain_name

  }

}

output “website_url” {

  value = aws_cloudfront_distribution.cdn.domain_name

}

GitHub Secrets: Storing Sensitive AWS Credentials Securely

GitHub Actions allow you to store sensitive information securely in the repository’s settings. Add the following secrets:

  1. AWS_ROLE_ARN: The ARN of the IAM role that GitHub Actions will assume.
  2. AWS_REGION: The region where your AWS infrastructure is deployed.

Store these values in Settings > Secrets of your GitHub repository.

GitHub Actions Workflow: Automating Terraform Deployment on Push to Main

Define a GitHub Actions workflow to automate the deployment process on each push to the main branch:

  1. Configure Terraform Plan and Apply: Use GitHub Actions to run Terraform commands automatically, ensuring the website gets deployed or updated without manual intervention.

name: Deploy Static Website

on:

  push:

    branches:

      – main

jobs:

  deploy:

    runs-on: ubuntu-latest

    permissions:

      id-token: write

      contents: read

    steps:

      – name: Checkout code

        uses: actions/checkout@v2

      – name: Setup Terraform

        uses: hashicorp/setup-terraform@v1

      – name: Terraform Init

        run: terraform init

      – name: Terraform Plan

        run: terraform plan

      – name: Terraform Apply

        run: terraform apply -auto-approve

Understanding Workflow Triggers and Branch Protection

Implement branch protection rules in GitHub to ensure only approved changes are pushed to the main branch, securely triggering the Terraform deployment process. Code reviews and checks are required to maintain code integrity.

Conclusion: A Scalable and Secure Deployment Pipeline with AWS and GitHub

By combining GitOps practices, OIDC authentication, Terraform, and GitHub Actions, you’ve created a secure, scalable deployment pipeline for static websites on AWS. This approach enhances security and streamlines the deployment process, minimizing the risk of manual errors.

Additional Enhancements: Leveraging Route 53, ACM, and WAF for a Robust Website

To further enhance your website, consider these additional steps:

  • Route 53: Configure a custom domain for your CloudFront distribution.
  • ACM (AWS Certificate Manager): Set up SSL certificates to enable HTTPS for your website.
  • AWS WAF: Add a Web Application Firewall (WAF) to protect your website from malicious attacks.

References

Automate Microsoft web application deployments with GitHub Actions and Terraform

Integrating with GitHub Actions – CI/CD pipeline to deploy a Web App to Amazon EC2