Is there Terraform script for creating migration activity in Azure? - terraform

I have created Azure data migration service and migration project using terraform, so is there any terraform scripts available for creating migration activity in Azure?

Currently its not possible with Terraform as only Database Migration Service and Project are available for now . You can use ARM template for the same .
If you want to use Terraform , then you can use local-exec to use PowerShell or CLI and execute the Az-powershell or Az CLI commands there .
Example of Local-exec :
resource "null_resource" "example" {
provisioner "local-exec" {
command = <<Settings
$ResourceGroupName = "${data.azurerm_resource_group.example.name}"
$FunctionAppName = "${var.function_app}"
$SubscriptionId = "${var.Subscription}"
Get-AzFunctionApp -ResourceGroupName $ResourceGroupName -Name $FunctionAppName -SubscriptionId $SubscriptionId
Settings
interpreter = ["PowerShell", "-Command"]
}
}

Related

PowerShell Task not running the script in Azure Pipelines?

I have a powershell task that is used to run a script which involves creating azure resources (Example: Resource group, Azure Key Vault, Function App...). When the pipeline is being run and it arrives to the powershell task in the deploy stage, it shows the following message:
The problem here, it says Finishing:Powershell but it didn't execute the script and did not create any azure resource.
Here is a sample of the powershell script:
$vaultName = "key vault name"
$blobstorageName = "blob storage name"
$Location = "Location Name"
$resourceGroupName = "Resource Group Name"
try {
#Creation of Resource Group
$resourceGroup = Get-AzResourceGroup -ResourceGroupName $resourceGroupName -ErrorAction SilentlyContinue
if($null -eq $resourceGroup)
{
New-AzResourceGroup -Name $resourceGroupName -Location $Location
}
else
{
Write-Host "The ResourceGroup with the name: $resourceGroupName already exists."
}
# Creation of Storage Account
$checkBlobStorage = (Get-AzStorageAccountNameAvailability -Name $blobstorageName) | Select-Object NameAvailable
if ($checkBlobStorage.NameAvailable)
{
New-AzStorageAccount -ResourceGroupName $resourceGroupName -AccountName $blobstorageName -Location $Location -SkuName Standard_LRS -Kind StorageV2 -AccessTier Hot
}
else
{
Write-Host "The name $blobStorageName is not available. Suggest a new globally unique name!"
}
catch
{
}
Does anyone have a clue what is wrong ? Am I missing something in the powershell script (Maybe I don't have direct access to the azure portal from azure devops) or maybe something is missing in
the Yaml file ?
Two major issues:
you seem to be using the Powershell Task, which is not designed for communication with Azure. You should use the Azure Powershell task for this kind of script, because it already has the right modules loaded and the authentication prepared.
your script is swallowing the error so it is hiding what went wrong. It's usually more useful not to catch exceptions; if your script is erroring then let it error, and let the pipeline show you in its log what has happened.

Azure Recovery Services Vault with Terraform local provisioner

Terraform doesn't provide options to change the Azure recovery Services Vault to use LocallyRedundant storage replication type. So I decided to use the PowerShell module to set this after the resource is provisioned. The command seems to be correct and works when it's manually invoked but doesn't when it's put in the provisioner. Any thoughts?
Terraform Version : 0.15
Azurerm Version : 2.40.0
resource "azurerm_recovery_services_vault" "RSV"{
name = "RSV"
location = "eastus"
resource_group_name = "RGTEST"
sku = "Standard"
provisioner "local-exec" {
command = "Get-AzRecoveryServicesVault -Name ${azurerm_recovery_services_vault.RSV.name} | Set-AzRecoveryServicesBackupProperty -BackupStorageRedundancy LocallyRedundant"
interpreter = ["powershell", "-Command"]
}
}
The PowerShell scripts rely on the resource "azurerm_recovery_services_vault" that is fully created. In this case, if you include the local-exec Provisioner in a null_resource, run terraform init and terraform apply again, it works.
Note that even though the resource will be fully created when the
provisioner is run, there is no guarantee that it will be in an
operable state
resource "null_resource" "script" {
provisioner "local-exec" {
command = "Get-AzRecoveryServicesVault -Name ${azurerm_recovery_services_vault.RSV.name} | Set-AzRecoveryServicesBackupProperty -BackupStorageRedundancy LocallyRedundant"
interpreter = ["powershell", "-Command"]
}
}

Create Azure Objects Using 'Publish Settings' File

So, I'm told if you import your Azure Subscription Publish Setting file into PowerShell...you can use the certificate in the Publish Setting file to create objects in your Azure Subscription.
However, I am getting the following exception trying to create a Resource Group:
New-AzureRmResourceGroup : Run Connect-AzureRmAccount to login.
+ CategoryInfo : CloseError: (:) [New-AzureRmResourceGroup], PSInvalidOperationException
+ FullyQualifiedErrorId : Microsoft.Azure.Commands.ResourceManager.Cmdlets.Implementation.NewAzureResourceGroupCmdlet
I Do The Following In My Script:
"Import" the Subscription
"Select" the Subscription
"Get" the Subscription (to view it)
...the subscription is both "Default & Current" (see attached image).
...and yet I still get that message.
SAMPLE CODE:
This code is edited so as not to "give away the farm"...
#Set Subscription
$Subscription_Id = "<not shown>"
Select-AzureSubscription -SubscriptionId $Subscription_Id
Get-AzureSubscription
# CHECK EXISTS: ResourceGroup
$RegionFullName = "South Central US"
$RegionShortName = "scus"
$EnvironmentShortName = "dev"
$ApplicationShortName = "<not shown>"
$ObjectTypeShortName = "rg"
$ResourceGroupFullName = "$($RegionShortName)-$($EnvironmentShortName)-$($ApplicationShortName)-$($ObjectTypeShortName)"
$ResourceGroup = Get-AzureRmResourceGroup -Name $ResourceGroupFullName -ErrorVariable NotPresent -ErrorAction SilentlyContinue
if ($ResourceGroup -eq $Null) {
#CREATE: ResourceGroup
$ResourceGroup = New-AzureRmResourceGroup -Name $ResourceGroupFullName -Location $RegionFullName -Confirm
}
I suppose you are using Import-PublishSettingsFile, but Azure Management Certificates and Publishing Setting files are only intended (for) and (are) limited to managing Azure Service Management (ASM) resources, which are being retired.
In your script, you mixed the ASM and AzureRm powershell modules together. Select-AzureSubscription and Get-AzureSubscription belong to ASM, Get-AzureRmResourceGroup and New-AzureRmResourceGroup belong to AzureRm.
So if you need to use AzureRm command, you need to run Connect-AzureRmAccount to login your account.

Running Powershell script in Terraform module

Am currently running some Terraform to create resources in Azure. We have a module we have written to create a resource group with a bunch of variables. The provider currently does not allow the creation of budgets and cost alerts but the Powershell modules do. I thought we could then add a Powershell script to carry out the settings. I seem to be hitting a snag where I cannot quite work out how to address the Powershell script. I have the following:
resource "null_resource" "PowerShellScriptRunAlways" {
triggers = {
always_run = "${timestamp()}"
}
provisioner "local-exec" {
command = ".'${path.module}//pwsh//costalert.ps1 -subscriptionID \"${var.azure_subscription_id}\" -tenantID \"${var.azure_tenant_id}\" -clientID \"${var.azure_client_id}\" -clientSecret \"${var.azure_client_secret}\" -budgetAmount \"${var.budgetAmount}\" -rgName \"${azurerm_resource_group.this.name}\" -emailAddresses \"${var.emailAddresses}\"'"
interpreter = ["pwsh", "-Command"]
}
}
using pwsh as this is running on a Linux Jenkins agent. This is part of a module where the ps1 file is under "root module directory/pwsh" but it seems to yield the following:
Error: Error running command '.'.terraform/modules/rg_test\pwsh\costalert.ps1 -subscriptionID "xxxxx" -tenantID "xxxxxxx" -clientID "xxxxxx" -clientSecret "xxxxx" -budgetAmount "1000" -rgName "rg-da_test-sbxeng-001" -emailAddresses "xxxxxx"'': exit status 1. Output: . : The module '.terraform/modules/rg_test' could not be loaded. For more information, run 'Import-Module .terraform/modules/rg_test
+ .'.terraform/modules/rg_test\pwsh\costalert.ps1 -subscriptionID
It seems to be switching the path but cannot seem to make it pick up the script and run it. Does anyone have any suggestions?
Isn't this a quoting issue?
I can successfully execute this pwsh null resource from a terraform module in an Azure DevOps linux agent. Note that only the script path is single quoted, while in your example you've got the whole command single quoted.
resource "null_resource" "create_sql_user" {
provisioner "local-exec" {
command = ".'${path.module}\\scripts\\create-sql-user.ps1' -password \"${random_password.sql_password.result}\" -username \"${var.sql_username}\" -sqlSaConnectionString \"${var.sql_server_connectionstring}\" -databaseName \"${azurerm_sql_database.db.name}\" "
interpreter = ["pwsh", "-Command"]
}
depends_on = [azurerm_sql_database.db]
}

How to create a Linux AppService Plan with New-AzAppServicePlan?

What is the equivalient of this code using New-AzAppServicePlan?
az appservice plan create --resource-group $ServerFarmResourceGroupName `
--name $AppServicePlanName `
--is-linux `
--location $ResourceGroupLocation `
--sku $AppServicePlanTier `
--number-of-workers $NumberOfWorkers
Is there really no way to create an App Service Plan using Az Powershell? Why can it only be done via Azure CLI or ARM?
I only found this answer, which basically uses ARM directly: How do I use Powershell to create an Azure Web App that runs on Linux?
There are some issues about this, suppose for now this is not supported for New-AzureRmAppServicePlan, however you could use New-AzureRmResource to create a linux plan. You could try the below command.
New-AzureRmResource -ResourceGroupName <>group name -Location "Central US" -ResourceType microsoft.web/serverfarms -ResourceName <plan name> -kind linux -Properties #{reserved="true"} -Sku #{name="S1";tier="Standard"; size="S1"; family="S"; capacity="1"} -Force
I originally used my script to create a ConsumptionPlan (Y1) through PowerShell and AzureCLI because I don't like when Azure put a generated name when creating a ConsumptionPlan.
Please find my solution to create a Linux App Service Plan (B1) using New-AzResource:
$fullObject = #{
location = "West Europe"
sku = #{
name = "B1"
tier = "Basic"
}
kind = "linux"
properties = #{
reserved = $true
}
}
$resourceGroupName = "rg-AppServicePlanLinux"
$serverFarmName = "aspl-test"
Write-Host "Step 1: CREATING APP SERVICE PLAN B1:Basic named [$serverFarmName]"
# Create a server farm which will host the function app in the resource group specified
New-AzResource -ResourceGroupName $resourceGroupName -ResourceType "Microsoft.Web/serverfarms" -Name $serverFarmName -IsFullObject -PropertyObject $fullObject -Force
So I used the ARM template to understand which information you need to provide on the -PropertyObject parameter
It also now seems possible to do an App Service Plan Linux with New-AzAppServicePlan command since Az PowerShell 4.3.0 (June 2020) with the parameter -Linux
Az.Websites
Added safeguard to delete created webapp if restore failed in 'Restore-AzDeletedWebApp'
Added 'SourceWebApp.Location' for 'New-AzWebApp' and 'New-AzWebAppSlot'
Fixed bug that prevented changing Container settings in 'Set-AzWebApp' and 'Set-AzWebAppSlot'
Fixed bug to get SiteConfig when -Name is not given for Get-AzWebApp
Added a support to create ASP for Linux Apps
Added exceptions for clone across resource groups
Release Note: https://learn.microsoft.com/en-us/powershell/azure/release-notes-azureps?view=azps-5.6.0&viewFallbackFrom=azps-4.3.0#azwebsites-7
New-AzAppServicePlan: https://learn.microsoft.com/en-us/powershell/module/az.websites/new-azappserviceplan?view=azps-5.6.0
If you get "The Service is unavailable" after deploying your new Function app (Consumption Plan) with Azure CLI, please make sure the following statement from Microsoft:
https://github.com/Azure/Azure-Functions/wiki/Creating-Function-Apps-in-an-existing-Resource-Group
I waste the whole day because I got another Function App (Premium Plan) in the same resource group I used to deploy the Consumption one.
This worked for me:
Adding -Linux as a parameter to my command
New-AzAppServicePlan -ResourceGroupName $RESOURCE_GROUP_NAME -Name $APP_SERVICE_PLAN_NAME -Location $RESOURCE_LOCATION -Linux -Tier $APP_SERVICE_PLAN_TIER -NumberofWorkers $APP_SERVICE_PLAN_WORKERS -WorkerSize $APP_SERVICE_PLAN_WORKER_SIZE
Example:
New-AzAppServicePlan -ResourceGroupName 'MyResourceGroup' -Name 'MyServicePlan' -Location 'northeurope' -Linux -Tier 'PremiumV2' -NumberofWorkers 2 -WorkerSize Medium
That's all.
I hope this helps

Resources