Build a Website in Azure using GitHub Actions, Jekyll and Terraform Cloud.

Build a Website with an Azure Static Web App and use GitHub Actions to manage your continuous deployment with Terraform Cloud for Infrastructure and Jekyll to generate your static website content.

  • Category: DevOps
  • Date: 13 May 2023

I have been looking at moving away from Square Space and thought I would look at free hosting options.

There’s multiple options out there, such as AWS S3 buckets, Azure Storage Accounts, Azure Static Web App and GitHub Pages. These days, you don’t even need to purchase a domain name, GitHub pages is probably the more favoured option as you get a username.github.io domain name if you didn’t want to pay for a custom domain name!

But I thought I would create this video and show all the technologies used in the real world today. The workflow in this video is a very common approach in today’s world working with Cloud technologies. Initially there will be manual processes to setup the accounts and integration but once set up, its as easy as just pushing code to make future updates!

Not to mention that this is a foundation where by you can enhance with A/B deployments, include throughout checks and testing before deploying, enforcing security controls or even scanning for bad practices!

Really this is quite an over engineered scenario for your own personal page but its a fun project to learn different technologies and how they integrate!

… and did I mention everything is FREE!

So lets get started with setting up the configuration!

Overview

Overview

Pre-requisites

  • Download Terraform (optional as Terraform Cloud is utilised via the workflow)
    • Install Terraform locally to run init, plans and apply. This is optional as GitHub Actions will invoke commands to Terraform Cloud.
      1. Browse to HashiCorp - Install Terraform
      2. Extract your tools folder e.g. (C:\Workspace\Terraform)
      3. Add the Path your Environment Path (Optional - For Convenience) - (Windows or Linux)
      4. Run command to setup your local Terraform Cloud token:
        terraform login
        
  • Setup a Terraform Cloud Account
  • Setup an Azure Account
  • Setup a GitHub Account
  • Setup Jekyll (or your choice of software)
    • Download and Setup Up Jekyll

1. Setup Terraform Cloud Workspace

Terraform workspace to create and manage Azure resources.

  1. Log into Terraform Cloud
  2. Under Projects & Workspaces

Alt text

  1. Click Create Workspace or New and Select Workspace

Alt text

  1. Select API Driven Workflow

Alt text

  1. Enter a Name for your Workspace
  2. Select a Project or leave as Default Project
  3. Click Create Workspace

Alt text

  1. Once created you will see the Waiting for Configuration page

Alt text

2. Create a Service Principal

This service principal will be used to by the Terraform AzureRM provider to manage Azure.

  1. Log into Azure Portal
  2. Browse to Azure Active Directory
  3. Click App Registrations
  4. Click New Registration
  5. Enter a Name
  6. Select Accounts in this organizational directory only

Alt text

  1. Click Register
  2. Once Done, Click Certificates & Secrets
  3. Under Client Secrets, Select + New Client Secret

Create Secret

  1. Enter a Description and Set an Expiry

Add Secret

  1. Click Add
  2. Take Note of the Secret under Value (leave this screen as it is or copy the secret as it will disappear once you navigate awy from this screen!)
  3. Open a New Azure Portal tab for the next step!

3. Assign Service Principal Permissions

This will be the role assignments that will give the service principal access to create and manage Azure resources.

  1. Browse to the resource (in this example Subscriptions)
  2. Select Access Control (IAM)

Access Control (IAM)

  1. Click + Add
  2. Select Add Role Assignment

Add Role Assignment

  1. Under Assignment Type, Select Privileged Administrator Roles
  2. Click Next
  3. Under Assignment Type, Enter the Permissions (in this example it will be Contributor)

Contributor

  1. Click Next
  2. Under Assign Access To, Select User, Group, Or Service Principal
  3. Under Members, Click Select Members
  4. Locate your Service Principal and Click Select

Select Service Principal

  1. Click Next
  2. Click Review + Assign

Assignment Success

  1. You should now have the Service Principal under the Role Assignments!

Role Assignment Complete

4. Create Terraform Workspace Variables for Azure Authentication

These variables will be used to authentication the Terraform AzureRM provider.

  1. Log into Terraform Cloud
  2. Under Projects & Workspaces

Alt text

  1. Locate and Select your Terraform Workspace
  2. Click Variables

Workspace Variables

  1. Now you will need get the details from above ( Create a Service Principal above)
  2. Under Workspace Variables, Select + Add Variable
  3. Now Create the Following Variables:
Variable Name Description
client_id Client ID (also known as the Application ID) of your Service Principal
client_secret Client Secret of your Service Principal
subscription_id Subscription ID of where you have assigned your Service Principal Role Assignments
tenant_id Tenant ID of your Azure Tenant
  1. Once done you should have a screen as below!

Don’t forget to mark your secrets as sensitive as they can be used to access your subscription. Create Workspace Variables

5. Create GitHub Repository

This repository will be used to store the Terraform code and GitHub Actions Workflow.

  1. Log into GitHub.com
  2. Click New
  3. Enter a Repository Name
  4. Enter a Description
  5. Set the Repository to Public
  6. Select Initialize this repository with: Check Add a README file
  7. Select Add .gitignore and Select Terraform
  8. Click Create Repository

Alt text

6. Create Terraform Workspace Variables for GitHub Authentication

This token will be used with GitHub Actions to create a Secret via Terraform, which will be used to publish the website.

  1. Log into GitHub.com
  2. Click on your Profile and Select Settings

