Skip to content

Commit

Permalink
Merge pull request #360 from Azure/auth_updates
Browse files Browse the repository at this point in the history
Auth updates
  • Loading branch information
hattan authored Jan 10, 2025
2 parents a70d613 + f96c5b3 commit 4172997
Show file tree
Hide file tree
Showing 24 changed files with 153 additions and 101 deletions.
2 changes: 1 addition & 1 deletion Modules/BenchPress.Azure/BenchPress.Azure.psd1
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
# Generated on: 12/1/2022
@{
RootModule = "BenchPress.Azure.psm1"
ModuleVersion = "0.2.2"
ModuleVersion = "0.2.3"
GUID = "3db0c6b2-7453-4972-a9de-402be1277ac9"
Author = "CSEDevOps"
CompanyName = "Microsoft"
Expand Down
88 changes: 49 additions & 39 deletions Modules/BenchPress.Azure/Private/Connect-Account.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -42,66 +42,76 @@ function Connect-Account {
param ( )
Begin { }
Process {
$useManagedIdentity = Get-EnvironmentVariable AZ_USE_MANAGED_IDENTITY -DontThrowIfMissing
$subscriptionId = Get-EnvironmentVariable AZ_SUBSCRIPTION_ID
$useManagedIdentity = Get-BooleanEnvironmentVariable AZ_USE_MANAGED_IDENTITY
$subscriptionId = Get-EnvironmentVariable AZ_SUBSCRIPTION_ID -DontThrowIfMissing
$applicationId = Get-EnvironmentVariable AZ_APPLICATION_ID -DontThrowIfMissing
$tenantId = Get-EnvironmentVariable AZ_TENANT_ID -DontThrowIfMissing

$currentConnection = Get-AzContext
$results = [AuthenticationResult]::new()

# Login Using Managed Identity
if ($useManagedIdentity) {
$connection = Connect-AzAccount -Identity
$subscriptionName = (Get-AzSubscription -SubscriptionId $subscriptionId).Name
Set-AzContext -Subscription $subscriptionName

if (IsCurrentAccountLoggedIn($currentConnection)) {
$results.Success = $true
$results.AuthenticationData = [AuthenticationData]::new($connection.Context.Subscription.Id)
$results.AuthenticationData = [AuthenticationData]::new(($currentConnection).Subscription.Id)
}
else {
# If the current context matches the subscription, tenant, and service principal, then we're already properly logged in.
$applicationId = Get-EnvironmentVariable AZ_APPLICATION_ID
$tenantId = Get-EnvironmentVariable AZ_TENANT_ID
# Login Using Managed Identity
if ($useManagedIdentity) {
$connection = Connect-AzAccount -Identity
if ($null -ne $subscriptionId) {
$subscriptionName = (Get-AzSubscription -SubscriptionId $subscriptionId).Name
Set-AzContext -Subscription $subscriptionName
}

if (IsCurrentAccountLoggedIn($currentConnection)) {
$results.Success = $true
$results.AuthenticationData = [AuthenticationData]::new(($currentConnection).Subscription.Id)
$results.AuthenticationData = [AuthenticationData]::new($connection.Context.Subscription.Id)
}
else {
# The current context is not correct
# Create the credentials and login to the correct account

$clientSecret = Get-EnvironmentVariable AZ_ENCRYPTED_PASSWORD | ConvertTo-SecureString
$clientSecret = New-Object System.Management.Automation.PSCredential -ArgumentList $applicationId, $clientSecret
# The current context is not correct
# Create the credentials and login to the correct account
$clientSecret = Get-EnvironmentVariable AZ_ENCRYPTED_PASSWORD | ConvertTo-SecureString
$clientSecret = New-Object System.Management.Automation.PSCredential -ArgumentList $applicationId, $clientSecret

try {
$connectionParams = @{
Credential = $clientSecret
TenantId = $tenantId
Subscription = $subscriptionId
if ($null -ne $currentConnection){
Write-Warning "Logging out of current Az.Powershell context and connecting to Subscription: $subscriptionId"
}
$connection = Connect-AzAccount -ServicePrincipal @connectionParams

$results.Success = $true
$results.AuthenticationData = [AuthenticationData]::new($connection.Context.Subscription.Id)
}
catch {
$thrownError = $_
$results.Success = $false
Write-Error $thrownError
}
}
try {
$connectionParams = @{
Credential = $clientSecret
TenantId = $tenantId
Subscription = $subscriptionId
}
$connection = Connect-AzAccount -ServicePrincipal @connectionParams

$results.Success = $true
$results.AuthenticationData = [AuthenticationData]::new($connection.Context.Subscription.Id)
}
catch {
$thrownError = $_
$results.Success = $false
Write-Error $thrownError
}
}
}

$results
}
End { }
}

function IsCurrentAccountLoggedIn($currentConnection) {
if ($null -ne $currentConnection `
-and ($currentConnection).Account.Type -eq 'ServicePrincipal' `
-and ($currentConnection).Account.Id -eq $applicationId `
-and ($currentConnection).Tenant.Id -eq $tenantId `
-and ($currentConnection).Subscription.Id -eq $subscriptionId) {
if ($null -eq $currentConnection) {
return $False
}

if ($null -eq $subscriptionId -or $null -eq $applicationId -or $null -eq $tenantId) {
return $True
}

if ($currentConnection.Account.Id -eq $applicationId `
-and $currentConnection.Tenant.Id -eq $tenantId `
-and $currentConnection.Subscription.Id -eq $subscriptionId) {
return $True
}

Expand Down
23 changes: 23 additions & 0 deletions Modules/BenchPress.Azure/Private/Get-EnvironmentVariable.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -70,3 +70,26 @@ function Get-RequiredEnvironmentVariable {
$value
}
}


function Get-BooleanEnvironmentVariable {
[OutputType([System.Boolean])]
param (
[Parameter(Mandatory = $true, Position = 0)]
[string]$VariableName
)
Begin {
$result = $False
}
Process {
$value = Get-EnvironmentVariable $VariableName -DontThrowIfMissing
try {
$result = [System.Convert]::ToBoolean($value)
} catch [FormatException] {
$result = $False
}
}
End {
$result
}
}
30 changes: 21 additions & 9 deletions Modules/BenchPress.Azure/Tests/Private/Connect-Account.Tests.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -29,15 +29,28 @@ Describe "Connect-Account" {
Mock Connect-AzAccount{}
}

It "Does not Invokes Connect-AzAccount when a context exists" {
# Arrange
Mock Get-EnvironmentVariable{ return "true" } -ParameterFilter { $VariableName -eq "AZ_USE_MANAGED_IDENTITY" -and $DontThrowIfMissing -eq $true }
Mock Set-AzContext {}

Mock Get-AzContext { @{Account = @{Type = "Mocked"; Id = $MockApplicationId};
Tenant = @{Id = $MockTenantId};
Subscription = @{Id = $MockSubscriptionId}}}

# Act
Connect-Account

# Assert Connect-AzAccount was not called and we are using the existing context
Assert-MockCalled Connect-AzAccount -Exactly 0
}

It "Invokes Connect-AzAccount with -Identity when AZ_USE_MANAGED_IDENTITY is set." {
# Arrange
Mock Get-EnvironmentVariable{ return "true" } -ParameterFilter { $VariableName -eq "AZ_USE_MANAGED_IDENTITY" -and $DontThrowIfMissing -eq $true }
Mock Set-AzContext {}

Mock Get-AzContext { @{Account = @{Type = "User"; Id = $MockApplicationId};
Tenant = @{Id = $MockTenantId};
Subscription = @{Id = $MockSubscriptionId}}} `
-Verifiable
Mock Get-AzContext { return $null} -Verifiable

# Act
Connect-Account
Expand All @@ -57,11 +70,10 @@ Describe "Connect-Account" {
}
}

It "Invokes Connect-AzAccount with -ServicePrincipal when the account type is not ServicePrincipal." {
Mock Get-AzContext { @{Account = @{Type = "User"; Id = $MockApplicationId};
Tenant = @{Id = $MockTenantId};
Subscription = @{Id = $MockSubscriptionId}}} `
-Verifiable
It "Invokes Connect-AzAccount with -ServicePrincipal when the context is empty and environment variables exist" {
Mock Get-BooleanEnvironmentVariable{ return $False } -ParameterFilter { $VariableName -eq "AZ_USE_MANAGED_IDENTITY" }
Mock Get-AzContext { return $null } -Verifiable
Mock Set-AzContext {}

Connect-Account

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,15 @@ Describe "Get-ResourceByType" {

Mock $functionName {}

Get-ResourceByType @params
| Should -Invoke -CommandName $Expected -Times 1 -ParameterFilter {$filterString}
if ($filterString -eq "") {
Get-ResourceByType @params
| Should -Invoke -CommandName $Expected -Times 1
}
else{
Get-ResourceByType @params
| Should -Invoke -CommandName $Expected -Times 1 -ParameterFilter {$filterString}
}

}
}
}
Expand Down
6 changes: 3 additions & 3 deletions assets/demos/main.bicep
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ resource applicationInsights 'Microsoft.Insights/components@2020-02-02' = {
}
}

resource emailActionGroup 'Microsoft.Insights/actionGroups@2022-06-01' = {
resource emailActionGroup 'Microsoft.Insights/actionGroups@2023-01-01' = {
name: join( ['benchpress', 'email', 'action', 'group', suffix ], '-')
location: 'global'
properties: {
Expand All @@ -33,7 +33,7 @@ resource emailActionGroup 'Microsoft.Insights/actionGroups@2022-06-01' = {
}
}

resource hostingPlan 'Microsoft.Web/serverfarms@2022-03-01' = {
resource hostingPlan 'Microsoft.Web/serverfarms@2024-04-01' = {
name: join( ['benchpress', 'hosting', 'plan', suffix ], '-')
location: location
sku: {
Expand All @@ -45,7 +45,7 @@ resource hostingPlan 'Microsoft.Web/serverfarms@2022-03-01' = {
}
}

resource webApp 'Microsoft.Web/sites@2022-03-01' = {
resource webApp 'Microsoft.Web/sites@2024-04-01' = {
name: join( ['benchpress', 'web', suffix ], '-')
location: location
identity: {
Expand Down
4 changes: 2 additions & 2 deletions examples/AksCluster/aksCluster.bicep
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
param aksName string = 'aks${take(uniqueString(resourceGroup().id), 5)}'
param location string = resourceGroup().location

resource aksCluster 'Microsoft.ContainerService/managedClusters@2022-09-01' = {
resource aksCluster 'Microsoft.ContainerService/managedClusters@2024-09-01' = {
name: aksName
location: location
identity: {
Expand All @@ -24,7 +24,7 @@ resource aksCluster 'Microsoft.ContainerService/managedClusters@2022-09-01' = {

param agentPoolName string = 'ap${take(uniqueString(resourceGroup().id), 5)}'

resource agentPool 'Microsoft.ContainerService/managedClusters/agentPools@2022-09-01' = {
resource agentPool 'Microsoft.ContainerService/managedClusters/agentPools@2024-09-01' = {
name: agentPoolName
parent: aksCluster
properties: {
Expand Down
12 changes: 6 additions & 6 deletions examples/ApiManagement/ApiManagement.bicep
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
param serviceName string = 'apim${take(uniqueString(resourceGroup().id), 5)}'
param location string = resourceGroup().location

resource apiManagementService 'Microsoft.ApiManagement/service@2022-08-01' = {
resource apiManagementService 'Microsoft.ApiManagement/service@2024-05-01' = {
name: serviceName
location: location
sku: {
Expand All @@ -16,7 +16,7 @@ resource apiManagementService 'Microsoft.ApiManagement/service@2022-08-01' = {

param apiName string = 'api${take(uniqueString(resourceGroup().id), 5)}'

resource api 'Microsoft.ApiManagement/service/apis@2022-08-01' = {
resource api 'Microsoft.ApiManagement/service/apis@2024-05-01' = {
name: apiName
parent: apiManagementService
properties: {
Expand All @@ -28,7 +28,7 @@ resource api 'Microsoft.ApiManagement/service/apis@2022-08-01' = {

param workspaceName string = 'logworkspace${take(uniqueString(resourceGroup().id), 5)}'

resource workspace 'Microsoft.OperationalInsights/workspaces@2022-10-01' = {
resource workspace 'Microsoft.OperationalInsights/workspaces@2023-09-01' = {
name: workspaceName
location: location
properties: {
Expand All @@ -52,7 +52,7 @@ resource applicationInsights 'Microsoft.Insights/components@2020-02-02' = {

param loggerName string = 'log${take(uniqueString(resourceGroup().id), 5)}'

resource logger 'Microsoft.ApiManagement/service/loggers@2022-08-01' = {
resource logger 'Microsoft.ApiManagement/service/loggers@2024-05-01' = {
name: loggerName
parent: apiManagementService
properties: {
Expand All @@ -65,7 +65,7 @@ resource logger 'Microsoft.ApiManagement/service/loggers@2022-08-01' = {

param diagnosticName string = 'applicationinsights'

resource diagnostic 'Microsoft.ApiManagement/service/diagnostics@2022-08-01' = {
resource diagnostic 'Microsoft.ApiManagement/service/diagnostics@2024-05-01' = {
name: diagnosticName
parent: apiManagementService
properties: {
Expand All @@ -75,7 +75,7 @@ resource diagnostic 'Microsoft.ApiManagement/service/diagnostics@2022-08-01' = {

param policyName string = 'policy'

resource apiPolicy 'Microsoft.ApiManagement/service/apis/policies@2022-08-01' = {
resource apiPolicy 'Microsoft.ApiManagement/service/apis/policies@2024-05-01' = {
name: policyName
parent: api
properties: {
Expand Down
4 changes: 2 additions & 2 deletions examples/AppInsights/appInsights.bicep
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ param appInsightsName string = 'appinsights${take(uniqueString(resourceGroup().i
param workspaceName string = 'logworkspace${take(uniqueString(resourceGroup().id), 5)}'
param location string = resourceGroup().location

resource workspace 'Microsoft.OperationalInsights/workspaces@2022-10-01' = {
resource workspace 'Microsoft.OperationalInsights/workspaces@2023-09-01' = {
name: workspaceName
location: location
properties: {
Expand All @@ -21,7 +21,7 @@ resource applicationInsights 'Microsoft.Insights/components@2020-02-02' = {
WorkspaceResourceId: workspace.id
}
}

#disable-next-line use-recent-api-versions //Disabling since this is the latest preview version available.
resource appInsightsDiagnostics 'Microsoft.Insights/diagnosticSettings@2021-05-01-preview' = {
scope: applicationInsights
name: 'default'
Expand Down
2 changes: 1 addition & 1 deletion examples/AppServicePlan/appServicePlan.bicep
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
param location string = resourceGroup().location
param name string = 'asp${take(uniqueString(resourceGroup().id), 5)}'

resource appServicePlan 'Microsoft.Web/serverfarms@2022-03-01' = {
resource appServicePlan 'Microsoft.Web/serverfarms@2024-04-01' = {
name: name
location: location
sku: {
Expand Down
6 changes: 3 additions & 3 deletions examples/ContainerApp/containerApp.bicep
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ param location string = resourceGroup().location
param targetPort int = 80
param containerImage string = 'mcr.microsoft.com/azuredocs/containerapps-helloworld:latest'

resource logAnalytics 'Microsoft.OperationalInsights/workspaces@2022-10-01' = {
resource logAnalytics 'Microsoft.OperationalInsights/workspaces@2023-09-01' = {
name: 'loganalytics${containerAppName}'
location: location
properties: {
Expand All @@ -13,7 +13,7 @@ resource logAnalytics 'Microsoft.OperationalInsights/workspaces@2022-10-01' = {
}
}

resource containerAppEnv 'Microsoft.App/managedEnvironments@2022-10-01' = {
resource containerAppEnv 'Microsoft.App/managedEnvironments@2024-03-01' = {
name: 'env${containerAppName}'
location: location
sku: {
Expand All @@ -30,7 +30,7 @@ resource containerAppEnv 'Microsoft.App/managedEnvironments@2022-10-01' = {
}
}

resource containerApp 'Microsoft.App/containerApps@2022-10-01' = {
resource containerApp 'Microsoft.App/containerApps@2024-03-01' = {
name: containerAppName
location: location
properties: {
Expand Down
Loading

0 comments on commit 4172997

Please sign in to comment.