# #10weeksofCloudOps - Week 1

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1692866802729/726e7371-137c-4041-b5e8-1d120ba41728.png align="center")

## Introduction

In today's digital age, hosting a website has become an essential part of establishing an online presence. Amazon Web Services (AWS) offers a robust and scalable platform for hosting static websites, while implementing Continuous Integration and Continuous Deployment (CI/CD) practices can streamline the development and deployment process.

One popular CI/CD tool is GitHub Actions, which allows developers to automate various tasks. In this article, we will explore how to host a static website on AWS and implement CI/CD using GitHub Actions, enabling you to efficiently manage and deploy your website with ease.

## Resources

* Use S3, CloudFront, Route53
    
* [https://docs.aws.amazon.com/AmazonS3/latest/userguide/HostingWebsiteOnS3Setup.html](https://docs.aws.amazon.com/AmazonS3/latest/userguide/HostingWebsiteOnS3Setup.html)
    
* [https://docs.aws.amazon.com/AmazonS3/latest/userguide/website-hosting-cloudfront-walkthrough.html](https://docs.aws.amazon.com/AmazonS3/latest/userguide/website-hosting-cloudfront-walkthrough.html)
    

## Architecture

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1691039593412/c065e2b6-30ca-4fd0-930d-c5c0b2fa00f6.png align="center")

<mark>(Unavailable, as the infrastructure has been torn down)</mark>

## Procedure

Download a [static site](https://html5up.net/) and add it to a [new Github repo](https://github.com/melvincv/10weeksofcloudops-w1). (under the www folder)

### Create an S3 bucket

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1690863578254/0571df61-9ace-464d-8e9c-c1b71d05b7e9.png align="center")

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1690863605010/c1eaffe3-5f4c-40e4-acdd-347983945650.png align="center")

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1690863626487/9eb917e1-734c-4035-9254-594aefc1a9ff.png align="center")

Click: Create Bucket

### Enable Static Website hosting

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1690863792158/fd4ab2ca-91b2-4351-aa2a-322eeff32fb3.png align="center")

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1690863813497/a8b1689b-f420-448a-b290-361a734f7294.png align="center")

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1690863973743/df99223c-9783-41d9-a593-50576c6a44c0.png align="center")

Click: Save Changes

Copy the Public URL from the bottom of the Properties page.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1690864044487/3d8351b9-8784-4197-b8b7-10d0b8bfbcb7.png align="center")

Install and configure the AWS CLI for your OS.

[https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html)

Create an AWS Access Key and Secret Key.

Configure AWS CLI:

```bash
aws configure
```

Copy the static site to the s3 bucket:

```bash
aws s3 cp www s3://melvincv2023-cloudops-w1 --recursive
```

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1690864508215/ec89c538-27e3-4de7-b941-4a17eb33096f.png align="center")

### Add an S3 Bucket Policy to allow public access

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1690865664108/3a0554bc-de70-4053-b064-bc11bfb45578.png align="center")

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1690865716687/d10c6176-7f6a-4ece-9f6b-9c7f2d32f2cd.png align="center")

```bash
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "PublicReadGetObject",
            "Effect": "Allow",
            "Principal": "*",
            "Action": [
                "s3:GetObject"
            ],
            "Resource": [
                "arn:aws:s3:::melvincv2023-cloudops-w1/*"
            ]
        }
    ]
}
```

Add the above policy and click Save Changes.

Now the Bucket URL should load the static site:

[http://melvincv2023-cloudops-w1.s3-website-ap-southeast-1.amazonaws.com/](http://melvincv2023-cloudops-w1.s3-website-ap-southeast-1.amazonaws.com/)

### CloudFront

Go to the Cloudfront service, click "Create distribution".

Enter the Amazon S3 **website endpoint** for your bucket. Do not select the default bucket URI from the dropdown.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1690866077175/82d55dad-fa4f-46ec-a66c-b8b96b73bc66.png align="center")

For **Default Cache Behavior Settings**, keep the values set to the defaults.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1690866877386/ceeec880-ffd2-4f9b-84b0-73488a04bb2e.png align="center")

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1690866958868/a878373a-d501-4498-9137-8f596f01158b.png align="center")

Go to the **Certificate Manager service &gt;** Create an SSL certificate &gt; Verify the certificate by adding records to Route 53 (or your domain registrar's DNS settings)

Select the certificate in CloudFront. I have already created an wildcard SSL certificate in **Certificate Manager.**

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1690866460440/d37ac24e-f2d5-4b4b-9de0-0497a33d10fc.png align="center")

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1690866518631/3f72a63a-7e85-4db4-8646-cafe5e7dca7c.png align="center")

Click: Create distribution.

Create an S3 bucket in the Singapore region for configuring Cloudfront logging:

```bash
aws s3 mb s3://melvincv2023-cloudops-w1-logs --region ap-southeast-1
```

Configure CloudFront logging:

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1690867956298/8808c3cf-ad19-427c-ae3d-0c7582e7cc99.png align="center")

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1690868055075/668e805e-6eee-4147-a42f-e2e43259acb4.png align="center")

Click: Save changes.

