Azure / reliable-web-app-pattern-dotnet

The Reliable Web App Pattern is a set of objectives to help your web application converge on the cloud. This repo contains a reference implementation of a reliable web application for .NET.
https://aka.ms/eap/rwa/dotnet/doc
MIT License
379 stars 120 forks source link

Simple Dev Containers configuration #214

Closed briandenicola closed 1 year ago

briandenicola commented 1 year ago

This pull request creates a simple dev container to address issue - #104

It has all the tools required to build and publish the application code. It also has Visual Studio extensions that can help further development.

KSchlobohm commented 1 year ago

Enables access to provision resources and to deploy code but does not provide ability to use Azure AD operations

e.g.

briandenicola commented 1 year ago

I have confirmed Azure AD operations also function without issue within the Code Space. I've run the validation script and it passed. The website is also functional when browsing to the URL including Sign In/Sign out. Is there anything that I am missing?

This is my Codespace information: Environ: GitHub Codespaces Kernel: 5.4.0-1100-azure Version: 11 (bullseye) IP: 172.16.5.4 / 20.125.119.54 Host: codespaces-264dca

Enables access to provision resources and to deploy code but does not provide ability to use Azure AD operations

  • bash ./infra/createAppRegistrations.sh -g "$myEnvironmentName-rg"
/workspaces/reliable-web-app-pattern-dotnet (main ✗) az login
A web browser has been opened at https://login.microsoftonline.com/organizations/oauth2/v2.0/authorize. Please continue the login in the web browser. If no web browser is available or if the web browser fails to open, use device code flow with `az login --use-device-code`.
...
/workspaces/reliable-web-app-pattern-dotnet (main ✗) az account set -s bjd_subscription
/workspaces/reliable-web-app-pattern-dotnet (main ✗) export myEnvironmentName=relecloud
/workspaces/reliable-web-app-pattern-dotnet (main ✗) bash ./infra/createAppRegistrations.sh -g "$myEnvironmentName-rg"
Inputs
----------------------------------------------
resourceGroupName='relecloud-rg'

Derived inputs
----------------------------------------------
isProd=false
keyVaultName=rc-v5vcsmsh3g6ps-kv
appConfigSvcName=v5vcsmsh3g6ps-appconfig
frontEndWebAppUri=https://web-v5vcsmsh3g6ps-web-app.azurewebsites.net
resourceToken=v5vcsmsh3g6ps
environmentName=relecloud
secondaryResourceGroupName=relecloud-secondary-rg

Runtime values
----------------------------------------------
frontEndWebAppName='relecloud-v5vcsmsh3g6ps-frontend'
apiWebAppName='relecloud-v5vcsmsh3g6ps-api'
maxNumberOfRetries=20
tenantId='1380bd4a-df76-4123-b482-56fec1eeb67e'

frontEndWebAppClientId='445ac345-fc4f-49bc-8481-10b33087ea9a'
... created clientSecret for front-end

Set keyvault value for: 'AzureAd--ClientSecret'
Set appconfig value for: 'AzureAd:TenantId'
Set appconfig value for: 'AzureAd:ClientId'

Finished app registration for front-end

apiWebAppClientId='85b19855-71bb-4164-a8b0-45a381a830a6'
... retrieved apiObjectId='d0af22d0-ffd3-4e6d-984c-eeccf9574874'
... added scope relecloud.api
... assigned scope to api
... retrieved permId=c791b666-cc87-4904-bc9f-c5945e08ba8f
front-end web app is now preAuthorized

Set appconfig value for: 'App:relecloudApi:AttendeeScope'
Set appconfig value for: 'Api:AzureAd:ClientId'
Set appconfig value for: 'Api:AzureAd:TenantId'

