diff --git a/azure-pipelines.yml b/azure-pipelines.yml index b0dc6783..be971bfe 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -256,8 +256,6 @@ extends: GrafanaHost: https://dotnet-eng-grafana-staging.westus2.cloudapp.azure.com GrafanaKeyVault: dotnet-grafana-staging GrafanaVariableGroup: Dotnet-Grafana-Staging - ServiceConnectionClientId: 57f299da-15de-4117-b8f6-7c10451926f0 - ServiceConnectionId: 7829de7e-fb4e-4118-8370-475d6bc61905 ${{ else }}: DeploymentEnvironment: Production DotNetStatusAppName: dotneteng-status @@ -269,5 +267,3 @@ extends: GrafanaHost: https://dotnet-eng-grafana.westus2.cloudapp.azure.com GrafanaKeyVault: dotnet-grafana GrafanaVariableGroup: Dotnet-Grafana-Production - ServiceConnectionClientId: fc1eb341-aea4-4a11-8f80-d14b8775b2ba - ServiceConnectionId: 4a511f6f-b538-48e6-a389-207e430634d1 \ No newline at end of file diff --git a/eng/deploy.yaml b/eng/deploy.yaml index 0fe4c2fe..28c1d7b2 100644 --- a/eng/deploy.yaml +++ b/eng/deploy.yaml @@ -1,10 +1,6 @@ parameters: - name: ServiceConnectionName type: string -- name: ServiceConnectionClientId - type: string -- name: ServiceConnectionId - type: string - name: PublishProfile type: string - name: DotNetStatusAppName @@ -194,10 +190,6 @@ stages: value: ${{ parameters.GrafanaHost }} - name: GrafanaKeyVault value: ${{ parameters.GrafanaKeyVault }} - - name: GrafanaClientId - value: ${{ parameters.ServiceConnectionClientId }} - - name: GrafanaServiceConnectionId - value: ${{ parameters.ServiceConnectionId }} jobs: - job: notifyEndDeployment displayName: Notify deployment end @@ -220,7 +212,7 @@ stages: useGlobalJson: true - script: dotnet publish $(Build.SourcesDirectory)\src\Monitoring\Sdk\Microsoft.DotNet.Monitoring.Sdk.csproj -f net6.0 displayName: Build Monitoring SDK - - script: dotnet build $(Build.SourcesDirectory)\src\Monitoring\Monitoring.ArcadeServices\Monitoring.ArcadeServices.proj -t:PublishGrafana -p:GrafanaAccessToken=$(grafana-admin-api-key) -p:GrafanaHost=$(GrafanaHost) -p:GrafanaKeyVaultName=$(GrafanaKeyVault) -p:ClientId=$(GrafanaClientId) -p:ServiceConnectionId=$(GrafanaServiceConnectionId) -p:SystemAccessToken=$(System.AccessToken) -p:GrafanaEnvironment=$(DeploymentEnvironment) -p:ParametersFile=parameters.json -v:normal + - script: dotnet build $(Build.SourcesDirectory)\src\Monitoring\Monitoring.ArcadeServices\Monitoring.ArcadeServices.proj -t:PublishGrafana -p:GrafanaAccessToken=$(grafana-admin-api-key) -p:GrafanaHost=$(GrafanaHost) -p:GrafanaKeyVaultName=$(GrafanaKeyVault) -p:GrafanaEnvironment=$(DeploymentEnvironment) -p:ParametersFile=parameters.json -v:normal displayName: Publish Grafana Dashboards - stage: validateDeployment diff --git a/src/Monitoring/Sdk/MonitoringPublish.cs b/src/Monitoring/Sdk/MonitoringPublish.cs index 8fee6359..904945f7 100644 --- a/src/Monitoring/Sdk/MonitoringPublish.cs +++ b/src/Monitoring/Sdk/MonitoringPublish.cs @@ -32,14 +32,7 @@ public class MonitoringPublish : BuildTask [Required] public string KeyVaultName { get; set; } - // For azure pipeline service connection authentication - public string ClientId { get; set; } - public string ServiceConnectionId { get; set; } - public string SystemAccessToken { get; set; } - - // For client secret authentication - public string KeyVaultServicePrincipalId { get; set; } - public string KeyVaultServicePrincipalSecret { get; set; } + public string ManagedIdentityId { get; set; } [Required] public string Tag { get; set; } @@ -58,43 +51,7 @@ public sealed override bool Execute() private async Task ExecuteAsync() { - string msftTenantId = "72f988bf-86f1-41af-91ab-2d7cd011db47"; - TokenCredential tokenCredential; - - if (ClientId == null && ServiceConnectionId == null && SystemAccessToken == null && KeyVaultServicePrincipalId == null && KeyVaultServicePrincipalSecret == null) - { - tokenCredential = new DefaultAzureCredential( - new DefaultAzureCredentialOptions() - { - TenantId = msftTenantId - } - ); - } - else if (ClientId != null || ServiceConnectionId != null || SystemAccessToken != null) - { - if (ClientId == null || ServiceConnectionId == null || SystemAccessToken == null) - { - Log.LogError("Invalid login combination. Set ClientId, ServiceConnectionId and SystemAccessToken for CI, or none for local user authentication."); - return false; - } - else - { - tokenCredential = new AzurePipelinesCredential(msftTenantId, ClientId, ServiceConnectionId, SystemAccessToken); - } - } - else - { - if (KeyVaultServicePrincipalId == null || KeyVaultServicePrincipalSecret == null) - { - Log.LogError("Invalid login combination. Set KeyVaultServicePrincipalId and KeyVaultServicePrincipalSecret for Client Secret authentication."); - return false; - } - else - { - tokenCredential = new ClientSecretCredential(msftTenantId, KeyVaultServicePrincipalId, KeyVaultServicePrincipalSecret); - } - } - + ChainedTokenCredential tokenCredential = TokenCredentialHelper.GetChainedTokenCredential(ManagedIdentityId); using (var client = new GrafanaClient(Host, AccessToken)) using (var deploy = new DeployPublisher( grafanaClient: client, diff --git a/src/Monitoring/Sdk/TokenCredentialHelper.cs b/src/Monitoring/Sdk/TokenCredentialHelper.cs new file mode 100644 index 00000000..45a8592a --- /dev/null +++ b/src/Monitoring/Sdk/TokenCredentialHelper.cs @@ -0,0 +1,37 @@ +using System.Collections.Concurrent; +using Azure.Identity; + +namespace Microsoft.DotNet.Monitoring.Sdk; + +internal static class TokenCredentialHelper +{ + private static readonly ChainedTokenCredential _defaultCredential = new( + new DefaultAzureCredential( + new DefaultAzureCredentialOptions + { + ExcludeEnvironmentCredential = true + } + ) + ); + + private static ConcurrentDictionary CredentialCache { get; } = new ConcurrentDictionary(); + + public static ChainedTokenCredential GetChainedTokenCredential(string managedIdentityId) + { + if (managedIdentityId == null) + { + return _defaultCredential; + } + + if (CredentialCache.TryGetValue(managedIdentityId, out var chainedTokenCredential)) + { + return chainedTokenCredential; + } + + var credential = new ChainedTokenCredential(new ManagedIdentityCredential(managedIdentityId), new AzureCliCredential(), _defaultCredential); + + CredentialCache.TryAdd(managedIdentityId, credential); + + return credential; + } +} diff --git a/src/Monitoring/Sdk/sdk/Sdk.targets b/src/Monitoring/Sdk/sdk/Sdk.targets index badf8d79..01ed370a 100644 --- a/src/Monitoring/Sdk/sdk/Sdk.targets +++ b/src/Monitoring/Sdk/sdk/Sdk.targets @@ -50,11 +50,7 @@ Host="$(GrafanaHost)" AccessToken="$(GrafanaAccessToken)" KeyVaultName="$(GrafanaKeyVaultName)" - ClientId="$(ClientId)" - ServiceConnectionId="$(ServiceConnectionId)" - SystemAccessToken="$(SystemAccessToken)" - KeyVaultServicePrincipalId="$(GrafanaKeyVaultServicePrincipalId)" - KeyVaultServicePrincipalSecret="$(GrafanaKeyVaultServicePrincipalSecret)" + MangedIdentityId="$(MangedIdentityId)" Tag="$(GrafanaDashboardTag)" Environment="$(GrafanaEnvironment)" ParametersFile="$(ParametersFile)"