Imagine developing a website and manually uploading files to a server every time you make a change. This process may work for a small project, but it becomes difficult to manage as the application grows.
Developers need a reliable way to test and deploy changes without repeating the same manual tasks.
That is where a CI/CD pipeline becomes useful.
In this tutorial, you will learn how GitHub Actions and Amazon Web Services (AWS) can work together to automate the deployment of a simple static website.
What Is a CI/CD Pipeline?
CI/CD stands for Continuous Integration and Continuous Delivery or Deployment.
Continuous Integration involves automatically checking code changes through activities such as builds and tests.
Continuous Delivery prepares validated changes so they can be released reliably, while Continuous Deployment goes further by automatically releasing approved changes without manual intervention.
For example, when a developer pushes code to GitHub, an automated workflow can validate the project and upload the website files to AWS.
This reduces repetitive work and makes the deployment process more consistent.
How GitHub Actions and AWS Work Together
GitHub Actions is an automation service that runs workflows in response to repository events.
AWS provides cloud services for hosting applications, storing files and managing infrastructure.
In this project, we will use:
- GitHub for source code management
- GitHub Actions for workflow automation
- AWS Identity and Access Management (IAM) for permissions
- Amazon S3 for storing static website files
- OpenID Connect (OIDC) for short-lived AWS authentication
The workflow will look like this:
Developer pushes code → GitHub Actions starts → Project validation runs → AWS authentication occurs → Website files are uploaded to S3
For production web delivery, Amazon CloudFront can be added in front of a private S3 bucket.
Step 1: Create a GitHub Repository
Create a repository called aws-cicd-demo.
Add a simple index.html file:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>My AWS DevOps Project</title>
</head>
<body>
<h1>Welcome to My DevOps Project</h1>
<p>Deployed automatically with GitHub Actions.</p>
</body>
</html>
Commit and push the file to the main branch.
This is the website that your pipeline will deploy.
Step 2: Create an Amazon S3 Bucket
Log in to the AWS Management Console and open Amazon S3.
Create a bucket with a globally unique name, such as one based on your project name and a unique identifier.
Choose the appropriate AWS Region.
For this exercise, the bucket will store static HTML files.
Keep S3 Block Public Access enabled. You can use CloudFront with Origin Access Control if you later want to serve the site publicly through HTTPS.
Do not make the bucket public simply to complete the deployment tutorial.
Remember that AWS services may generate charges depending on usage and configuration.
Step 3: Configure AWS Authentication
Avoid placing permanent AWS access keys directly in your source code or workflow file.
Instead, use OIDC authentication.
This allows GitHub Actions to obtain temporary AWS credentials by assuming an authorized IAM role.
At a high level, the setup requires:
- Configuring GitHub's OIDC identity provider in AWS IAM.
- Creating an IAM role with a trust policy.
- Restricting the role to the intended GitHub repository and branch.
- Granting only the S3 permissions needed for deployment.
- Recording the IAM role ARN for the GitHub workflow.
For example, a deployment role may need permission to list a specific bucket and upload or replace objects in that bucket.
If your workflow also deletes obsolete files, it needs the corresponding delete permission.
Avoid broad permissions such as unrestricted administrator access.
Step 4: Create a GitHub Actions Workflow
Inside your repository, create this directory:
.github/workflows/
Add a file called deploy.yml.
name: Deploy Website to AWS
on:
push:
branches: [main]
permissions:
id-token: write
contents: read
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Validate website
run: test -s index.html
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: ${{ secrets.AWS_ROLE_ARN }}
aws-region: ap-south-1
- name: Upload website
run: |
aws s3 cp index.html \
s3://${{ vars.S3_BUCKET_NAME }}/index.html
This sample assumes that:
- The configured IAM role trusts the correct GitHub repository and branch.
AWS_ROLE_ARN is available as a GitHub Actions secret.
S3_BUCKET_NAME is configured as a GitHub Actions variable.
- The bucket is in
ap-south-1, or the workflow Region is updated accordingly.
- The role has the required S3 permissions.
Pinning actions to reviewed commit SHAs is preferable for production workflows.
Step 5: Understand the Workflow
The workflow runs whenever a commit is pushed to the main branch.
First, GitHub Actions retrieves the repository files.
Next, it verifies that index.html exists and is not empty.
The workflow then uses OIDC to authenticate with AWS.
Finally, the AWS CLI uploads the HTML file to the selected S3 bucket.
This is a minimal validation-and-deployment pipeline. A real software project should include meaningful automated tests, not just a file existence check.
Step 6: Test the Pipeline
Make a small change to your HTML file and push it to GitHub.
Open the Actions tab in your repository.
You should see the workflow run.
Inspect each step and verify whether it completed successfully.
Next, open your S3 bucket and confirm the expected file was uploaded.
The presence of the file in S3 confirms deployment to storage. It does not automatically mean the website is publicly accessible.
If you configure CloudFront separately, verify the website through its distribution URL and consider cache invalidation when appropriate.
Common CI/CD Problems
Access Denied
The IAM role may not have permission to access the bucket.
Review the role's policies and the bucket configuration.
OIDC Authentication Failure
Check the IAM trust policy, repository name, branch condition and role ARN.
A common mistake is allowing a different repository or branch than the one running the workflow.
Workflow Does Not Start
Confirm that the YAML file is located in .github/workflows/ and the push occurred on the configured branch.
Files Are Uploaded but the Website Is Not Updated
If CloudFront is serving cached content, an invalidation or appropriate cache policy may be needed.
How to Extend This DevOps Project
Once the basic pipeline works, try adding:
- HTML and JavaScript linting
- Automated tests
- A production build step
- Separate staging and production environments
- Deployment approvals
- CloudFront integration
- Deployment notifications
- Rollback procedures
For more advanced projects, learn how to deploy containerized applications using Docker and AWS services such as Amazon ECS.
Frequently Asked Questions
1. Is GitHub Actions free?
GitHub provides GitHub Actions usage allowances depending on the repository and plan. Additional usage or hosted runners may incur costs.
2. Is AWS knowledge necessary for DevOps?
AWS is one of several cloud platforms used in DevOps. Understanding cloud computing, Linux, networking, automation and CI/CD is valuable.
3. What is the difference between Jenkins and GitHub Actions?
Both support workflow automation. Jenkins is commonly self-managed, while GitHub Actions integrates directly with GitHub repositories.
4. Can beginners build a CI/CD pipeline?
Yes. A simple static website deployment is a useful starting project before moving to containers and complex infrastructure.
5. Should AWS access keys be stored in GitHub?
Long-lived access keys should be avoided when suitable short-lived authentication, such as OIDC, is available.
Conclusion
Building a CI/CD pipeline with GitHub Actions and AWS is a practical way to understand automated software delivery.
Begin with a small project, learn how permissions and deployment workflows operate, and then add testing, monitoring and production controls.
CI/CD pipeline using GitHub Actions and AWS
Explore more hands-on cloud infrastructure and deployment concepts through Itvedant's DevOps with AWS Course.