Static Website Hosting on Azure Cloud and CI/CD with Azure DevOps #10WeeksofCloudOps (Week 1/10)
Synopsis
Hello everyone, my name is Nishant Singh, and currently, I am learning DevOps. Practical implementation of what I learn is one of the things I appreciate about Piyush Sachdeva. He provides amazing free content to everyone. This blog is also one of the challenges given by him, #10WeeksOfCloudOps, and it is my first challenge. In this challenge, we are required to host a static website on the cloud using AWS (S3), Azure (Storage Account), and GCP (Cloud Storage). Since I am preparing for the AZ-104 exam, I decided to create this amazing project in Azure Cloud and utilize Azure Storage Account. Additionally, we need to use a CDN, so I will be using Azure CDN. I am excited about the requirement to create a CI/CD pipeline as well! For this, I will be using Azure DevOps. So, let's build this amazing project together!
Prerequisite
Azure Account
Azure DevOps Account
Static Website (I have my own created by Chat.. ME ๐คช)
Domain name
And Some Patience ๐
Architecture
I have posted this architecture diagram for your ease ๐
Before starting, I have something to tell you: the full infrastructure script of this project is already prepared. If you want, you can run this script on your machine to set up the project entirely. You will need to perform some tasks after that as well.
So, Let's Start ๐ค
If you plan to follow the steps below without using the script, kindly ensure that you take note of any instructions marked with 'NOTE'. These notes indicate the need to modify specific aspects of the pipeline script.
Azure Portal setup
Login to your Azure Account and Search for Resource Group
Click on Create Resource Group.
Enter Resource Group Name (eg:
StaticWebsiteRG
)NOTE
Search for Storage Account and Click on Create Storage Account
Select the previously entered Resource Group and provide a unique name for the Storage Account (e.g.,
staticstoragewebsite
).NOTE
For Enabling Static Website in Storage Account. In the Overview pane, navigate to the Capabilities tab, and then select Static Website. This will display the configuration page for the static website.
In the Index document name field, type the name of the default index page for your website (e.g.,
index.html
). This page will be displayed when users navigate to the root of your website. In the Error document name field, type the name of the default error page (e.g.,error.html
or404.html
). This page will be shown when users try to navigate to a page that does not exist.Click on
Save
to save the changes. Afterwards, click on the$web
container, which will serve as the server holding your site code for your static website.NOTE Primary Endpoint
Upload your website code to the
$web
containerPaste the URL of the Primary Endpoint into your browser to view your website.
Congratulations! ๐คWe have deployed a Static website.
Now, Our website is on the internet, but to ensure customer satisfaction and provide them with quick access to our website without delay, we will create an Azure CDN endpoint. This endpoint will allow customers to access our website without delay as it will be cached on a server closer to them.
Search for Front Door and CDN profiles and click on Create. Then, select the options provided below and Continue
Select Resource Group and Enter the Name for your CDN Profile (eg:
staticwebsitecdn
), SelectMicrosoft CDN (classic)
on Pricing Tier and Create CDN profileNow that Our CDN profile setup is complete, the last thing we need to do is connect our static website endpoint to this CDN profile. This connection will provide us with a new endpoint that incorporates the CDN.
After creating the CDN profile, click on Endpoint and enter the necessary fields such as [Name, Origin Type (
Storage Static Website
), Origin Hostname]. Once you have filled in the necessary fields, clickAdd
to add the endpoint.From this point onwards, those who are using the script for infrastructure setup will also follow the below steps.
Now that our CDN Profile and CDN Endpoint which point to Storage Account Static Website URL is configured. But Endpoint provided by CDN endpoint is not good-looking. Why Not Add a Custom Domain !! Let's do that.
Firstly, we need to create a
CNAME
record with our custom domain pointing to the CDN Endpoint. Go to your domain registrar and in the DNS management section, create a newCNAME
record.Now, to add a custom domain to the CDN endpoint, navigate to the CDN profile, select the endpoint that we have created, and click on the
Custom domain
option. Add your Custom domain (eg:staticwebsite.nishudomain.in
)and enable HTTPS.Congratulations! ๐ฅณ We have successfully set up our website, equipped with a CDN to reduce latency and a custom domain that allows anyone to access our website.
Azure DevOps Setup
Now that our website is up and running on our custom domain, leveraging the power of the Azure Cloud's Content Delivery Network, the last step remaining is to automate the process of updating the website code. For this task, we will create a CICD pipeline using Azure DevOps. Let's create a CICD pipeline.
Login to your Azure DevOps account and navigate Organization Settings > Pipelines > Agent pools
Click on
Add Pool
. Now, you might be wondering why we need to create an Agent Pool. Let me explain. As you know, we require some computing resources to run our pipeline. While Azure DevOps provides a default agent, it wasn't working for me due to certain reasons. Therefore, let's create our self-hosted agent.In the Pool Type section, select
Self-Hosted
(Our Local machine eg: laptop, PC) and provide a name for this agent pool (eg: My Computer Agent).NOTE
In the 'Agent' tab, click on 'New Agent' to add an agent.
Select your operating system and download the agent. Follow the provided instructions.
Copy the URL of your Azure DevOps.
NOTE
After running the config script, it will prompt for the Server URL. Enter the URL you copied in the previous step.
Next, it will ask for a Personal Access Token (PAT). Press
Enter
and navigate to the top-right corner of the page. Click on User Settings, then go to Personal Access Token, and select New Token.Enter the same options as given below. Once you create the token, paste it into the running configuration script when prompted. It will then ask for the Agent Pool. Enter the name of the pool you noted earlier, followed by the agent's name.
Now, Run run.sh
Linux
scriptOur Agent is Online and ready for the Job.
Now that we have our agent set up, the last step before setting up the pipeline is to authenticate with your Azure Cloud subscription where all our resources are running. To achieve this, we will create a service connection with Azure Resource Manager in Azure DevOps.Let's go to the Azure portal and search for Azure Active Directory. We will be creating a
Service Principal
.In the Azure portal, click on the
App registrations
tab.Click on
New registration
Enter a name for the application (eg:
AzureDevopsReg
) and selectWeb
as the Redirect URL option. Create the application.Now that we have created the service principal, it doesn't have access to the subscription. Search for
Subscription
in the Azure portal.Click on
Access Control
.Click on
Add
and selectNew Role Assignments
.Select the given options for now, but if desired, you can provide more specific constraints on permissions.
In the
Member
section, add your service principal and create a role.Now that we have assigned roles to our service principal, the only thing left is to add it to Azure DevOps. Move to Azure DevOps and create a new project (eg :
Static Website
)In the Project Settings, under the pipeline section, select Service Connection and then click on Create Service Connection.
Select
Azure Resource Manager
After Clicking
Next
, selectService Principal (manual)
Enter relevant details
For the Subscription Id and Subscription Name paste the previously noted text. For the Service Principal Id and Service Principal Key go to
App registrations
in Azure AD and copy theapplication (client ID)
for the Service Principal Id. For the Tenant ID copy theDirectory (tenant) ID
and click onCertificates & secrets
.In the
Client secrets
tab, click onNew client secret
and then click on 'Add.'Copy the
Value
for the Service Principal Key and save it, as it will not be visible afterwards.Fill in the copied values and click on
Verify
If the provided values are correct, it will showVerification Succeeded
Fill in the Service Connection name (e.g.,My Azure Students Subscription
), and in the security section, tick the box and save the connection.NOTE Service Connection name
Azure Pipeline
Now that this entire setup is complete, the only thing left is to set up the CICD pipeline. But before we proceed with that, let's take a look at our azure-pipeline.yml file and check if any corrections are needed.
azure-pipeline.yml file
trigger:
- week1
pool: My Computer Agent
steps:
- task: AzureCLI@2
displayName: 'Running Pipeline Script'
inputs:
azureSubscription: 'My Azure Students Subscription'
scriptType: 'bash'
scriptLocation: 'scriptPath'
scriptPath: 'pipeline_script.sh'
As you can see, the pool
field has a value of My Computer Agent
, which is the name we assigned to our self-hosted runner. If you have set it to a different name, please update the value of the pool
accordingly. Similarly, for the azureSubscription
field, it currently has a value of My Azure Students Subscription
, which is the name we assigned to the service connection. If you have set it to a different name, please update the value of azureSubscription
.
This pipeline runs the pipeline_script.sh script in the background. Let's take a look at the content of this pipeline script.
pipeline_script.sh file
#!/bin/bash
AccountName="firstweekofcloudops"
RG="10_Weeks_Of_CloudOps"
ProfileName="CDN-First-Week"
EndPoint="firstweekendpoint"
echo "--------------------------------------------------------"
echo "| Removing previous content from CDN edge locations |"
echo "--------------------------------------------------------"
az cdn endpoint purge \
--name $EndPoint \
--profile-name $ProfileName \
--resource-group $RG \
--content-paths "/*"
echo "--------------------------------------------------------"
echo "| Uploading to Azure Storage Account |"
echo "--------------------------------------------------------"
Connection_String=$(az storage account show-connection-string --name $AccountName --resource-group $RG --query connectionString -o tsv)
az storage blob upload-batch \
-d "\$web" \
-s "website" \
--connection-string $Connection_String \
--overwrite \
--pattern "*"
If you are following this with the automated script provided at the beginning, you don't have to make any changes. However, in the script, you'll notice that we require the AccountName
for the Azure Storage Account, RG
for the Resource Group Name, ProfileName
for the CDN Profile, and EndPoint
for the CDN endpoint connected to Azure Storage. Please replace these placeholders with the values you have previously NOTED.
Now let's see what this pipeline script is doing. Firstly, it will purge all cached data on the edge locations and instruct the CDN to retrieve it from the origin server. Then, it will upload the content to the Storage Account. With the previous purging completed, the website content will be available to end customers.
Additionally, create a Git repository to which we can push updates for the website and have the pipeline triggered through a trigger event. Please ensure that the Git repository structure matches the structure provided below.
.
โโโ azure-pipelines.yml
โโโ pipeline_script.sh
โโโ website
โโโ error.html
โโโ image.jpeg
โโโ index.html
Let's setup Azure DevOps Pipeline
Navigate to the Project section, select the Pipelines tab, and click on
Pipelines
. It will prompt you to specify where your code is located. Since we are using GitHub, selectGitHub
. After that, it will ask you to authorize your GitHub account. Please proceed with the authorization process.Now Select Your Git repository
As we have our yaml pipeline configured, Select
Existing Azure Pipelines YAML file
Now, select the
Branch
and specify the path to your pipeline YAML configuration file.Run your pipeline
Congratulations! ๐ฅณ We have successfully automated the entire process of uploading website code to the Azure Storage Account using the CI/CD pipeline. Now, all you need to do is push your new code to your Git repository. As you push your code, it will trigger the Azure pipeline, and it will automatically deploy your code to the Azure Storage Account. Well done!
Thank you for sticking to this long Blog bye see you soon in my Second Week of the Project