From 0c13ff9e5324eff6dbb31176dc6a5bb4e23fde5e Mon Sep 17 00:00:00 2001 From: zedy Date: Mon, 27 Mar 2023 13:34:34 +0800 Subject: [PATCH] update according to comments --- Directory.Packages.props | 2 +- README.md | 14 +- infra/core/database/sqlserver/sqlserver.bicep | 3 +- infra/core/host/appservice.bicep | 6 +- infra/core/security/keyvault-access.bicep | 2 +- src/Web/AzureDeveloperCliCredential.cs | 148 ------------------ 6 files changed, 19 insertions(+), 156 deletions(-) delete mode 100644 src/Web/AzureDeveloperCliCredential.cs diff --git a/Directory.Packages.props b/Directory.Packages.props index 4573d60e7..802924a72 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -12,7 +12,7 @@ - + diff --git a/README.md b/README.md index 272fb32a7..3caeab2cd 100644 --- a/README.md +++ b/README.md @@ -63,20 +63,28 @@ powershell -ex AllSigned -c "Invoke-RestMethod 'https://aka.ms/install-azd.ps1' curl -fsSL https://aka.ms/install-azd.sh | bash ``` +And you can also install with package managers, like winget, choco, and brew. For more detials, you can follow the documentation: https://aka.ms/azure-dev/install. + After logging in with the following command, you will be able to use the azd cli to quickly provision and deploy the application. ``` azd login ``` -Then, just use the `azd up` command to complete all operations of clone, provision and deployment. +Then, executes the commands `azd init` to initializes environment. +``` +azd init -t dotnet-architecture/eShopOnWeb ``` -azd up -t dotnet-architecture/eShopOnWeb + +And executes the commands `azd up` to complete all operations of provision and deployment. ``` +azd up +``` + According to the prompt, enter an `env name`, and select `subscription` and `location`, these are the necessary parameters when you create resources. Wait a moment for the resource deployment to complete, click the web endpoint and you will see the home page. **Notes:** -Considering security, we store its related data (id, password) in the key vault when we create the database, and obtain it from the key vault when we use it. This is different from directly deploying applications locally. +Considering security, we store its related data (id, password) in the **Azure Key Vault** when we create the database, and obtain it from the Key Vault when we use it. This is different from directly deploying applications locally. You can also run the sample directly locally (See below). diff --git a/infra/core/database/sqlserver/sqlserver.bicep b/infra/core/database/sqlserver/sqlserver.bicep index 1c4c2122b..64477a745 100644 --- a/infra/core/database/sqlserver/sqlserver.bicep +++ b/infra/core/database/sqlserver/sqlserver.bicep @@ -33,7 +33,7 @@ resource sqlServer 'Microsoft.Sql/servers@2022-05-01-preview' = { resource firewall 'firewallRules' = { name: 'Azure Services' properties: { - // Allow all clients + // Allow all clients // Note: range [0.0.0.0-0.0.0.0] means "allow all Azure-hosted clients only". // This is not sufficient, because we also want to allow direct access from developer machine, for debugging purposes. startIpAddress: '0.0.0.1' @@ -127,4 +127,3 @@ resource keyVault 'Microsoft.KeyVault/vaults@2022-07-01' existing = { var connectionString = 'Server=${sqlServer.properties.fullyQualifiedDomainName}; Database=${sqlServer::database.name}; User=${appUser}' output connectionStringKey string = connectionStringKey output databaseName string = sqlServer::database.name -output connectionString string = connectionString diff --git a/infra/core/host/appservice.bicep b/infra/core/host/appservice.bicep index 62e34a658..c65f2b89e 100644 --- a/infra/core/host/appservice.bicep +++ b/infra/core/host/appservice.bicep @@ -32,6 +32,8 @@ param minimumElasticInstanceCount int = -1 param numberOfWorkers int = -1 param scmDoBuildDuringDeployment bool = false param use32BitWorkerProcess bool = false +param ftpsState string = 'FtpsOnly' +param healthCheckPath string = '' resource appService 'Microsoft.Web/sites@2022-03-01' = { name: name @@ -43,12 +45,14 @@ resource appService 'Microsoft.Web/sites@2022-03-01' = { siteConfig: { linuxFxVersion: linuxFxVersion alwaysOn: alwaysOn - ftpsState: 'FtpsOnly' + ftpsState: ftpsState + minTlsVersion: '1.2' appCommandLine: appCommandLine numberOfWorkers: numberOfWorkers != -1 ? numberOfWorkers : null minimumElasticInstanceCount: minimumElasticInstanceCount != -1 ? minimumElasticInstanceCount : null use32BitWorkerProcess: use32BitWorkerProcess functionAppScaleLimit: functionAppScaleLimit != -1 ? functionAppScaleLimit : null + healthCheckPath: healthCheckPath cors: { allowedOrigins: union([ 'https://portal.azure.com', 'https://ms.portal.azure.com' ], allowedOrigins) } diff --git a/infra/core/security/keyvault-access.bicep b/infra/core/security/keyvault-access.bicep index 96c9cf730..aa989ebdc 100644 --- a/infra/core/security/keyvault-access.bicep +++ b/infra/core/security/keyvault-access.bicep @@ -1,6 +1,6 @@ param name string = 'add' -param keyVaultName string = '' +param keyVaultName string param permissions object = { secrets: [ 'get', 'list' ] } param principalId string diff --git a/src/Web/AzureDeveloperCliCredential.cs b/src/Web/AzureDeveloperCliCredential.cs deleted file mode 100644 index 406c7bf47..000000000 --- a/src/Web/AzureDeveloperCliCredential.cs +++ /dev/null @@ -1,148 +0,0 @@ -using Azure.Core; -using System.Diagnostics; -using System.Runtime.InteropServices; -using System.Text.Json; -using System.Text.RegularExpressions; - -namespace Azure.Identity -{ - public class AzureDeveloperCliCredential : TokenCredential - { - internal const string AzdCliNotInstalled = $"Azure Developer CLI could not be found. {Troubleshoot}"; - internal const string AzdNotLogIn = "Please run 'azd login' from a command prompt to authenticate before using this credential."; - internal const string WinAzdCliError = "'azd is not recognized"; - internal const string AzdCliTimeoutError = "Azure Developer CLI authentication timed out."; - internal const string AzdCliFailedError = "Azure Developer CLI authentication failed due to an unknown error."; - internal const string Troubleshoot = "Please visit https://aka.ms/azure-dev for installation instructions and then, once installed, authenticate to your Azure account using 'azd login'."; - internal const string InteractiveLoginRequired = "Azure Developer CLI could not login. Interactive login is required."; - private const string RefreshTokeExpired = "The provided authorization code or refresh token has expired due to inactivity. Send a new interactive authorization request for this user and resource."; - - private static readonly string DefaultWorkingDirWindows = Environment.GetFolderPath(Environment.SpecialFolder.System); - private const string DefaultWorkingDirNonWindows = "/bin/"; - private static readonly string DefaultWorkingDir = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? DefaultWorkingDirWindows : DefaultWorkingDirNonWindows; - - private static readonly Regex AzdNotFoundPattern = new Regex("azd:(.*)not found"); - - public override AccessToken GetToken(TokenRequestContext requestContext, CancellationToken cancellationToken = default) - { - return RequestCliAccessTokenAsync(requestContext, cancellationToken) - .GetAwaiter() - .GetResult(); - } - - public override async ValueTask GetTokenAsync(TokenRequestContext requestContext, CancellationToken cancellationToken = default) - { - return await RequestCliAccessTokenAsync(requestContext, cancellationToken).ConfigureAwait(false); - } - - private async ValueTask RequestCliAccessTokenAsync(TokenRequestContext context, CancellationToken cancellationToken) - { - try - { - ProcessStartInfo processStartInfo = GetAzdCliProcessStartInfo(context.Scopes); - string output = await RunProcessAsync(processStartInfo); - - return DeserializeOutput(output); - } - catch (OperationCanceledException) when (!cancellationToken.IsCancellationRequested) - { - throw new AuthenticationFailedException(AzdCliTimeoutError); - } - catch (InvalidOperationException exception) - { - bool isWinError = exception.Message.StartsWith(WinAzdCliError, StringComparison.CurrentCultureIgnoreCase); - bool isOtherOsError = AzdNotFoundPattern.IsMatch(exception.Message); - - if (isWinError || isOtherOsError) - { - throw new CredentialUnavailableException(AzdCliNotInstalled); - } - - bool isAADSTSError = exception.Message.Contains("AADSTS"); - bool isLoginError = exception.Message.IndexOf("azd login", StringComparison.OrdinalIgnoreCase) != -1; - - if (isLoginError && !isAADSTSError) - { - throw new CredentialUnavailableException(AzdNotLogIn); - } - - bool isRefreshTokenFailedError = exception.Message.IndexOf(AzdCliFailedError, StringComparison.OrdinalIgnoreCase) != -1 && - exception.Message.IndexOf(RefreshTokeExpired, StringComparison.OrdinalIgnoreCase) != -1 || - exception.Message.IndexOf("CLIInternalError", StringComparison.OrdinalIgnoreCase) != -1; - - if (isRefreshTokenFailedError) - { - throw new CredentialUnavailableException(InteractiveLoginRequired); - } - - throw new AuthenticationFailedException($"{AzdCliFailedError} {Troubleshoot} {exception.Message}"); - } - catch (Exception ex) - { - throw new CredentialUnavailableException($"{AzdCliFailedError} {Troubleshoot} {ex.Message}"); - } - } - - private async ValueTask RunProcessAsync(ProcessStartInfo processStartInfo, CancellationToken cancellationToken = default) - { - var process = Process.Start(processStartInfo); - if (process == null) - { - throw new CredentialUnavailableException(AzdCliFailedError); - } - - await process.WaitForExitAsync(cancellationToken); - - if (process.ExitCode != 0) - { - var errorMessage = process.StandardError.ReadToEnd(); - throw new InvalidOperationException(errorMessage); - } - - return process.StandardOutput.ReadToEnd(); - } - - private ProcessStartInfo GetAzdCliProcessStartInfo(string[] scopes) - { - string scopeArgs = string.Join(" ", scopes.Select(scope => string.Format($"--scope {scope}"))); - string command = $"azd auth token --output json {scopeArgs}"; - - string fileName; - string argument; - - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) - { - fileName = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.System), "cmd.exe"); - argument = $"/c \"{command}\""; - } - else - { - fileName = "/bin/sh"; - argument = $"-c \"{command}\""; - } - - return new ProcessStartInfo - { - FileName = fileName, - Arguments = argument, - UseShellExecute = false, - RedirectStandardOutput = true, - RedirectStandardError = true, - ErrorDialog = false, - CreateNoWindow = true, - WorkingDirectory = DefaultWorkingDir, - }; - } - - private static AccessToken DeserializeOutput(string output) - { - using JsonDocument document = JsonDocument.Parse(output); - - JsonElement root = document.RootElement; - string accessToken = root.GetProperty("token").GetString(); - DateTimeOffset expiresOn = root.GetProperty("expiresOn").GetDateTimeOffset(); - - return new AccessToken(accessToken, expiresOn); - } - } -}