Derived inputs for second azure location
----------------------------------------------
secondaryKeyVaultName=
secondaryAppConfigSvcName=
No secondary vault to configure
/workspaces/reliable-web-app-pattern-dotnet (main ✗) az ad app list --filter "displayName eq 'relecloud-v5vcsmsh3g6ps-frontend'" 
[
  {
    "addIns": [],
    "api": {
      "acceptMappedClaims": null,
      "knownClientApplications": [],
      "oauth2PermissionScopes": [],
      "preAuthorizedApplications": [],
      "requestedAccessTokenVersion": null
    },
    "appId": "445ac345-fc4f-49bc-8481-10b33087ea9a",
    "appRoles": [
      {
        "allowedMemberTypes": [
          "User"
        ],
        "description": "relecloud Administrator",
        "displayName": "relecloud Administrator",
        "id": "0abf4cc6-0016-4bbf-ac55-ee368bc6e004",
        "isEnabled": true,
        "origin": "Application",
        "value": "Administrator"
      }
    ],
    "applicationTemplateId": null,
    "certification": null,
    "createdDateTime": "2023-01-26T14:08:11Z",
    "defaultRedirectUri": null,
    "deletedDateTime": null,
    "description": null,
    "disabledByMicrosoftStatus": null,
    "displayName": "relecloud-v5vcsmsh3g6ps-frontend",
    "groupMembershipClaims": null,
    "id": "8e7ebcda-5050-4d06-90b4-48e9bcc61682",
    "identifierUris": [],
....
  • bash ./infra/makeSqlUserAccount.sh -g "$myEnvironmentName-rg"

    /workspaces/reliable-web-app-pattern-dotnet (main ✗) bash ./infra/addLocalIPToSqlFirewall.sh -g "$myEnvironmentName-rg"
    {
    "endIpAddress": "20.125.119.54",
    "id": "/subscriptions/2d1c19ef-dc46-4d0e-b4b9-be1613da164b/resourceGroups/relecloud-rg/providers/Microsoft.Sql/servers/v5vcsmsh3g6ps-sql-server/firewallRules/devbox_2023-01-26_02-22-41",
    "name": "devbox_2023-01-26_02-22-41",
    "resourceGroup": "relecloud-rg",
    "startIpAddress": "20.125.119.54",
    "type": "Microsoft.Sql/servers/firewallRules"
    }
    found sqlcmd
    connecting to: v5vcsmsh3g6ps-sql-server.database.windows.net
    opening: v5vcsmsh3g6ps-sql-database
    {
    "azureAdOnlyAuthentication": false,
    "id": "/subscriptions/2d1c19ef-dc46-4d0e-b4b9-be1613da164b/resourceGroups/relecloud-rg/providers/Microsoft.Sql/servers/v5vcsmsh3g6ps-sql-server/azureADOnlyAuthentications/Default",
    "name": "Default",
    "resourceGroup": "relecloud-rg",
    "type": "Microsoft.Sql/servers"
    }
    {
    "azureAdOnlyAuthentication": true,
    "id": "/subscriptions/2d1c19ef-dc46-4d0e-b4b9-be1613da164b/resourceGroups/relecloud-rg/providers/Microsoft.Sql/servers/v5vcsmsh3g6ps-sql-server/azureADOnlyAuthentications/Default",
    "name": "Default",
    "resourceGroup": "relecloud-rg",
    "type": "Microsoft.Sql/servers"
    }
  • the cmds we provide to "Grant your account access to Azure App Configuration Service"

    
    /workspaces/reliable-web-app-pattern-dotnet (main ✗) appConfigDataReaderRole='516239f1-63e1-4d78-a4de-a74fb236a071'
    /workspaces/reliable-web-app-pattern-dotnet (main ✗) currentUserObjectId=$(az ad signed-in-user show --query "id" -o tsv)
    /workspaces/reliable-web-app-pattern-dotnet (main ✗) scopeId=$(az group show -n "$myEnvironmentName-rg" --query "id" -o tsv)
    /workspaces/reliable-web-app-pattern-dotnet (main ✗) az role assignment create --role $appConfigDataReaderRole --assignee $currentUserObjectId --scope $scopeId
    {
    "canDelegate": null,
    "condition": null,
    "conditionVersion": null,
    "description": null,
    "id": "/subscriptions/2d1c19ef-dc46-4d0e-b4b9-be1613da164b/resourceGroups/relecloud-rg/providers/Microsoft.Authorization/roleAssignments/94586c44-7cc3-41d6-8800-b724c0d76654",
    "name": "94586c44-7cc3-41d6-8800-b724c0d76654",
    "principalId": "cd3cbaf1-9b7a-4b1a-9e19-a13a630b88fe",
    "principalType": "User",
    "resourceGroup": "$myEnvironmentName-rg",
    "roleDefinitionId": "/subscriptions/2d1c19ef-dc46-4d0e-b4b9-be1613da164b/providers/Microsoft.Authorization/roleDefinitions/516239f1-63e1-4d78-a4de-a74fb236a071",
    "scope": "/subscriptions/2d1c19ef-dc46-4d0e-b4b9-be1613da164b/resourceGroups/relecloud-rg",
    "type": "Microsoft.Authorization/roleAssignments"
    }

/workspaces/reliable-web-app-pattern-dotnet (main ✗) az role assignment list --scope /subscriptions/2d1c19ef-dc46-4d0e-b4b9-be1613da164b/resourceGroups/relecloud-rg -o table Principal Role Scope


6c02bf1c-04ca-454f-ad2a-6cd0494d003b Contributor /subscriptions/2d1c19ef-dc46-4d0e-b4b9-be1613da164b/resourceGroups/relecloud-rg 7411bff2-7a76-469e-9afd-03f25b55a6dd App Configuration Data Reader /subscriptions/2d1c19ef-dc46-4d0e-b4b9-be1613da164b/resourceGroups/relecloud-rg [ACCOUNT_PRINCIPAL_REMOVED] App Configuration Data Reader /subscriptions/2d1c19ef-dc46-4d0e-b4b9-be1613da164b/resourceGroups/relecloud-rg


Additional tests:
``` bash
/workspaces/reliable-web-app-pattern-dotnet (main ✗) bash ./infra/getSecretsForLocalDev.sh -g "$myEnvironmentName-rg"
{
   "Api:AppConfig:Uri": "https://v5vcsmsh3g6ps-appconfig.azconfig.io",
   "Api:AzureAd:ClientId": "85b19855-71bb-4164-a8b0-45a381a830a6",
   "Api:AzureAd:TenantId": "1380bd4a-df76-4123-b482-56fec1eeb67e",
   "App:RedisCache:ConnectionString": "v5vcsmsh3g6ps-rediscache.redis.cache.windows.net:6380,password=[REDACTED],ssl=True,abortConnect=False",
   "App:SqlDatabase:ConnectionString": "Server=tcp:v5vcsmsh3g6ps-sql-server.database.windows.net,1433;Initial Catalog=v5vcsmsh3g6ps-sql-database;Authentication=Active Directory Default",
   "App:StorageAccount:QueueConnectionString": "DefaultEndpointsProtocol=https;AccountName=v5vcsmsh3g6psstorage;AccountKey=[REDACTED];EndpointSuffix=core.windows.net"
}

/workspaces/reliable-web-app-pattern-dotnet (main ✗) bash ./infra/validateDeployment.sh -g "$myEnvironmentName-rg"
All settings validated successfully...
If this script was unable to diagnose your problem then please create a GitHub issue
KSchlobohm commented 1 year ago

Thanks for this PR @briandenicola - this is looking like a good fit. When I run it, I hit an AAD error about managing resources from an approved device, so I've asked @kwkraus to take a look.

kwkraus commented 1 year ago

@KSchlobohm My default subscription 'kkraus-MCAPS-Hybrid' did not let me authenticate with error 'AADSTS530004' AcceptCompliantDevice setting not configured.

image

I received the same AAD errors that you did on my kkraus-Microsoft-Internal (AIRS) subscription. This is my old subscription that will be decommissioned very soon.

When running the bash ./infra/createAppRegistration.sh -g "$myEnvironment-rg" command I received this error

image

kwkraus commented 1 year ago

@briandenicola First attempts at running devcontainer locally, with a Windows based git repo, showed issues with EOL characters in the post-create.sh and post-start.sh scripts. This was solved by running sed command to updated line endings.

Then ran into issues with missing tooling. Needed to install Docker Engine on WSL in order for the container to build successfully.

I then ran into the need to install Bicep using az bicep upgrade command, would be nice to have already installed on container.

provisioning and createAppRegistration.sh ran just fine, but my azd deploy command failed with the following error

image

ended up deleting the bin and obj folders from src folder and re-ran azd deploy and everything seemed to work.

Think there needs to be clear guidance on how to use devcontainers prior to making it available.

briandenicola commented 1 year ago

Hi @kwkraus. I updated the devcontainer.json to eliminate the need for the post creation/startup scripts. Since they were only a couple commands, I integrated them directly into the devcontainer. This should eliminate any line feed issue on Windows.

The devcontainer.json also includes the az bicep upgrade command by default.

I also add documentation on how to use the Dev Container and linked to it from the Readme.md

kwkraus commented 1 year ago

Hi @kwkraus. I updated the devcontainer.json to eliminate the need for the post creation/startup scripts. Since they were only a couple commands, I integrated them directly into the devcontainer. This should eliminate any line feed issue on Windows.

The devcontainer.json also includes the az bicep upgrade command by default.

I also add documentation on how to use the Dev Container and linked to it from the Readme.md

@briandenicola You stated that the need for post creation/startup scripts has been eliminated, but it still appears that the post-create.sh file is still being referenced in the devcontainer.json file. Thus the need to guide the user to use the sed command to updated EOL characters.

The deployment markdown states to run task up command. when i tried it stated that I needed the TaskWarrior tool to make work sudo apt install taskwarrior.

It also appears that the postStartCommand within devcontainer.json is failing due to unknown argument --version

image