diff --git a/Directory.Packages.props b/Directory.Packages.props
index 4573d60..802924a 100644
--- a/Directory.Packages.props
+++ b/Directory.Packages.props
@@ -12,7 +12,7 @@
-
+
diff --git a/README.md b/README.md
index 272fb32..3caeab2 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 up -t dotnet-architecture/eShopOnWeb
+azd init -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 1c4c212..64477a7 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 62e34a6..c65f2b8 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 96c9cf7..aa989eb 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 406c7bf..0000000
--- 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);
- }
- }
-}