I built this website in Gatsby.js. The MobX library was used to manage the state of the application, while Styled Components and Framer Motion were used for page styling and animations. Application pages are dynamically created by GraphQL queries that retrieve data from markdown files. Also, like all my React projects, this one is built with TypeScript to write safer and better code.
- Dark and light theme,
- Canvas eraser effect ,
- Custom cursor,
- Markdown files as a source content.
Application | Infrastructure |
---|---|
GatsbyJS v5 | Azure |
MobX | GitHub |
TypeScript | GitHub Actions |
GraphQL | Terraform |
Markdown | Terraform Cloud |
Styled Components | OVH |
Framer Motion | Google Analytics |
IcoMoon | diagrams.net |
Eslint | |
Prettier |
- Node.js v18.
-
Navigate into .\gatsby-app directory and run the following command to download packages:
npm install
-
Optionally you can create .env.development and .env.production files in the .\gatsby-app folder by setting the following environment variables:
- GOOGLE_ANALYTICS_TRACKING_ID - this is the Google Analytics Measurement Id. Plugin
gatsby-plugin-google-gtag
only works in production mode. To test your Global Site Tag is installed and firing events correctly run:gatsby build && gatsby serve
- GATSBY_AZURE_APPLICATION_INSIGHTS_CONNECTION_STRING - this is the Azure Application Insights Connection String.
- GOOGLE_ANALYTICS_TRACKING_ID - this is the Google Analytics Measurement Id. Plugin
-
Start the development environment:
gatsby develop
Your site is now running at http://localhost:8000
.
The Application Infrastructure consists of one environment - production. Gatsby SPA is deployed to an Azure Static Web App which can have multiple preview environments. Therefore, each pull request deploys a preview version of the site available through a temporary URL.
Resource | Purpose | Name |
---|---|---|
Azure Service Principal1 | application (service principal) for authenticating sivonte organization to Terraform Cloud | sp-terraform-cloud-sivonte |
Azure Resource Group2 | a container for Azure resources | rg-portfolio-prod |
Azure DNS Zones2 | domain hosting and management | sivonte.com |
Azure Static Web App2 | web hosting for static site .\gatsby-app |
appi-portfolio-prod |
Azure Application Insights2 | website monitoring | stapp-portfolio-prod |
Azure Log Analytics Workspace2 | analysis of log data collected from Application Insights | log-portfolio-prod |
Azure Monitor Action Groups2 | collection of notification preferences | ag-developers-portfolio-prod |
Azure Monitor Alerts2 | alerts that there may be an infrastructure or application problem | ar-failure-anomalies-portfolio-prod |
Terraform Cloud | remote state management of infrastructure | portfolio-prod |
OVH | domain registration | sivonte.com |
GitHub / GitHub Actions | git repository and CI/CD tool | portfolio-website |
Google Analytics | website traffic | portfolio-prod |
The Deployment consists of two parts: infrastructure_deployment.yml and application_deployment.yml. First, the Application Infrastructure is deployed, and then the SPA application itself. The developer creates a pull request to the master branch that starts the deployment process as shown in the Deployment Architecture figure. Two rules have been created for the master branch:
- require a pull request before merging,
- require status checks to pass before merging:
Infrastructure Deployment
andApplication Deployment / Build and Deploy
.
After successfully deploying the SPA application to the preview environment, the developer can test the website and merge the pull request, which triggers:
- the same deployment process as before, but this time to the production environment,
- remove the temporary (preview) environment: close_pull_request.yml.
- Connect Google Analytics to Gatsby application:
- create an
Account
and aProperty
in Google Analytics, - create a
Web
as a data stream for the Property set above and copy theMeasurement Id
, - in your repository create a secret named GOOGLE_ANALYTICS_TRACKING_ID, setting the Measurement Id.
- create an
- Connect Terraform Cloud to Azure using a Azure Service
Principal with a Client Secret:
- register an application with Azure AD and create a Service Principal using the Azure Portal or Azure PowerShell ,
- assign a Contributor role to the application,
- create an application secret and copy it,
- create a workspace in Terraform Cloud with
API-driven workflow
, - create variables in workspace:
- ARM_SUBSCRIPTION_ID - the ID of the Azure Subscription where resources will be created,
- ARM_TENANT_ID - this is the Azure Directory (tenant) ID of the Service Principal,
- ARM_CLIENT_ID - this is the Application (client) ID of the Service Principal,
- ARM_CLIENT_SECRET - mark as sensitive, this is the Application Secret for the Service Principal,
- in Workspace Settings set:
- Execution Mode to
Remote
, - Terraform Working Directory to infrastructure/azure/prod,
- Execution Mode to
- in repository in \infrastructure\azure\prod\config.tf set your organization and workspace name.
# Terraform Cloud setup cloud { organization = "your_organization_name" workspaces { name = "your_workspace_name" }
- Connect Terraform Cloud
to GitHub Actions:
- create API token in Terraform Cloud,
- in your repository create a secret named TERRAFORM_CLOUD_API_TOKEN, setting the Terraform Cloud API token.
- In .\infrastructure\azure\prod\terraform.tfvars set your domain name.
dns_zone_name = "your_domain_name"
- Run
Deploy Infrastructure to Azure
workflow in GitHub Actions. - The first run will fail because you need to:
- delegate your domain to Azure - on the DNS management page of your existing registrar provider, replace the DNS server records with name servers that you created in the previous step in the Azure DNS Zones,
- in your repository create secrets:
- AZURE_STATIC_WEB_APPS_API_TOKEN setting the Static Web App Deployment Token,
- AZURE_APPLICATION_INSIGHTS_CONNECTION_STRING setting the Application Insights Connection String.
- Run
Deploy Infrastructure to Azure
again.
This project is licensed under the MIT License.
Krzysztof Talar - Linkedin - krzysztof.talar@protonmail.com