How to deploy Jekyll site to AWS with GitHub actions
In this post we will see how to deploy the blog we created here How to build blog with Jekyll.
AWS S3
-
Create S3 bucket with your domain name. e.g. If your domain is mypersonaldomain.com, then create bucket in S3 with name mypersonaldomain.com
-
Allow all public access for this bucket and select the acknowledgement. Hit Create bucket
-
Click on the bucket created and go to Properties, at the bottom of the page edit the static website hosting. Enable the static website hosting and enter index.html in the index document and 404.html in the error document. Hit Save Changes. This will create a website endpoint.
-
Click the permission tabs, and edit the bucket policy. Add the following policy
{ "Version": "2012-10-17", "Statement": [ { "Sid": "PublicReadGetObject", "Effect": "Allow", "Principal": "*", "Action": [ "s3:GetObject", "s3:PutObjectAcl", "s3:GetObjectAcl" ], "Resource": "arn:aws:s3:::mypersonaldomain.com/*" } ] }
Now our bucket can be accessed publicly and data can be pushed from GitHub action
AWS IAM User
- Create an IAM user with S3 and Cloudfront permissions. This user will be used by the GitHub actions to copy content from repository to S3 bucket.
-
Create an access key for this user. Note down the access key and access secret (it won’t be generated again)
Domain Certificate
We will create certificate for our domain which will used by the cloud distribution
-
Request public certificate in AWS certificate manager.
- Choose DNS verification. ( You can choose any verification)
-
Click on the certificate and copy the CNAME name and values and paste in your Domain DNS to verify.
- Once verified will use this certificate in the cloud distribution
AWS Cloudfront
Now we will create cloud front for our static S3.
- Create distribution, choose your S3 in the origin domain.
- Choose your SSL certificate which was created in the previous step
- Hit Create distribution.
- Add the distribution domain name in the DNS
- Add Alias with value of distribution domain name
- Add CNAME for www with value of distribution domain name
- Edit the cloud distribution, and add alternate domains
mypersonaldomian.com www.mypersonaldomain.com
- After successful save, your domain is now connected to this distribution which is connected to the S3 bucket.
GitHub Action
- Create a repository and push the code created in previous article to GitHub.
- Copy values for access id, access secret, bucket name and cloud distribution id
-
Create secrets for the repository with following names
-
Create a new GitHub action which will build the code and push the code to AWS S3.
name: CI / CD # Controls when the action will run. on: # Triggers the workflow on push for the main branch push: branches: [ main ] # Allows you to run this workflow manually from the Actions tab workflow_dispatch: env: AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} AWS_DEFAULT_REGION: 'us-west-2' # A workflow run is made up of one or more jobs that can run sequentially or in parallel jobs: build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Set up Ruby uses: ruby/setup-ruby@v1 with: ruby-version: "3.2.2" # Not needed with a .ruby-version file bundler-cache: true - name: "Build Site" run: bundle exec jekyll build env: JEKYLL_ENV: production - name: "Deploy to AWS S3" run: aws s3 sync ./_site/ s3://${{ secrets.AWS_S3_BUCKET_NAME }} --acl public-read --delete --cache-control max-age=604800 - name: "Invalidate CloudFront Cache" run: aws cloudfront create-invalidation --distribution-id ${{ secrets.AWS_CLOUDFRONT_DISTRIBUTION_ID }} --paths "/*"
- Run the action, files should be copied to the S3 bucket and the domain should now serve the blog.
- Any new data pushed to the main branch should automatically build the solution and push the latest to our S3.
Conclusion
In this article we created S3 bucket with our domain name and cloud distribution using amazon managed certificate. And then created the GitHub action which will copy data to our S3 bucket with any new pushed to main branch.