Skip to content

ondfisk/GitHubDemo

Repository files navigation

GitHub Demo

This repository demonstrates a number of capabilities in GitHub and Microsoft Azure:

  • Continuous Planning using GitHub Issues
  • Continuous Integration using GitHub Repositories and GitHub Actions
  • Continuous Deployment to App Services and Azure SQL using GitHub Actions
  • Continuous Security using GitHub Advanced Security
  • Continuous Monitoring using Azure Monitor and Application Insights
  • Continuous Quality using unit tests and GitHub Actions
  • Database migration using Entity Framework and GitHub Actions
  • Blue/green deployments to App Services using Deployment Slots
  • Local development environments using Dev Containers

Run locally (in a Dev Container)

  1. Create and export development certificate from Windows:

    New-Item $env:USERPROFILE/.aspnet/https -ItemType Directory -Force
    dotnet dev-certs https -ep $env:USERPROFILE/.aspnet/https/aspnetapp.pfx --password "<YourStrong@Passw0rd>"
    dotnet dev-certs https --trust
  2. Copy development certificate to WSL:

    sudo cp /mnt/c/Users/[Windows-Username]/.aspnet/https/aspnetapp.pfx ~/.aspnet/https
  3. Fork the repository.

  4. Clone repository to WSL and open in Visual Studio Code.

  5. Open in Dev Container.

  6. Run locally:

    # Update packages
    dotnet outdated --upgrade
    
    # Restore
    dotnet restore
    
    # Build
    dotnet build
    
    # Set development connection string:
    dotnet user-secrets set "ConnectionStrings:Default" "Host=localhost;Port=5432;Database=postgres;Username=postgres;Password=postgres" --project src/MovieApi/
    
    # Update database:
    dotnet ef database update --project src/MovieApi/
    
    # Test
    dotnet test
    
    # Run
    dotnet watch run --project src/MovieApi/
  7. Browse to https://localhost:8001/Movies to inspect API:

    [
       {
          "id": 5,
          "title": "12 Angry Men",
          "director": "Sidney Lumet",
          "year": 1957
       },
       {
          "id": 8,
          "title": "Pulp Fiction",
          "director": "Quentin Tarantino",
          "year": 1994
       },
       ...
    ]

Deploy to Azure

  1. Login to Azure and GitHub:

    az login
    gh auth login
  2. Declare input variables

    SUBSCRIPTION=$(az account show --query id --output tsv)
    RESOURCE_GROUP="GitHubDemo"
    GITHUB_ORGANIZATION="ondfisk"
    REPOSITORY="GitHubDemo"
    APP_REGISTRATION_DISPLAY_NAME="$GITHUB_ORGANIZATION-$REPOSITORY"
  3. Create a Microsoft Entra application (SPN) and connect it to GitHub:

    CLIENT_ID=$(az ad app create --display-name $APP_REGISTRATION_DISPLAY_NAME --query appId --output tsv)
    OBJECT_ID=$(az ad sp create --id $CLIENT_ID --query id --output tsv)
    
    az role assignment create --assignee $OBJECT_ID --role "Owner" --scope "/subscriptions/$SUBSCRIPTION"
    
    az ad app federated-credential create --id $CLIENT_ID --parameters "{ \"name\": \"$GITHUB_ORGANIZATION-$REPOSITORY-Environment-Staging\", \"issuer\": \"https://token.actions.githubusercontent.com\", \"subject\": \"repo:$GITHUB_ORGANIZATION/$REPOSITORY:environment:Staging\", \"description\": \"Deploy to staging environment\", \"audiences\": [ \"api://AzureADTokenExchange\" ] }"
    
    az ad app federated-credential create --id $CLIENT_ID --parameters "{ \"name\": \"$GITHUB_ORGANIZATION-$REPOSITORY-Environment-Production\", \"description\": \"Deploy to production environment\", \"issuer\": \"https://token.actions.githubusercontent.com\", \"subject\": \"repo:$GITHUB_ORGANIZATION/$REPOSITORY:environment:Production\", \"audiences\": [ \"api://AzureADTokenExchange\" ] }"
  4. Set repository secrets:

    TENANT=$(az account show --query tenantId --output tsv)
    
    gh secret set AZURE_TENANT_ID --body "$TENANT"
    gh secret set AZURE_SUBSCRIPTION_ID --body "$SUBSCRIPTION"
    gh secret set AZURE_CLIENT_ID --body "$CLIENT_ID"
    gh secret set AZURE_CLIENT_DISPLAY_NAME --body "$APP_REGISTRATION_DISPLAY_NAME"
  5. Create a Log Analytics Workspace and an App Service Plan if needed.

  6. Update infrastructure/main.bicepparam.

  7. Push the changes to trigger the infrastructure workflow.

  8. Grant SPN access to PostgreSQL server:

    DATABASE_SERVER=$(az postgres flexible-server list --resource-group $RESOURCE_GROUP --query [].name --output tsv)
    
    az postgres flexible-server microsoft-entra-admin create --display-name "$APP_REGISTRATION_DISPLAY_NAME" --object-id $OBJECT_ID --resource-group $RESOURCE_GROUP --server-name $DATABASE_SERVER --type ServicePrincipal
  9. Grant web app permission to database:

    WEB_APP=$(az webapp list --resource-group $RESOURCE_GROUP --query [].name --output tsv)
    SLOT="staging"
    DATABASE="Movies"
    STAGING_DATABASE="MoviesStaging"
    
    az extension add --name serviceconnector-passwordless
    
    az webapp connection create postgres-flexible --resource-group $RESOURCE_GROUP --name $WEB_APP --target-resource-group $RESOURCE_GROUP --server $DATABASE_SERVER --database $DATABASE --system-identity --client-type dotnet --connection $DATABASE --new --opt-out configinfo
    
    az webapp connection create postgres-flexible --resource-group $RESOURCE_GROUP --name $WEB_APP --slot $SLOT --target-resource-group $RESOURCE_GROUP --server $DATABASE_SERVER --database $STAGING_DATABASE --system-identity --client-type dotnet --connection $STAGING_DATABASE --new --opt-out configinfo
  10. Run the application workflow from GitHub.

Clean up

az group delete --name $RESOURCE_GROUP
az ad app delete --id $CLIENT_ID

Notes

To lint repository locally run (from WSL):

docker run -e DEFAULT_BRANCH=main -e RUN_LOCAL=true -e VALIDATE_GIT_COMMITLINT=false -e VALIDATE_JSCPD=false -e FIX_JSON=true -e FIX_JSON_PRETTIER=true -e FIX_JSONC=true -e FIX_JSONC_PRETTIER=true -e FIX_MARKDOWN=true -e FIX_MARKDOWN_PRETTIER=true -e FIX_YAML_PRETTIER=true -v .:/tmp/lint --rm ghcr.io/super-linter/super-linter:latest

Links

About

This project demonstrates a number of capabilities in GitHub and Microsoft Azure

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors 2

  •  
  •