|
[CmdletBinding()] |
|
param |
|
( |
|
[Parameter(Mandatory = $True)] |
|
[String] $ServicePrincipalUsername, |
|
|
|
[Parameter(Mandatory = $True)] |
|
[SecureString] $ServicePrincipalPassword, |
|
|
|
[Parameter(Mandatory = $True)] |
|
[String] $TenancyId, |
|
|
|
[Parameter(Mandatory = $True)] |
|
[String] $SubscriptionName, |
|
|
|
[String] $AppCode = 'gocd', # just a short code to identify this app |
|
|
|
[String] $UniqueCode = 'dsr', # a short unique code to ensure that resources are unique |
|
|
|
[String] $ContainerImage = 'gocd/gocd-server:v17.8.0', # the container image name and version to deploy |
|
|
|
[String] $ContainerPort = '8153', # The port to expose on the container |
|
|
|
[String] $VolumeName = 'gocd', # The name of the volume to mount |
|
|
|
[String] $MountPoint = '/godata/', # The mount point |
|
|
|
[Int] $CPU = 1, # The number of CPUs to assign to the instance |
|
|
|
[String] $MemoryInGB = '1.5' # The amount of memory to assign to the instance |
|
) |
|
|
|
$supportRGName = '{0}{1}rg' -f $UniqueCode, $AppCode |
|
$storageAccountName = '{0}{1}storage' -f $UniqueCode, $AppCode |
|
$storageShareName = '{0}{1}share' -f $UniqueCode, $AppCode |
|
$keyvaultName = '{0}{1}akv' -f $UniqueCode, $AppCode |
|
$keyvaultStorageSecretName = '{0}key' -f $storageAccountName |
|
$aciRGName = '{0}{1}acirg' -f $UniqueCode, $AppCode |
|
$aciName = '{0}{1}aci' -f $UniqueCode, $AppCode |
|
$location = 'eastus' |
|
|
|
# Login to Azure using Service Principal |
|
Write-Verbose -Message ('Connecting to Azure Subscription "{0}" using Service Principal account "{1}"' -f $SubscriptionName, $ServicePrincipalUsername) |
|
$servicePrincipalCredential = New-Object -TypeName 'System.Management.Automation.PSCredential' -ArgumentList ($ServicePrincipalUsername, $ServicePrincipalPassword) |
|
$null = Add-AzureRmAccount -TenantId $TenancyId -SubscriptionName $SubscriptionName -ServicePrincipal -Credential $servicePrincipalCredential |
|
|
|
# Create resource group for Key Vault and Storage Account |
|
if (-not (Get-AzureRmResourceGroup -Name $supportRGName -ErrorAction SilentlyContinue)) |
|
{ |
|
Write-Verbose -Message ('Creating Resource Group "{0}" for Storage Account and Key Vault' -f $supportRGName) |
|
$null = New-AzureRmResourceGroup -Name $supportRGName -Location $location |
|
} |
|
|
|
# Create Key Vault |
|
if (-not (Get-AzureRmKeyVault -ResourceGroupName $supportRGName -VaultName $keyVaultName -ErrorAction SilentlyContinue)) |
|
{ |
|
Write-Verbose -Message ('Creating Key Vault "{0}" in Resource Group "{1}"' -f $keyVaultName, $supportRGName) |
|
$null = New-AzureRmKeyVault -ResourceGroupName $supportRGName -VaultName $keyVaultName -Location $location -EnabledForTemplateDeployment -EnabledForDeployment |
|
} |
|
Write-Verbose -Message ('Setting Key Vault "{0}" access policy to enable Service Principal "{1}" to Get,List and Set secrets' -f $keyVaultName, $ServicePrincipalUsername) |
|
$null = Set-AzureRmKeyVaultAccessPolicy -ResourceGroupName $supportRGName -VaultName $keyVaultName -ServicePrincipalName $ServicePrincipalUsername -PermissionsToSecrets get, list, set |
|
Write-Verbose -Message ('Getting Key Vault "{0}" Id' -f $keyVaultName) |
|
$keyvaultNameId = (Get-AzureRmKeyVault -Name $keyVaultName).ResourceId |
|
|
|
# Create Storage Account |
|
if (-not (Get-AzureRmStorageAccount -ResourceGroupName $supportRGName -Name $storageAccountName -ErrorAction SilentlyContinue)) |
|
{ |
|
Write-Verbose -Message ('Creating Storage Account "{0}" in Resource Group "{1}"' -f $storageAccountName, $supportRGName) |
|
$null = New-AzureRmStorageAccount -ResourceGroupName $supportRGName -Name $storageAccountName -SkuName Standard_LRS -Location $location |
|
} |
|
Write-Verbose -Message ('Getting Storage Account "{0}" key' -f $storageAccountName) |
|
$storageAccountKey = Get-AzureRmStorageAccountKey -ResourceGroupName $supportRGName -Name $storageAccountName |
|
$storageConnectionString = 'DefaultEndpointsProtocol=https;AccountName={0};AccountKey={1};' -f $storageAccountName, $storageAccountKey[0].value |
|
$storageContext = New-AzureStorageContext -ConnectionString $storageConnectionString |
|
if (-not (Get-AzureStorageShare -Name $storageShareName -Context $storageContext -ErrorAction SilentlyContinue)) |
|
{ |
|
Write-Verbose -Message ('Creating Azure Storage Share "{0}" in Storage Account {1}' -f $storageShareName, $storageAccountName) |
|
$null = New-AzureStorageShare -Name $storageShareName -Context $storageContext |
|
} |
|
|
|
# Add the Storage Key to the Key Vault |
|
Write-Verbose -Message ('Adding Storage Account "{0}" key to Key Vault "{1}"' -f $storageAccountName, $keyvaultName) |
|
$null = Set-AzureKeyVaultSecret -VaultName $keyvaultName -Name $keyvaultStorageSecretName -SecretValue (ConvertTo-SecureString -String $storageAccountKey[0].value -AsPlainText -Force) |
|
|
|
# Create Azure Container Intstance |
|
if (-not (Get-AzureRmResourceGroup -Name $aciRGName -ErrorAction SilentlyContinue)) |
|
{ |
|
Write-Verbose -Message ('Creating Resource Group "{0}" for Container Group' -f $aciRGName) |
|
$null = New-AzureRmResourceGroup -Name $aciRGName -Location $location |
|
} |
|
|
|
# Generate the azure deployment parameters |
|
$azureDeployParametersPath = (Join-Path -Path $PSScriptRoot -ChildPath 'aci-azuredeploy.parameters.json') |
|
$azureDeployPath = (Join-Path -Path $PSScriptRoot -ChildPath 'aci-azuredeploy.json') |
|
|
|
$azureDeployParameters = ConvertFrom-Json -InputObject (Get-Content -Path $azureDeployParametersPath -Raw) |
|
$azureDeployParameters.parameters.containername.value = $aciName |
|
$azureDeployParameters.parameters.containerimage.value = $ContainerImage |
|
$azureDeployParameters.parameters.cpu.value = $CPU |
|
$azureDeployParameters.parameters.memoryingb.value = $MemoryInGB |
|
$azureDeployParameters.parameters.containerport.value = $ContainerPort |
|
$azureDeployParameters.parameters.sharename.value = $storageShareName |
|
$azureDeployParameters.parameters.storageaccountname.value = $storageAccountName |
|
$azureDeployParameters.parameters.storageaccountkey.reference.keyVault.id = $keyvaultNameId |
|
$azureDeployParameters.parameters.storageaccountkey.reference.secretName = $keyvaultStorageSecretName |
|
$azureDeployParameters.parameters.volumename.value = $VolumeName |
|
$azureDeployParameters.parameters.mountpoint.value = $MountPoint |
|
Set-Content -Path $azureDeployParametersPath -Value (ConvertTo-Json -InputObject $azureDeployParameters -Depth 6) -Force |
|
|
|
$deploymentName = ((Get-ChildItem -Path $azureDeployPath).BaseName + '-' + ((Get-Date).ToUniversalTime()).ToString('MMdd-HHmm')) |
|
Write-Verbose -Message ('Deploying Container Group "{0}" to Resource Group "{1}"' -f $aciName, $aciRGName) |
|
$null = New-AzureRmResourceGroupDeployment -Name $deploymentName ` |
|
-ResourceGroupName $aciRGName ` |
|
-TemplateFile $azureDeployPath ` |
|
-TemplateParameterFile $azureDeployParametersPath ` |
|
-Force ` |
|
-ErrorVariable errorMessages |
|
|
|
# Get the container info and display it |
|
$subscriptionId = (Get-AzureRmSubscription -SubscriptionName $SubscriptionName).Id |
|
$resourceId = ('/subscriptions/{0}/resourceGroups/{1}/providers/Microsoft.ContainerInstance/containerGroups/{2}' -f $subscriptionId, $aciRGName, $aciName) |
|
$containerState = 'Unknown' |
|
while ($containerState -ne 'Running') |
|
{ |
|
Write-Verbose -Message 'Waiting for container to enter running state' |
|
$containerResource = Get-AzureRmResource -ResourceId $resourceId |
|
$containerState = $containerResource.Properties.state |
|
Start-Sleep -Seconds 2 |
|
} |
|
|
|
Write-Verbose -Message ('Container is running on http://{0}:{1}' -f $containerResource.Properties.ipAddress.ip, $containerResource.Properties.ipAddress.ports.port) |