Profile Settings

  1. Scroll to the bottom and Click Developer Settings
  2. Under Personal Access Tokens, Select Fine-Grained Tokens

Fine-Grained Tokens

  1. Configure (as Required):
Name Configuration Attribute Description
Token Name AZURE_STATIC_WEB_APPS_API_TOKEN NA Name for your token, this will appear in the GitHub UI
Expiration 30 Days NA This is up to you, ideally you should frequently rotate this on a regular basis
Description Azure Static Web App API Token NA Description for your Token
Repository Access Only Select Repositories Select Your Repository Name You should also go with the least privileged access controls to mitigate risks
Metadata Read-Only (Mandatory Default) NA This is a Mandatory Configuration item
Permissions Repository Permissions > Actions Read-Only Required to Read the GitHub Actions Workflow
Permissions Repository Permissions> Secrets Read and Write Required to create the GitHub Actions Workflow Secret
  1. Click Generate Token

Generate Token

  1. Copy the Personal Access Token (PAT)
  2. Go back to Step 4 above to create a new Workspace Variable named GITHUB_TOKEN
Variable Name Description
GITHUB_TOKEN GitHub Token to be able to Create the GitHub Actions Workflow Secret - Note: This is case sensitive and needs to align with the variables.tf file

GitHub Variable

Don’t forget to mark your secrets as sensitive as they can be used to access your subscription.

7. Configure Terraform Token as GitHub Actions Secret

This will be used with GitHub Actions to interface with Terraform Cloud via CLI.

  1. Log into Terraform Cloud
  2. Click on your Profile
  3. Click User Settings

Alt text

  1. Click Tokens
  2. Click Create an API Token
  3. Enter a Name and Expiration

Alt text

  1. Click Generate Token
  2. Copy the Token
  3. Browse back to GitHub.com
  4. Find the newly created repository and Click Settings
  5. Under Security, Select Secrets and Variables then Select Actions

Alt text

  1. Under Secrets, Select New Repository Secret

Alt text

  1. Enter a Name for the Secret (example is TF_API_TOKEN)
  2. In the Secret box, Paste the above API Token

Alt text

  1. Click Add Secret
  2. Now you should have a new secret under Repository Secrets

Alt text

8. Setup Your Repository with the Demo Code

So next up, we will write some simple Terraform code to deploy the resource group and static web app. Clone my repository which has all the Terraform code and GitHub Actions Workflow.

  1. Log into GitHub.com
  2. Clone the above repository: azure_website_actions_terraform
  3. Copy all the Terraform files (*.tf) to your NEW REPOSITORY created in step 6. Create GitHub Repository
  4. Update the following configuration:
Filename Configuration Attribute Description
providers.tf Terraform > Cloud Organization Add your Terraform Cloud Organization Name
providers.tf Terraform > workspaces Name Add your Terraform Cloud Workspace Name
main.tf locals > repo_name NA Add your Repository Name
  1. Copy the .github/workflows/website-automation.txt folder to your NEW REPOSITORY
  2. Rename the file website-automation.txt to website-automation.yaml (this was named as a txt so my repo does try and the GitHub Actions Workflow everytime!)

9. Build a Jekyll Website

This is an option step, you can choose software of your choice. Once you have website code, it will need to be updated to the /src folder in your repository. The following steps are from the Jekyll - Quick Start page. This was run on WSL Ubuntu.

You can also get Jekyll templates from here. We’ll be using the Jekflix Template in this demo.

  1. Install Gem and Jekyll by running:
    sudo gem install jekyll bundler
    
  2. Browse to a temp directory. This will become your local website development directory
  3. Create a new Jekyll website by running:
    sudo jekyll new mywebsite
    
  4. Browse to the mywebsite folder:
    cd mywebsite
    
  5. Now build the website with Jekyll:
    bundle exec jekyll build --destination <path-to-repo>/src
    
  6. Now in your repository folder you should have a /src folder with html files.

10. Deploy your Code

Your repository should look something along the lines of:

Repo Files

  1. Now merge your code into master
    git add .
    git commit -m "initial upload"
    git push
    
  2. Once your code is merged, open GitHub.com
  3. Click Actions
  4. Under All Workflows, Select the Running Workflow

    Note: You might will get an initial failure because your github_actions_secret is created but it appears that the workflow does not update for the next stage, so it needs to be run again!

Token Error

  1. If you get the above error, you can open the failed job and Click Re-Run Jobs and Select Re-Run All Jobs

Re-Run All Jobs

11. Locate your Website URL

  1. Log into Azure Portal
  2. Locate your Resource Group (this will be in the Plan / Apply outputs from your GitHub Actions runs)
  3. Click on the Static Web App
  4. Locate the URL and this is your Website URL

Website URL

If you want to make changes to your website, all you need to do is push code to the /src folder and the GitHub Actions Workflow will republish your website!

Learn more at the following:

You can learn more from the links below!

- HashiCorp - Automate Terraform with GitHub Actions
- HashiCorp - Get Started - Terraform Cloud
- Quickstart for GitHub Actions
- Learn GitHub Actions
- Microsoft - Static Web Apps
- Jekyll - Getting Started

And that is it! You should now have a new website and this is generally how infrastructure and applications are managed in larger environments. Obviously there’s more controls such a code approvers, tighter security controls around access and networking but this was a cool project to experience multiple technologies and did I mention.. everything is free!

Hope you enjoyed this blog and the YouTube video!

Cheers
Sunny