Created
February 26, 2021 17:34
-
-
Save fluffy-cakes/956386d4170679c270f7eb0c56bfe7a4 to your computer and use it in GitHub Desktop.
How to call the Azure API directly via PowerShell from within Terraform
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
resource "null_resource" "deploy_workspace_settings" { | |
provisioner "local-exec" { | |
command = <<EOT | |
Import-Module ${path.module}/tf_azure_api_call.psm1 | |
New-WorkspaceSetting ` | |
-ClientId "${var.ARM_CLIENT_ID}" ` | |
-ClientSecret "${var.ARM_CLIENT_SECRET}" ` | |
-SubscriptionId "${var.ARM_SUBSCRIPTION_ID}" ` | |
-TenantId "${var.ARM_TENANT_ID}" ` | |
-WorkspaceId "${var.workspace_id}" ` | |
-WorkspaceScope "${var.scope_id}" | |
EOT | |
interpreter = ["pwsh", "-Command"] | |
} | |
} | |
resource "null_resource" "destroy_workspace_settings" { | |
triggers = { | |
"ClientId" = var.ARM_CLIENT_ID | |
"ClientSecret" = var.ARM_CLIENT_SECRET | |
"SubscriptionId" = var.ARM_SUBSCRIPTION_ID | |
"TenantId" = var.ARM_TENANT_ID | |
} | |
provisioner "local-exec" { | |
when = destroy | |
command = <<EOT | |
Import-Module ${path.module}/tf_azure_api_call.psm1 | |
Remove-WorkspaceSetting ` | |
-ClientId "${self.triggers.ClientId}" ` | |
-ClientSecret "${self.triggers.ClientSecret}" ` | |
-SubscriptionId "${self.triggers.SubscriptionId}" ` | |
-TenantId "${self.triggers.TenantId}" | |
EOT | |
interpreter = ["pwsh", "-Command"] | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<# | |
.Synopsis | |
An example set of Terraform functions that allows you to deploy resources to Azure via API calls. | |
This was created to bypass deployments via Azure ARM templates and Terraform which routinely timed | |
out and failed, an issue that had been raised, still many months later with no fix in sight. | |
~ example ref: https://github.com/terraform-providers/terraform-provider-azurerm/issues/5475 | |
.Parameter ClientId | |
Service principal client ID authorised for the deployment scope | |
.Parameter ClientSecret | |
Service principal client secret | |
.Parameter SubscriptionId | |
The ID of the subscription to deploy to | |
.Parameter TenantId | |
The ID of the tenant to deploy to | |
.Parameter WorkspaceId | |
The Log Analytics workspace ID used in this example to enable the workspace settings in Security Center | |
.Parameter WorkspaceScope | |
The subscription scope to which this workspace setting applies to | |
.Example | |
resource "null_resource" "deploy_workspace_settings" { | |
provisioner "local-exec" { | |
command = <<EOT | |
Import-Module ${path.module}/workspace_settings.psm1 | |
New-WorkspaceSetting ` | |
-ClientId "${var.ARM_CLIENT_ID}" ` | |
-ClientSecret "${var.ARM_CLIENT_SECRET}" ` | |
-SubscriptionId "${var.ARM_SUBSCRIPTION_ID}" ` | |
-TenantId "${var.ARM_TENANT_ID}" ` | |
-WorkspaceId "${var.workspace_id}" ` | |
-WorkspaceScope "${var.scope_id}" | |
EOT | |
interpreter = ["pwsh", "-Command"] | |
} | |
} | |
resource "null_resource" "destroy_workspace_settings" { | |
triggers = { | |
"ClientId" = var.ARM_CLIENT_ID | |
"ClientSecret" = var.ARM_CLIENT_SECRET | |
"SubscriptionId" = var.ARM_SUBSCRIPTION_ID | |
"TenantId" = var.ARM_TENANT_ID | |
} | |
provisioner "local-exec" { | |
when = destroy | |
command = <<EOT | |
Import-Module ${path.module}/workspace_settings.psm1 | |
Remove-WorkspaceSetting ` | |
-ClientId "${self.triggers.ClientId}" ` | |
-ClientSecret "${self.triggers.ClientSecret}" ` | |
-SubscriptionId "${self.triggers.SubscriptionId}" ` | |
-TenantId "${self.triggers.TenantId}" | |
EOT | |
interpreter = ["pwsh", "-Command"] | |
} | |
} | |
#> | |
function Get-Authenticated { | |
[CmdletBinding()] | |
param ( | |
[ValidateNotNullOrEmpty()] | |
[string] $ClientId, | |
[ValidateNotNullOrEmpty()] | |
[string] $ClientSecret, | |
[ValidateNotNullOrEmpty()] | |
[string] $TenantId | |
) | |
$headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]" | |
$headers.Add("Content-Type", "application/x-www-form-urlencoded") | |
# Client secrets can contain special characters, so we encode it to be used without errors | |
$encode = [System.Web.HTTPUtility]::UrlEncode("$ClientSecret") | |
$body = "client_id=$ClientId&client_secret=$encode&grant_type=client_credentials&scope=https%3A%2F%2Fmanagement.azure.com%2F.default" | |
$url = "https://login.microsoftonline.com/" + $TenantId + "/oauth2/v2.0/token" | |
$authentication = Invoke-RestMethod $url -Method 'GET' -Headers $headers -Body $body | |
return $authentication.access_token | |
} | |
function New-WorkspaceSetting { | |
[CmdletBinding()] | |
param ( | |
[ValidateNotNullOrEmpty()] | |
[string] $ClientId, | |
[ValidateNotNullOrEmpty()] | |
[string] $ClientSecret, | |
[ValidateNotNullOrEmpty()] | |
[string] $SubscriptionId, | |
[ValidateNotNullOrEmpty()] | |
[string] $TenantId, | |
[ValidateNotNullOrEmpty()] | |
[string] $WorkspaceId, | |
[ValidateNotNullOrEmpty()] | |
[string] $WorkspaceScope | |
) | |
$workspaceName = "default" | |
$token = Get-Authenticated -ClientId "$ClientId" -ClientSecret "$ClientSecret" -TenantId "$TenantId" | |
$headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]" | |
$headers.Add("Authorization", "Bearer $token") | |
$headers.Add("Content-Type", "application/json") | |
$body = "{`n | |
`"properties`": {`n | |
`"workspaceId`": `"$WorkspaceId`",`n | |
`"scope`": `"$WorkspaceScope`"`n | |
}`n | |
}" | |
$url = "https://management.azure.com/subscriptions/" + $SubscriptionId + "/providers/Microsoft.Security/workspaceSettings/" + $workspaceName + "?api-version=2017-08-01-preview" | |
$response = Invoke-RestMethod $url -Method 'PUT' -Headers $headers -Body $body | |
$response | |
} | |
function Remove-WorkspaceSetting { | |
[CmdletBinding()] | |
param ( | |
[ValidateNotNullOrEmpty()] | |
[string] $ClientId, | |
[ValidateNotNullOrEmpty()] | |
[string] $ClientSecret, | |
[ValidateNotNullOrEmpty()] | |
[string] $SubscriptionId, | |
[ValidateNotNullOrEmpty()] | |
[string] $TenantId | |
) | |
$workspaceName = "default" | |
$token = Get-Authenticated -ClientId "$ClientId" -ClientSecret "$ClientSecret" -TenantId "$TenantId" | |
$headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]" | |
$headers.Add("Authorization", "Bearer $token") | |
$url = "https://management.azure.com/subscriptions/" + $SubscriptionId + "/providers/Microsoft.Security/workspaceSettings/" + $workspaceName + "?api-version=2017-08-01-preview" | |
$response = Invoke-RestMethod $url -Method 'DELETE' -Headers $headers -Body $body | |
$response | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment