Introduction
In my previous post, I showed how to cheaply and securely host a static website on AWS using an S3 bucket and CloudFront CDN. Now, let’s automate deployments using GitHub Actions with AWS IAM role assumption, a best practice approach that avoids managing long-lived AWS credentials and increases deployment security.
This guide will walk you through configuring your GitHub repository and AWS account to build your site and deploy it automatically to your private S3 bucket behind CloudFront—using only official AWS GitHub Actions and CLI tools, with no third-party dependencies.
What You’ll Need
- Your website hosted on AWS with S3 and CloudFront (refer to the previous tutorial for setup)
- A GitHub repository containing your static site source code
- AWS IAM permissions to create policies, roles, and identity providers
- Familiarity with GitHub Actions workflows and AWS CLI
Creating a Policy
Start by creating an AWS IAM policy granting the minimum permissions necessary for deployment:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:PutObject",
"s3:GetObject",
"s3:DeleteObject",
"s3:ListBucket"
],
"Resource": [
"arn:aws:s3:::your-bucket-name",
"arn:aws:s3:::your-bucket-name/*"
]
},
{
"Effect": "Allow",
"Action": [
"cloudfront:CreateInvalidation",
"cloudfront:GetDistribution",
"cloudfront:GetDistributionConfig"
],
"Resource": "arn:aws:cloudfront::your-account-id:distribution/your-distribution-id"
}
]
}
Important:
- Replace
your-bucket-namewith your actual S3 bucket name. - Replace
your-account-idandyour-distribution-idwith your AWS account and CloudFront distribution IDs respectively.
Attach this policy to the IAM role you will create in the next step.
Add GitHub as an Identity Provider in AWS IAM
To allow GitHub Actions to assume an AWS role securely using OpenID Connect (OIDC), add GitHub as an identity provider:
- In the AWS Management Console, navigate to IAM > Identity Providers.
- Click Add provider.
- Set Provider type to OpenID Connect.
- Set the Provider URL to: https://token.actions.githubusercontent.com
Create an IAM Role for GitHub Actions
Create a role your GitHub workflow will assume:
- Go to IAM > Roles, then click Create role.
- Select Web identity as the trusted entity type.
- Choose the GitHub identity provider you created above.
- Set the audience to: sts.amazonaws.com
- Set the Github organization either to your account name can be extracted by the github url of your repository or the name of an organisation.
- Set the Github repository to the name of your respository
- Set the Github branch to the name of your branch
- Attach the policy you created earlier with minimal S3 and CloudFront permissions.
- Complete creating the role and note its ARN (you will need it in GitHub Secrets).
Configure GitHub Secrets
In your GitHub repository, navigate to Settings > Secrets and variables > Actions and add the following secrets:
AWS_REGION— your AWS region (e.g.,eu-central-1)ROLE_TO_ASSUME— the ARN of the IAM role created aboveS3_BUCKET— your S3 bucket nameCLOUDFRONT_DISTRIBUTION_ID— your CloudFront distribution ID
You do not need to provide AWS access keys due to OIDC role assumption.
GitHub Actions Workflow Using Official AWS Action
Create or update .github/workflows/deploy.yml in your repository with this workflow configuration:
name: Build and Deploy to AWS
on:
push:
branches:
- main
permissions:
id-token: write
contents: read
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Configure AWS Credentials
uses: aws-actions/configure-aws-credentials@v3
with:
role-to-assume: ${{ secrets.ROLE_TO_ASSUME }}
aws-region: ${{ secrets.AWS_REGION }}
- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version: '22.16.0' # Adjust Node.js version as needed
- name: Install dependencies
run: npm install
- name: Build site
run: npm run build
- name: Sync site to S3
run: aws s3 sync ./dist s3://${{ secrets.S3_BUCKET }} --delete
- name: Invalidate CloudFront cache
run: aws cloudfront create-invalidation --distribution-id ${{ secrets.CLOUDFRONT_DISTRIBUTION_ID }} --paths "/*"
Summary
By adding GitHub as an OIDC identity provider, creating a tightly scoped IAM policy and role for GitHub Actions, and using the official AWS GitHub Action and CLI, you can establish a secure, fully automated workflow to deploy your static website hosted in AWS S3 and delivered via CloudFront.
This method removes the risks of long-lived AWS credentials and leverages short-lived tokens with precise access control tied directly to your GitHub repository and branch.
Happy shipping! 🚀