2 minute read

One of the core business tenets is business agility - the ability to adapt to changing market conditions. Similarly, businesses must be agile and must ensure availability through business continuity best practices. Businesses either change or die. How does this affect cloud in particular?

In general, a modular, cloud-agnostic, application that follows the 12 factor methodology can provide business agility, continuity, scalability and cost efficiency. Below I demonstrate avoiding vendor lock-in while using PaaS with an array of architectures. Though similar principles apply to XaaS (read β€œany”-as-a-Service). A modern web application is built using a modern cross-platform programming language, such as ASP.NET 7 MVC, which can run on any system - Linux based or Windows based. One can either take a code-first or database-first approach. This choice will largely depend on the size of the application and enterprise or team complexity - smaller teams may benefit from code-first, but larger teams often must follow strict change management processes, which require a database-first approach. The below diagrams show a systematic approach to design such a modern web-app. More detail and sample code can be found in my GitHub repo found here: GitHub Platform Agnostic App.

Architecture Diagrams

Logical Architecture using MVC Pattern

Microsoft Azure Physical Architecture

Google Cloud Platform Architecture

CI/CD with GitHub Actions


GitHub Actions for Microsoft Azure


name: GitHub Actions for Azure

env:
  AZURE_WEBAPP_NAME: friendly-octo-giggle   # set this to your application's name
  AZURE_WEBAPP_PACKAGE_PATH: '.'      # set this to the path to your web app project, defaults to the repository root
  DOTNET_VERSION: '6.0.x'                 # set this to the .NET Core version to use

on: 
  workflow_dispatch:
        
jobs:
  build:
    runs-on: ubuntu-latest
    
    steps:
      - uses: actions/checkout@v4

      - name: Set up .NET Core
        uses: actions/setup-dotnet@v3
        with:
          dotnet-version: ${{ env.DOTNET_VERSION }}

      #substitute production appsettings entries to appsettings json file
      - name: App Settings Variable Substitution
        uses: microsoft/variable-substitution@v1
        with:
          files: './BethanysPieShop/appsettings.json'
        env:
          ConnectionStrings.BethanysPieShopDbContextConnection: ${{ secrets.AZURE_DB_CONNECTION_STRING }}
          
      - name: Build with dotnet
        run: dotnet build --configuration Release

      - name: dotnet publish
        run: dotnet publish -c Release -o ${{env.DOTNET_ROOT}}/myapp

      - name: Upload artifact for deployment job
        uses: actions/upload-artifact@v3
        with:
          name: .net-app
          path: ${{env.DOTNET_ROOT}}/myapp    

  deploy:
    runs-on: ubuntu-latest
    needs: build
    environment:
      name: 'production'
      url: ${{ steps.deploy-to-webapp.outputs.webapp-url }}

    steps:
      - name: Download artifact from build job
        uses: actions/download-artifact@v3
        with:
          name: .net-app
          
      - name: Deploy to Azure Web App
        id: deploy-to-webapp
        uses: azure/webapps-deploy@v2
        with:
          app-name: ${{ env.AZURE_WEBAPP_NAME }}
          publish-profile: ${{ secrets.AZURE_WEBAPP_PUBLISH_PROFILE }}
          package: ${{ env.AZURE_WEBAPP_PACKAGE_PATH }}


GitHub Actions for Google Cloud Platform


name: GitHub Actions for GCP

on: 
  workflow_dispatch:

jobs:
  build:
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v4

      # Substitute production appsettings entries to appsettings json file
      - name: App Settings Variable Substitution
        uses: microsoft/variable-substitution@v1
        with:
          files: './BethanysPieShop/appsettings.json'
        env:
          ConnectionStrings.BethanysPieShopDbContextConnection: ${{ secrets.GCP_DB_CONNECTION_STRING }}

      - id: 'auth'
        name: Authenticate to Google Cloud
        uses: 'google-github-actions/auth@v1'
        with:
          credentials_json: '${{ secrets.GCP_CREDENTIALS }}'
          
      - name: 'Set up Google Cloud SDK'
        uses: 'google-github-actions/setup-gcloud@v1'
          
      - name: Deploy to App Engine
        run: gcloud app deploy ./BethanysPieShop/app.yaml