Go to Route 53 &gt; select your zone

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1690868194743/c5b3f01f-b1d3-42f6-80a8-4fbe24ee744e.png align="center")

Add an Alias record pointing to your CloudFront distribution.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1690868283661/39b335d7-d33a-40a1-8d85-3fae4e202e6c.png align="center")

Click: Create records.

The site is now accessible at:

[Dimension by HTML5 UP (](https://site1.aws.melvincv.com/)[melvincv.com](http://melvincv.com)[)](https://site1.aws.melvincv.com/)

## GitHub Actions Workflow

GitHub Actions workflows are a powerful tool for automating various tasks in the software development lifecycle. Workflows are defined in YAML files and can be triggered by events such as code pushes, pull requests, or scheduled intervals.

Workflows consist of one or more jobs, which are executed on virtual machines or containers. Each job can have multiple steps, which are individual tasks that can be executed sequentially or in parallel. Workflows can also use actions, which are reusable units of code that can be shared and used across different workflows.

With GitHub Actions workflows, developers can automate tasks such as building, testing, and deploying their code, enabling them to focus on writing high-quality software.

### Add repo secrets

Create an IAM user with programmatic access and download the `credentials.csv` file

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1690871848494/d8828ce4-9383-4673-9582-7d8b9e27e0e1.png align="center")

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1690871864632/77159fe6-da40-4517-b228-68a36a777d18.png align="center")

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1690871897438/2915bb5b-ecf7-4b01-a97f-da9775d48e41.png align="center")

Next &gt; Create Access Key &gt; Download CSV file

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1690870045191/de551123-dc3d-4646-8ef9-87633366d5eb.png align="center")

Create 2 secrets, add the access key and secret access key as their values:

```bash
AWS_ACCESS_KEY_ID
AWS_SECRET_ACCESS_KEY
```

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1690872183228/674e0e9a-d868-413b-a58d-c4eca3ed0460.png align="center")

### Github Workflow

Create a file in the repo in the path `.github/workflows/deploy.yml`

```yaml
name: Deploy Static Site to S3

on:
  push:
    branches:
      - main
      
jobs:
  deploy:
    runs-on: ubuntu-latest

    steps:
      - name: Checkout code
        uses: actions/checkout@v3

      - name: Set up AWS credentials
        uses: aws-actions/configure-aws-credentials@v2
        with:
          aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
          aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
          aws-region: ap-southeast-1

      - name: Deploy to S3
        run: |
          aws s3 sync www s3://melvincv2023-cloudops-w1 --delete
      
      - name: Invalidate CloudFront cache
        run: |
          aws cloudfront create-invalidation --distribution-id E12J9I3XUIQBDB --paths "/*"
```

### Create an Origin Access?

No, it is not possible to use Origin Access Control (OAC) with an S3 website endpoint. When your origin is an Amazon S3 bucket configured as a website endpoint, you cannot use OAC or OAI (Origin Access Identity) \[1\].

However, you can still restrict access to a custom origin by setting up **custom headers** and configuring the origin to require them \[1\]. This means you can implement additional measures to control access to your S3 bucket content when using an S3 website endpoint with CloudFront.

It is important to note that using OAI is a best practice for securing access to your S3 bucket content through CloudFront\[2\]\[4\]. While it may not apply to an S3 website endpoint, you can explore other options like **custom headers** to enhance the security of your static website hosted on S3.

Citations:

\[1\] [https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/private-content-restricting-access-to-s3.html](https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/private-content-restricting-access-to-s3.html)

\[2\] [https://trendmicro.com/cloudoneconformity/knowledge-base/aws/CloudFront/s3-origin.html](https://trendmicro.com/cloudoneconformity/knowledge-base/aws/CloudFront/s3-origin.html)

\[3\] [https://repost.aws/knowledge-center/cloudfront-serve-static-website](https://repost.aws/knowledge-center/cloudfront-serve-static-website)

\[4\] [https://www.stormit.cloud/blog/cloudfront-origin-access-identity/](https://www.stormit.cloud/blog/cloudfront-origin-access-identity/)

\[5\] [https://crishantha.medium.com/securing-s3-with-origin-access-identity-oai-via-cloudfront-147467eae8aa](https://crishantha.medium.com/securing-s3-with-origin-access-identity-oai-via-cloudfront-147467eae8aa)

\[6\] [https://think-devops.com/posts/static-website-hosting/](https://think-devops.com/posts/static-website-hosting/)

## Conclusion

Hosting a static website on AWS and implementing CI/CD using GitHub Actions can greatly enhance your web development workflow. By leveraging the power of AWS services like Amazon S3 and CloudFront, you can ensure high availability, scalability, and cost-effectiveness for your website.

Additionally, integrating CI/CD practices with GitHub Actions enables you to automate the deployment process, ensuring that your website is always up-to-date with the latest changes. This combination of AWS and GitHub Actions empowers developers to focus on building and improving their websites, while the infrastructure and deployment processes are taken care of seamlessly.

So, whether you are a seasoned developer or just starting your journey, hosting a static website on AWS and implementing CI/CD using GitHub Actions is a valuable skill set to have in your toolkit. Embrace the power of these technologies and take your web development projects to new heights.
