Saying Goodbye to Google Sites
I’m sure that plenty of people have a use for Google Sites and the prebuilt templates, but I simply couldn’t find one that did what I wanted. So I built an ask list:
- Static content (no JavaScript, etc.)
- Cheap/free hosting - I didn’t want to pay $30/month for a prebuilt site with too much flash.
- Automated deployment onto modern infrastructure - I wanted CI/CD practice with a backend that I controlled.
- I wanted custom domain support with cheap/free SSL certificates.
The Stack
After some research, I came up with a stack that was easy to generate and maintain, hosted for free, supported custom domains, and gave me the CI/CD practice I wanted:
- Frontend: Hugo for static site generation with the Papermod theme - Free, easy to use, with a theme that was simple and requires no maintenance.
- Hosting: Azure Static Web Apps - The Free Tier gives you up to 100GB/month per subscription in bandwidth, perfect for a static site with no media like mine (and low traffic) as well as two custom domain names with free SSL certs.
- CI/CD Pipelines - GitHub Actions has a native integration with Azure and the site builds in under two minutes. With 2000 minutes free per month, I’m more than set.
- Infrastructure - Hosted in Azure, with full control of authentication using Microsoft Entra, a tool I use every day at work. And just for fun, I set up SSO using Okta’s free Developer Account.
The Pain in the Process
Getting the Azure Environment working
I work in Azure every day, but I’ve only made a brand new environment from scratch once for myself. Naturally, I ran into issues. When I signed up for this account, I went to portal.azure.com, put in my email address and password and I was in, or so I thought. After I finished setting up my MFA, I went to go make my breakglass admin account in Entra. The problem was, I couldn’t get to that portion of Entra from the portal. What I got instead was:
AADSTS50020: User account 'user@domain.com' from identity provider 'live.com' does not exist in tenant 'Microsoft Services' and cannot access the application '**redacted** in that tenant. The account needs to be added as an external user in the tenant first. Sign out and sign in again with a different Azure Active Directory user account.
Lovely. I’d gone and made myself a live.com account, and been added as a guest in Entra, instead of a primary user. It took me another twenty minutes of trying to break in via Powershell and a few other methods, when it hit me. I’m currently studying for the AZ-400 exam and on every single Microsoft Learn page is a link to make your own free Azure account. I figured if anything, that would actually make a “real” Entra account for me. A few clicks, and I was in. I made a breakglass user, ensured access to the tenant was secured, and deleted my unwanted external guest. I made sure to go sign into the live.com account and change the email used to prevent weird problems in the future too.
The only other issue I ran into was giving myself Azure permissions. There is a hidden toggle under Preferences on the left hand side that allows you to give yourself owner permissions to you Azure subscription. This option only appears if you go to portal.azure.com, search for Entra and load it, versus going to entra.microsoft.com. Make that make sense, because it sure doesn’t to me.
Enabling Okta SSO
This was a completely unnecessary step, but it gave me the opportunity to mess around with a third party SSO that is very well known in the corporate space, and one I am sure to encounter in my next roles. Set up was easy, sign up for a developer’s account (They call it the “Integrator” plan now, apparently), federate to Azure, then add my user and assign the Microsoft 365 application. The only additional step I had to do was force that Okta calls an “immutable id” to be associated with my UPN in Azure. I did this via Microsoft Graph.
Update-MgUser -UserId "user@domain.com" -OnPremisesImmutableId "user@domain.com"
A quick page refresh, and I had my redirect to Okta for SSO set up and signing in with ease.
Azure Static Web Apps
The linchpin to my plan was leveraging Azure’s Static Web Apps, specifically their free hosting tier. Since I’m not delivering active content, and my expected view count isn’t in the hundreds of thousands per month, this is the perfect tier for me. During the process you set up the resource group for the app and give it a name. Azure spits out a string to use as a domain name with a .azurestaticapps.net to start out with. You get two free custom domain adds with the free tier, and you can either purchase and set up a domain via Azure, use a domain you bought elsewhere and Azure’s DNS, or use your registrar as DNS. I chose the third option, since I’m currently hosting my custom domain’s email via Google Workspace (moving to Microsoft soon) there and managing DNS records in two places would be nuts.
The issue I ran into here was that I had a website on Google Sites, and the DNS records live there. It was a painful dance remember which DNS records were for my site and which ones were for my email. Getting this working alone was an hour ordeal, but that was mostly me being stupid and frantically watching Youtube videos and reading tutorials to remind myself. I’m not a DNS expert now, but I know more than I did, so that’s a win.
Setting up Hugo
This is honestly the tutorial hell part, or maybe the “I read too many tutorials and got confused part”. I was convinced that Hugo was this massive undertaking, requiring hours of tweaking and template changes and coding to fix. I couldn’t have been more wrong.
Downloading Hugo is a piece of cake. I used winget but chocolatey works just as well for this. I quickly created a skeleton page and saved it. Next, I initialized a local Git repository and tied to it a private Github repository I’d already made and set up with my static app. Sending a commit to the repository kicks off a Github Actions pipeline that builds the site and sends it to my webapp.
I sent my first commit AND….. build failed. Parsing the error logs, I saw that there was versioning error with Hugo. Whatever Github Actions runs on isn’t able to work with the latest version of Hugo (0.152.0 at time of writing). I had to go into the YAML, change the version to what the error logs said it was expecting, and the build ran (we’re not gonna talk about the four other failed builds because I can’t spell…just…spell things right.). I then uninstalled Hugo, and installed the version I needed for the YAML change (0.146.0) so I could have Dev/Prod parity. Not insanely important in something like this, but it helps.
With the fixes and the site live, I then turned to making the site live and breathe. My About Me Page was made and my Certifications page (in the works) was set up. And now, this blog post has been made.
I certainly learned a lot during this process, and hopefully something in this article helped you as well. I can’t promise a steady stream of posts, but when I get to learn or break something, you’ll be sure to hear about it.