Opprett Azure-ressurser ved hjelp av Azure PowerShell- eller ARM-maler
Denne artikkelen beskriver hvordan du bruker Microsoft Azure PowerShell- eller Azure Resource Manager-maler (ARM) til å opprette ressurser som kreves for elektronisk fakturering.
Hvis du vil aktivere e-fakturering i Dynamics 365 Finance, må du opprette og konfigurere flere Azure-ressurser, for eksempel et Azure-nøkkelhvelv, en Azure-lagringskonto og en Azure-lagringskontocontainer. Denne prosessen kan være tidkrevende og utsatt for feil hvis den gjøres manuelt. For å forenkle og automatisere denne prosessen kan du bruke et PowerShell-skript eller en ARM-mal som oppretter og konfigurerer alle de nødvendige Azure-ressursene for deg.
Bruk Azure PowerShell
Forutsetninger
Før du kjører PowerShell-skriptet må følgende forutsetninger være oppfylt:
- Du har et Azure-abonnement som har tilstrekkelige tillatelser til å opprette og administrere ressurser.
- Du har installert Azure PowerShell-modulen. (En støttet versjon av PowerShell versjon 7 eller senere anbefales for bruk med Azure PowerShell-modulen.)
- Du har PowerShell-skriptfilen.
PowerShell-skript
param (
[Parameter(Mandatory=$true)]
[string]$subscriptionId,
[Parameter(Mandatory=$true)]
[string]$resourceGroup,
[Parameter(Mandatory=$true)]
[string]$location,
[Parameter(Mandatory=$true)]
[string]$storageAccountName,
[Parameter(Mandatory=$true)]
[string]$keyVaultName,
[Parameter(Mandatory=$true)]
[string]$containerName,
[Parameter(Mandatory=$true)]
[string]$storageAccountKeyVaultSecretName
)
if (!(Get-Module -ListAvailable -Name Az)) {
throw "Az PowerShell module is required to run this script. Please install from https://learn.microsoft.com/en-us/powershell/azure/install-azure-powershell."
}
function Write-ErrorMessage {
param (
[string]$errorMessage
)
Write-Host "Error: $errorMessage" -ForegroundColor Red
exit 1
}
function Write-VerboseMessage {
param (
[string]$message
)
Write-Host "Verbose: $message" -ForegroundColor DarkYellow
}
function Confirm-ResourceExists {
param (
[string]$resourceType,
[string]$resourceName,
[string]$resourceGroup = ''
)
try {
switch ($resourceType) {
'ResourceGroup' {
Get-AzResourceGroup -Name $resourceName -ErrorAction Stop | Out-Null
}
'StorageAccount' {
Get-AzStorageAccount -ResourceGroupName $resourceGroup -Name $resourceName -ErrorAction Stop | Out-Null
}
'StorageContainer' {
Get-AzStorageContainer -Name $resourceName -ErrorAction Stop | Out-Null
}
'KeyVault' {
$kv = Get-AzKeyVault -ResourceGroupName $resourceGroup -VaultName $resourceName
if ($null -eq $kv)
{
return $false
}
}
}
return $true
} catch {
return $false
}
}
# Connect to Azure account and set the subscription context
try {
Write-VerboseMessage "Connecting to Azure account..."
Connect-AzAccount -Subscription $subscriptionId -ErrorAction Stop -Verbose
} catch {
Write-Host $_.Exception.Message
Write-ErrorMessage "Failed to connect to the Azure account or set subscription context."
}
try {
Write-VerboseMessage "Checking if the e-invoice service principal exists."
$objectId = (Get-AzADServicePrincipal -ApplicationId "ecd93392-c922-4f48-9ddf-10741e4a9b65" -ErrorAction SilentlyContinue -Verbose).Id
if ($null -eq $objectId)
{
Write-VerboseMessage "The e-invoice service principal does not exist. Trying to create now."
New-AzADServicePrincipal -AppId "ecd93392-c922-4f48-9ddf-10741e4a9b65" -ErrorAction Stop -Verbose
}
else {
Write-VerboseMessage "The e-invoice service principal already exists. No action required."
}
}
catch {
Write-Host $_.Exception.Message
Write-ErrorMessage "Adding e-Invoicing Service to your tenant as a service principal failed."
}
# Check if the resource group exists
if (-not (Confirm-ResourceExists -resourceType 'ResourceGroup' -resourceName $resourceGroup)) {
try {
Write-VerboseMessage "Creating Azure resource group..."
New-AzResourceGroup -Name $resourceGroup -Location $location -ErrorAction Stop -Verbose
$msg = "Resource group {0} created successfully in at location: {1}." -f $resourceGroup, $location
Write-VerboseMessage $msg
} catch {
Write-Host $_.Exception.Message
Write-ErrorMessage "Failed to create Azure resource group."
}
} else {
Write-VerboseMessage "Resource group '$resourceGroup' already exists."
}
# Check if the Azure Key Vault exists
if (-not (Confirm-ResourceExists -resourceType 'KeyVault' -resourceName $keyVaultName -resourceGroup $resourceGroup)) {
try {
Write-VerboseMessage "Creating Azure Key Vault..."
New-AzKeyVault -Name $keyVaultName -ResourceGroupName $resourceGroup -Location $location -ErrorAction Stop -Verbose
$msg = "Key vault {0} created successfully in resource group: {1} at location: {2}." -f $keyVaultName, $resourceGroup, $location
Write-VerboseMessage $msg
} catch {
Write-Host $_.Exception.Message
Write-ErrorMessage "Failed to create Azure Key Vault."
}
} else {
Write-VerboseMessage "Azure Key Vault '$keyVaultName' already exists."
}
# Check if the storage account exists
if (-not (Confirm-ResourceExists -resourceType 'StorageAccount' -resourceName $storageAccountName -resourceGroup $resourceGroup)) {
try {
Write-VerboseMessage "Creating Azure Storage Account..."
New-AzStorageAccount -ResourceGroupName $resourceGroup `
-Name $storageAccountName `
-Location $location `
-SkuName Standard_LRS `
-Kind StorageV2 `
-AllowBlobPublicAccess $true -ErrorAction Stop -Verbose
$msg = "Storage account {0} created successfully in resource group: {1} at location: {2}." -f $storageAccountName, $resourceGroup, $location
Write-VerboseMessage $msg
} catch {
Write-Host $_.Exception.Message
Write-ErrorMessage "Failed to create Azure Storage Account."
}
} else {
Write-VerboseMessage "Storage account '$storageAccountName' already exists."
}
# Check if the storage container exists
$ctx = (Get-AzStorageAccount -ResourceGroupName $resourceGroup -Name $storageAccountName).Context
Set-AzCurrentStorageAccount -Context $ctx
if (-not (Confirm-ResourceExists -resourceType 'StorageContainer' -resourceName $containerName -resourceGroup $resourceGroup)) {
try {
Write-VerboseMessage "Creating storage container..."
New-AzStorageContainer -Name $containerName -Context $ctx -ErrorAction Stop -Verbose
$msg = "Storage container {0} created successfully in storage account: {1}." -f $containerName, $storageAccountName
Write-VerboseMessage $msg
} catch {
Write-Host $_.Exception.Message
Write-ErrorMessage "Failed to create storage container."
}
} else {
Write-VerboseMessage "Storage container '$containerName' already exists."
}
# Set the start and end time for the SAS token
$StartTime = Get-Date
$EndTime = $StartTime.AddYears(3)
# Generate SAS token for the container
try {
Write-VerboseMessage "Generating SAS token for the container..."
$sasToken = New-AzStorageContainerSASToken -Name $containerName -Permission racwdli -Protocol HttpsOnly -StartTime $StartTime -ExpiryTime $EndTime -Context $ctx -ErrorAction Stop -Verbose
$msg = "SAS token for container {0} generated successfully with full permissions. The token would expire on {1}." -f $containerName, $EndTime
Write-VerboseMessage $msg
} catch {
Write-Host $_.Exception.Message
Write-ErrorMessage "Failed to generate SAS token for the container."
}
# Construct the SAS URL
$sasURL = "https://$($storageAccountName).blob.core.windows.net/$($containerName)?$($sastoken)"
# Set access policy for the application to get and list secrets
try {
Write-VerboseMessage "Setting access policy for Azure Key Vault..."
Set-AzKeyVaultAccessPolicy -VaultName $keyVaultName -ObjectId $objectId -PermissionsToSecrets get,list -ErrorAction Stop -Verbose
$msg = "Get and list access policies set successfully on key vault {0} for the e-invoicing application {1}." -f $keyVaultName, $objectId
Write-VerboseMessage $msg
} catch {
Write-Host $_.Exception.Message
Write-ErrorMessage "Failed to set access policy for Azure Key Vault."
}
# Convert SAS URL to secure string
$secretvalue = ConvertTo-SecureString $sasURL -AsPlainText -Force
# Create a new secret in Azure Key Vault
try {
Write-VerboseMessage "Creating secret in Azure Key Vault..."
Set-AzKeyVaultSecret -VaultName $keyVaultName -Name $storageAccountKeyVaultSecretName -SecretValue $secretvalue -Expires $EndTime -ContentType "" -ErrorAction Stop -Verbose
$msg = "Secret {0} created successfully in {1} and will expire on {2}." -f $storageAccountKeyVaultSecretName, $keyVaultName, $EndTime
Write-VerboseMessage $msg
} catch {
Write-Host $_.Exception.Message
Write-ErrorMessage "Failed to create secret in Azure Key Vault."
}
# Display the secret
Write-Host "Secret created successfully."
Kjør PowerShell-skriptet
Følg fremgangsmåten nedenfor for å kjøre PowerShell-skriptet.
Åpne PowerShell, og gå til mappen der PowerShell-skriptfilen og konfigurasjonsfilen er plassert.
Hvis du vil kjøre PowerShell-skriptet ved hjelp av dine egne parametere, kjører du kommandoen nedenfor.
.\Create-AzureResourcesForEInvoice.ps1 -subscriptionId <azure_subscription_id> -resourceGroup <resource_group_name> -location <resource_group_location> -storageAccountName <storage_account_name> -containerName <container_name> -storageAccountKeyVaultSecretName <SAS_token_keyvault_secret_name>
PowerShell-skriptet utfører følgende handlinger.
- Skriptet ber deg om å logge deg på Azure-kontoen. Angi legitimasjonen din, og velg deretter Logg på.
- Skriptet bestemmer om sikkerhetskontohaveren for e-fakturatjenesten allerede finnes. Hvis den ikke finnes, oppretter skriptet den.
- Skriptet finner ut om følgende Azure-ressurser allerede finnes: en Azure-ressursgruppe, et Azure-nøkkelhvelv, en Azure-lagringskonto og en Azure-lagringskontocontainer. Hvis noen av dem ikke finnes, oppretter og konfigurerer skriptet dem.
- Skriptet genererer et SAS-token (signatur for delt tilgang) for lagringskontocontaineren og legger det til som en Key Vault-hemmelighet i nøkkelhvelvet.
- Skriptet angir tilgangspolicyen for nøkkelhvelvet for å gi tillatelsene hent og liste til e-fakturaappen.
- Som utdata genererer skriptet detaljene for Azure-ressursene som ble opprettet. Disse detaljene omfatter navn og nettadresser.
Obs!
Du kan kjøre det samme skriptet hvis du må fornye et SAS-token som er utløpt. I så fall oppretter ikke skriptet ressursene. I stedet genererer det bare et nytt SAS-token og oppdaterer det i nøkkelhvelvet.
Bruk en ARM-mal
ARM-mal
{
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"keyVaultName": {
"type": "string",
"metadata": {
"description": "Name of KeyVault to Store secrets/certificates/SaS Token"
}
},
"tenantID": {
"type": "string",
"metadata": {
"description": "Azure AD Tenant ID"
}
},
"keyVaultAccessObjectID": {
"type": "string",
"metadata": {
"description": "ID of user or App to grant access to KV"
},
"defaultValue": "ecd93392-c922-4f48-9ddf-10741e4a9b65"
},
"StorageAccountName": {
"type": "string",
"metadata": {
"description": "Name of Storage Account to Create"
}
},
"ContainerName": {
"type": "string",
"metadata": {
"description": "Name of container for einvoice upload"
}
},
"accountSasProperties": {
"type": "object",
"defaultValue": {
"signedServices": "bf",
"signedPermission": "rwacld",
"signedExpiry": "2024-12-01T00:00:00Z",
"signedResourceTypes": "o"
}
}
},
"variables": {},
"resources": [
{
"name": "[parameters('StorageAccountName')]",
"type": "Microsoft.Storage/storageAccounts",
"apiVersion": "2018-07-01",
"location": "[resourceGroup().location]",
"tags": {
"displayName": "[parameters('StorageAccountName')]"
},
"sku": {
"name": "Standard_LRS"
},
"kind": "StorageV2",
"properties": {
"allowBlobPublicAccess": true
},
"resources":[
{
"type": "blobServices/containers",
"apiVersion": "2018-03-01-preview",
"name": "[concat('default/', parameters('ContainerName'))]",
"dependsOn": [
"[parameters('StorageAccountName')]"
],
"properties": {
"publicAccess": "None"
}
}
]
},
{
"type": "Microsoft.KeyVault/vaults",
"apiVersion": "2018-02-14",
"name": "[parameters('keyVaultName')]",
"location": "[resourceGroup().location]",
"tags": {
"displayName": "[parameters('keyVaultName')]"
},
"properties": {
"enabledForDeployment": true,
"enabledForTemplateDeployment": true,
"enabledForDiskEncryption": true,
"tenantId": "[parameters('tenantID')]",
"accessPolicies": [
{
"tenantId": "[parameters('tenantID')]",
"objectId": "[parameters('keyVaultAccessObjectID')]",
"permissions": {
"keys": [
"get"
],
"secrets": [
"list",
"get"
]
}
}
],
"sku": {
"name": "standard",
"family": "A"
}
}
},
{
"apiVersion": "2018-02-14",
"type": "Microsoft.KeyVault/vaults/secrets",
"dependsOn": [
"[concat('Microsoft.KeyVault/vaults/', parameters('keyVaultName'))]"
],
"name": "[concat(parameters('keyVaultName'), '/', 'StorageSaSToken')]",
"properties": {
"value": "[concat('https://', parameters('StorageAccountName'), '.blob.core.windows.net/', parameters('ContainerName'), '?', listAccountSas(parameters('StorageAccountName'), '2018-07-01', parameters('accountSasProperties')).accountSasToken)]"
}
}
],
"outputs": {}
}
Distribuer ARM-malen
Følg fremgangsmåten nedenfor for å distribuere ARM-malen.
Logg deg på Azure-portalen, og søk etter Distribuer en egendefinert mal.
Velg Bygg din egen mal i redigeringsprogrammet.
Kopier ARM-malen fra den forrige delen av denne artikkelen, lim den inn i redigeringsprogrammet og velg deretter Lagre.
Oppgi de nødvendige parameterne.
Velg Se gjennom + Opprett.
Gå gjennom detaljene, og velg deretter Opprett.
Verifiser Azure-ressursene
For å verifisere om Azure-ressursene ble opprettet og riktig konfigurert, kan du følge denne fremgangsmåten.
- Logg på Azure-portalen, og gå til ressursgruppen som inneholder Azure-ressursene. Du skal se ressurser som har navnene du har angitt i parameterne for PowerShell-skriptet eller ARM-malen.
- Åpne Key Vault-ressursen, og bekreft at SAS-tokenet for Azure-lagringskontoen er opprettet og har den riktige verdien.