How to Host a Static Website on Azure Storage with a Custom Domain and CI/CD Pipeline

How to Host a Static Website on Azure Storage with a Custom Domain and CI/CD Pipeline

In this tutorial, we will walk you through the process of hosting a static website on Azure Storage with a custom domain and setting up continuous integration and deployment (CI/CD) using GitHub Actions.

Prerequisites

Before you can host a static website on Azure Storage with a custom domain and CI/CD pipeline, there are a few prerequisites that need to be in place. These include:

  1. Creating an Azure subscription

    To get started, you'll need an Azure subscription. If you don't have one already, you can create a free account at azure.microsoft.com.

  2. Azure CLI

    You can install it from here if you don't have it installed.

  3. Domain name registered with a domain service provider (we'll use Namecheap in this tutorial).

  4. Node.js and npm (if you are using React or any other framework to build your static website).

Creating a new storage account

Azure Storage provides scalable, secure, and highly available storage for your static website files. You'll need to create a new storage account where you'll upload your static website files. This storage account will be configured to enable static website hosting.

To create the resource group and storage account, you can use the Azure portal or Azure CLI. Here's an example of how to create them using the Azure portal:

  1. Log in to the Azure portal with your Azure subscription.

  2. In the left-hand menu, click on "Resource groups".

  3. Click on the "Add" button to create a new resource group.

  4. Enter your desired name as the resource group name, choose the desired subscription and region, and click on "Review + Create".

  5. Review the settings and click on "Create" to create the resource group.

  6. Once the resource group is created, go back to the left-hand menu and click on "Storage accounts".

  7. Click on the "Add" button to create a new storage account.

  8. Enter a unique name for your storage account, select the resource group "my-website" that you created earlier, choose the desired location and performance settings, and click on Review.

  9. Review the settings and click on "Create" to create the storage account.

With these prerequisites in place, you're now ready to move on to the next steps of enabling static website hosting on Azure Storage.

Part 1: Enabling Static Website Hosting on Azure Storage

Static Content Hosting

Static website hosting is a feature provided by Azure Storage that allows you to host and serve static content such as HTML, CSS, JavaScript, and image files directly from your storage account. This eliminates the need for a traditional web server and provides a scalable and cost-effective solution for hosting static websites.

Step 1: Enable static website hosting on the storage account

To enable static website hosting on your Azure Storage account, follow these steps:

  1. Go to the Azure portal and navigate to your storage account.

  2. In the left-hand menu, under Settings, click on "Static website."

  3. In the Static website blade, toggle the "Static website" option to "Enabled."

  4. Enter the name of the default HTML file (e.g., "index.html"). This file will be served when visitors access the root URL of your website.

  5. Optionally, you can specify a custom 404 page that will be displayed when a requested resource is not found.

  6. Click "Save" to enable static website hosting on your storage account.

Step 2: Upload Static Files

  1. In the storage account's left-hand menu, navigate to the "Containers" section and click on the "$web" container.

  2. Upload your static files to the "$web" container. If you are using React, run npm run build or yarn build and upload the contents of the build or dist folder.

  3. In the storage account's left-hand menu, click on the "Static website" section.

  4. From the overview page, copy the static site endpoint. Open it in a web browser to verify if your static website is working correctly.

Part 2: Configuring a Custom Domain and Enabling HTTPS with Azure CDN

A static website hosted on Azure Storage is already a great way to serve your content. But to take it a step further and enhance its functionality and performance, you can configure a custom domain and enable HTTPS using Azure CDN (Content Delivery Network).

Step 1: Create a new CDN endpoint for the custom domain

To start, you need to create a new CDN (Content Delivery Network) endpoint in Azure. This endpoint acts as a gateway between your custom domain and the underlying storage account hosting your static website.

  1. In the Azure portal, navigate to your resource group and click on "Add" to create a new resource.

  2. Search for "CDN" in the search bar and select "CDN" from the results.

  3. Choose the Azure CDN from Microsoft option. Click on "Create" to begin configuring the CDN endpoint.

Step 2: Select "Storage Static Site" as the origin type for the CDN endpoint

When configuring the CDN endpoint, you need to specify where it should fetch content from. In this case, since we are using Azure Storage to host our static website, we will select "Storage Static Site" as the origin type.

  1. In the "Origin Type" section of the CDN endpoint configuration, choose "Storage Static Site" from the dropdown menu.

  2. Select your "Origin Hostname" from the list of available hostnames.

  3. Click on Review + create.

Step 3: Map the custom domain to the CDN endpoint using CNAME records

Now that you have set up your CDN endpoint, it's time to map your custom domain to it. This involves adding CNAME (Canonical Name) records in your DNS settings that point your domain name to the CDN endpoint.

  1. Go to your domain service provider (e.g., Namecheap) and access the domain management settings for your custom domain.

  2. Look for the DNS settings or advanced DNS settings section.

  3. Add two CNAME records:

  • The first record should have "@" or your root domain as the host and the CDN endpoint as the value.

  • The second record should have "www" as the host and again use the CDN endpoint as the value.

  • Save the DNS changes and wait for around an hour for the DNS records to propagate.

Step 4: Configure Custom Domain and Enable HTTPS

  1. In the Azure Portal, select the CDN endpoint you created earlier.

  2. Go to the custom domain feature and click on "Add custom domain".

  3. Enter your custom domain name and click on "Add" to add it to the CDN endpoint.

  4. Select the custom domain and toggle the switch to enable HTTPS for your custom domain.

  5. Choose whether to use a managed certificate or bring your own certificate.

  • Managed certificate: Azure CDN can automatically provision a free SSL certificate from Azure Key Vault. In this Tutorial, we will be using the CDN Managed Cerificate.

  • Bring your own certificate: If you have a custom SSL certificate from a trusted certificate authority (CA), you can upload it to Azure Key Vault and use it for your custom domain.

  1. It may take around an hour for the SSL certificate to be provisioned.

Part 3: Setting Up CI/CD with GitHub Actions for Automatic Deployment

CI/CD (Continuous Integration/Continuous Deployment) is crucial for streamlining the development process and ensuring rapid and reliable deployments. With CI/CD, developers can automate the building, testing, and deployment of code, resulting in increased efficiency and reduced errors.

Step 1: Generate deployment credentials using Azure CLI and service principal

Next, you'll need to generate deployment credentials using Azure CLI and set up a service principal:

  • Utilize the Azure CLI to create a service principal, which is an identity created for use with applications, services, and automation tools.

  • Assign specific roles and permissions to the service principal for accessing resources within your Azure subscription.

      az ad sp create-for-rbac --name "myML" --role contributor \
                                   --scopes /subscriptions/<subscription-id>/resourceGroups/<group-name> \
                                   --json-auth
    
  • In the example above, replace the placeholders with your subscription ID, resource group name, and app name. The output is a JSON object with the role assignment credentials that provide access to your App Service app similar to below. Copy this JSON object for later.

      {
        "clientId": "<azure-app-id>",
        "clientSecret": "<azure-client-secret>",
        "tenantId": "<azure-tenant-id>",
        "subscriptionId": "<azure-subscription-id>"
      }
    

Step 2: Use GitHub Secrets to securely store the deployment credentials

To ensure that your deployment credentials are stored securely, you can use GitHub Secrets:

  • Create a Github Repo for your Static Site if you have not already.

  • Go to your Repository Settings which contains the static site and select Actions from Secrets and variables. Click on New Repository secret.

  • Define these secrets within your repository's settings, allowing them to be accessed by your GitHub Actions workflow without exposing them in your codebase.

  • Click on Add Secret.

Step 3: Set up a GitHub Actions workflow to deploy the static website to Azure Storage

Here's how you can create a workflow to automatically deploy your static website to Azure Storage using GitHub Actions:

  • Start by creating a .github/workflows directory in your GitHub repository.

  • Within this directory, add a YAML file (e.g., deploy.yml) to define the workflow for deploying your static website.

      name: Deploy To Azure Storage
    
      on:
          push:
              branches: main
    
      jobs:
        build:
          runs-on: ubuntu-latest
          steps:
          - uses: actions/checkout@v3
          - uses: azure/login@v1
            with:
                creds: ${{ secrets.AZURE_CREDENTIALS }}
    
          - name: Upload to blob storage
            uses: azure/CLI@v1
            with:
              inlineScript: |
                  az storage blob upload-batch --account-name <STORAGE_ACCOUNT_NAME> --auth-mode key -d '$web' -s . 
          - name: Purge CDN endpoint
            uses: azure/CLI@v1
            with:
              inlineScript: |
                 az cdn endpoint purge --content-paths  "/*" --profile-name "CDN_PROFILE_NAME" --name "CDN_ENDPOINT" --resource-group "RESOURCE_GROUP"
    
        # Azure logout
          - name: logout
            run: |
                  az logout
            if: always()
    
  • Remember to replace <STORAGE_ACCOUNT_NAME>, CDN_PROFILE_NAME, CDN_ENDPOINT, and RESOURCE_GROUP with your actual values. The secrets.AZURE_CREDENTIALS should be set in your GitHub repository’s secrets settings. You can read more about GitHub Actions here.

  • If you're using a framework, don't forget to add the build or dist folder.

      az storage blob upload-batch --account-name <STORAGE_ACCOUNT_NAME> --auth-mode key -d '$web' -s dist/ --overwrite
    

By following these steps, you can establish a seamless CI/CD pipeline using GitHub Actions for deploying your static website to Azure Storage. This automated approach not only saves time but also maintains consistency across deployments while enhancing security through encrypted credential management.

Conclusion

As you can see, hosting a static website on Azure Storage with a custom domain and CI/CD pipeline is a straightforward process that offers numerous benefits.

Remember to monitor and manage your Azure resources to ensure the availability and performance of your static website.

Did you find this article valuable?

Support Vishesh Gubrani by becoming a sponsor. Any amount is appreciated!