Initial commit
This commit is contained in:
Родитель
4920515444
Коммит
60ab467b8b
37
README.md
37
README.md
|
@ -1,2 +1,39 @@
|
|||
# azure-devops-utils
|
||||
Utilities of Azure Devops to run/configure systems in Azure
|
||||
|
||||
## [Create Service Principal](bash/create-service-principal.sh)
|
||||
> [bash/create-service-principal.sh](bash/create-service-principal.sh)
|
||||
|
||||
Creates Azure Service Principal credentials.
|
||||
|
||||
Requires that the [Azure CLI](https://docs.microsoft.com/en-us/azure/xplat-cli-install) is pre-installed.
|
||||
|
||||
The script prompts for user input to be able to authenticate on Azure and to pick the desired subscription (this step can be skipped by providing the subscription id as a script argument).
|
||||
|
||||
For doing this in Windows without a bash shell, refer to instructions [here](https://docs.microsoft.com/en-us/azure/azure-resource-manager/resource-group-authenticate-service-principal-cli)
|
||||
|
||||
Another alternative using PowerShell can be found [here](https://docs.microsoft.com/en-us/azure/azure-resource-manager/resource-group-authenticate-service-principal)
|
||||
|
||||
## [Jenkins Azure Agent initialization script](powershell/Jenkins-Windows-Init-Script.ps1)
|
||||
> [powershell/Jenkins-Windows-Init-Script.ps1](powershell/Jenkins-Windows-Init-Script.ps1)
|
||||
|
||||
Sample script on how to setup your Windows Azure Jenkins Agent to communicate through JNLP with the Jenkins master.
|
||||
Before deploying using this initialization script remember to update this line with your credentials (you can get api token by clicking on your username --> configure --> show api token):
|
||||
```powershell
|
||||
$credentials="username:apitoken"
|
||||
```
|
||||
More information about the Azure VM Agents plugin can be found [here](https://wiki.jenkins-ci.org/display/JENKINS/Azure+VM+Agents+Plugin).
|
||||
|
||||
## [Azure Classic VM Image migration](powershell/Migrate-Image-From-Classic.ps1)
|
||||
> [powershell/Migrate-Image-From-Classic.ps1](powershell/Migrate-Image-From-Classic.ps1)
|
||||
|
||||
Migrates an image from the classic image model to the new Azure Resource Manager model.
|
||||
|
||||
| Argument | Description |
|
||||
|----------------------|---------------------------------------------------------------------------------------------------|
|
||||
| ImageName | Original image name |
|
||||
| TargetStorageAccount | Target account to copy to |
|
||||
| TargetResourceGroup | Resource group of the target storage account |
|
||||
| TargetContainer | Target container to put the VHD |
|
||||
| TargetVirtualPath | Virtual path to put the blob in. If not specified, defaults to the virtual path of the source URI |
|
||||
| TargetBlobName | Blob name to copy to. If not specified, defaults to the blob name of the source URI |
|
||||
|
|
|
@ -0,0 +1,139 @@
|
|||
#!/bin/bash
|
||||
|
||||
#echo "Usage:
|
||||
# 1 bash create-service-principal.sh
|
||||
# 2 bash create-service-principal.sh <Subscription ID>
|
||||
# You need Azure CLI: https://docs.microsoft.com/en-us/azure/xplat-cli-install
|
||||
|
||||
SUBSCRIPTION_ID=$1
|
||||
|
||||
#echo ""
|
||||
#echo " Background article: https://azure.microsoft.com/en-us/documentation/articles/resource-group-authenticate-service-principal"
|
||||
echo ""
|
||||
|
||||
my_app_name_uuid=$(python -c 'import uuid; print str(uuid.uuid4())[:8]')
|
||||
MY_APP_NAME="app${my_app_name_uuid}"
|
||||
|
||||
MY_APP_KEY=$(python -c 'import uuid; print uuid.uuid4().hex')
|
||||
|
||||
my_app_id_URI="${MY_APP_NAME}_id"
|
||||
|
||||
#check if the user has subscriptions. If not she's probably not logged in
|
||||
subscriptions_list=$(azure account list --json)
|
||||
subscriptions_list_count=$(echo $subscriptions_list | jq '. | length' 2>/dev/null)
|
||||
if [ $? -ne 0 ] || [ "$subscriptions_list_count" -eq "0" ]
|
||||
then
|
||||
azure login
|
||||
else
|
||||
echo " You are already logged in with an Azure account so we won't ask for credentials again."
|
||||
echo " If you want to select a subscription from a different account, before running this script you should either log out from all the Azure accounts or login manually with the new account."
|
||||
echo " azure login"
|
||||
echo ""
|
||||
fi
|
||||
|
||||
if [ -z "$SUBSCRIPTION_ID" ]
|
||||
then
|
||||
#prompt for subscription
|
||||
subscription_index=0
|
||||
subscriptions_list=$(azure account list --json)
|
||||
subscriptions_list_count=$(echo $subscriptions_list | jq '. | length')
|
||||
if [ $subscriptions_list_count -eq 0 ]
|
||||
then
|
||||
echo " You need to sign up an Azure Subscription here: https://azure.microsoft.com"
|
||||
exit 1
|
||||
elif [ $subscriptions_list_count -gt 1 ]
|
||||
then
|
||||
echo $subscriptions_list | jq -r 'keys[] as $i | " \($i+1). \(.[$i] | .name)"'
|
||||
|
||||
while read -r -t 0; do read -r; done #clear stdin
|
||||
subscription_idx=0
|
||||
until [ $subscription_idx -ge 1 -a $subscription_idx -le $subscriptions_list_count ]
|
||||
do
|
||||
read -p " Select a subscription by typing an index number from above list and press [Enter]: " subscription_idx
|
||||
if [ $subscription_idx -ne 0 -o $subscription_idx -eq 0 2>/dev/null ]
|
||||
then
|
||||
:
|
||||
else
|
||||
subscription_idx=0
|
||||
fi
|
||||
done
|
||||
subscription_index=$((subscription_idx-1))
|
||||
fi
|
||||
|
||||
SUBSCRIPTION_ID=`echo $subscriptions_list | jq -r '.['$subscription_index'] | .id'`
|
||||
echo ""
|
||||
fi
|
||||
|
||||
azure account set $SUBSCRIPTION_ID >/dev/null
|
||||
if [ $? -ne 0 ]
|
||||
then
|
||||
exit 1
|
||||
else
|
||||
echo " Using subscription ID $SUBSCRIPTION_ID"
|
||||
echo ""
|
||||
fi
|
||||
|
||||
MY_SUBSCRIPTION_ID=$(azure account show --json | jq -r '.[0].id')
|
||||
MY_TENANT_ID=$(azure account show --json | jq -r '.[0].tenantId')
|
||||
|
||||
azure config mode arm >/dev/null
|
||||
|
||||
my_error_check=$(azure ad sp show --search $MY_APP_NAME --json | grep "displayName" | grep -c \"$MY_APP_NAME\" )
|
||||
|
||||
if [ $my_error_check -gt 0 ];
|
||||
then
|
||||
echo " Found an app id matching the one we are trying to create; we will reuse that instead"
|
||||
else
|
||||
echo " Creating application in active directory:"
|
||||
echo " azure ad app create --name '$MY_APP_NAME' --home-page 'http://$MY_APP_NAME' --identifier-uris 'http://$my_app_id_URI/' --password $MY_APP_KEY"
|
||||
azure ad app create --name $MY_APP_NAME --home-page http://$MY_APP_NAME --identifier-uris http://$my_app_id_URI/ --password $MY_APP_KEY >/dev/null
|
||||
if [ $? -ne 0 ]
|
||||
then
|
||||
exit 1
|
||||
fi
|
||||
# Give time for operation to complete
|
||||
echo " Waiting for operation to complete...."
|
||||
sleep 20
|
||||
my_error_check=$(azure ad app show --search $MY_APP_NAME --json | grep "displayName" | grep -c \"$MY_APP_NAME\" )
|
||||
|
||||
if [ $my_error_check -gt 0 ];
|
||||
then
|
||||
my_app_object_id=$(azure ad app show --json --search $MY_APP_NAME | jq -r '.[0].objectId')
|
||||
MY_CLIENT_ID=$(azure ad app show --json --search $MY_APP_NAME | jq -r '.[0].appId')
|
||||
echo " "
|
||||
echo " Creating the service principal in AD"
|
||||
echo " azure ad sp create -a $MY_CLIENT_ID"
|
||||
azure ad sp create -a $MY_CLIENT_ID >/dev/null
|
||||
# Give time for operation to complete
|
||||
echo " Waiting for operation to complete...."
|
||||
sleep 20
|
||||
my_app_sp_object_id=$(azure ad sp show --search $MY_APP_NAME --json | jq -r '.[0].objectId')
|
||||
|
||||
echo " Assign rights to service principle"
|
||||
echo " azure role assignment create --objectId $my_app_sp_object_id -o Owner -c /subscriptions/$MY_SUBSCRIPTION_ID"
|
||||
azure role assignment create --objectId $my_app_sp_object_id -o Owner -c /subscriptions/$MY_SUBSCRIPTION_ID >/dev/null
|
||||
if [ $? -ne 0 ]
|
||||
then
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
echo " "
|
||||
echo " We've encounter an unexpected error; please hit Ctr-C and retry from the beginning"
|
||||
read my_error
|
||||
fi
|
||||
fi
|
||||
|
||||
MY_CLIENT_ID=$(azure ad sp show --search $MY_APP_NAME --json | jq -r '.[0].appId')
|
||||
|
||||
echo " "
|
||||
echo " Your access credentials ============================="
|
||||
echo " "
|
||||
echo " Subscription ID:" $MY_SUBSCRIPTION_ID
|
||||
echo " Client ID:" $MY_CLIENT_ID
|
||||
echo " Client Secret:" $MY_APP_KEY
|
||||
echo " OAuth 2.0 Token Endpoint:" "https://login.microsoftonline.com/${MY_TENANT_ID}/oauth2/token"
|
||||
echo " Tenant ID:" $MY_TENANT_ID
|
||||
echo " "
|
||||
echo " You can verify the service principal was created properly by running:"
|
||||
echo " azure login -u "$MY_CLIENT_ID" --service-principal --tenant $MY_TENANT_ID"
|
||||
echo " "
|
|
@ -0,0 +1,44 @@
|
|||
Set-ExecutionPolicy Unrestricted
|
||||
# Jenkins plugin will dynamically pass the server name and vm name.
|
||||
# If your jenkins server is configured for security , make sure to edit command for how slave executes
|
||||
# You may need to pass credentails or secret in the command , Refer to help by running "java -jar slave.jar --help"
|
||||
$jenkinsserverurl = $args[0]
|
||||
$vmname = $args[1]
|
||||
|
||||
|
||||
# Download the file to a specific location
|
||||
Write-Output "Downloading zulu SDK "
|
||||
$source = "http://azure.azulsystems.com/zulu/zulu1.7.0_51-7.3.0.4-win64.zip?jenkins"
|
||||
mkdir d:\azurecsdir
|
||||
$destination = "d:\azurecsdir\zuluJDK.zip"
|
||||
$wc = New-Object System.Net.WebClient
|
||||
$wc.DownloadFile($source, $destination)
|
||||
|
||||
Write-Output "Unzipping JDK "
|
||||
# Unzip the file to specified location
|
||||
$shell_app=new-object -com shell.application
|
||||
$zip_file = $shell_app.namespace($destination)
|
||||
mkdir d:\java
|
||||
$destination = $shell_app.namespace("d:\java")
|
||||
$destination.Copyhere($zip_file.items())
|
||||
Write-Output "Successfully downloaded and extracted JDK "
|
||||
|
||||
# Downloading jenkins slaves jar
|
||||
Write-Output "Downloading jenkins slave jar "
|
||||
$slaveSource = $jenkinsserverurl + "jnlpJars/slave.jar"
|
||||
$destSource = "d:\java\slave.jar"
|
||||
$wc = New-Object System.Net.WebClient
|
||||
$wc.DownloadFile($slaveSource, $destSource)
|
||||
|
||||
# execute slave
|
||||
Write-Output "Executing slave process "
|
||||
$java="d:\java\zulu1.7.0_51-7.3.0.4-win64\bin\java.exe"
|
||||
$jar="-jar"
|
||||
$jnlpUrl="-jnlpUrl"
|
||||
$serverURL=$jenkinsserverurl+"computer/" + $vmname + "/slave-agent.jnlp"
|
||||
$jnlpCredentialsFlag="-jnlpCredentials"
|
||||
# syntax for credentials username:apitoken or username:password
|
||||
# you can get api token by clicking on your username --> configure --> show api token
|
||||
$credentials="username:apitoken"
|
||||
& $java $jar $destSource $jnlpCredentialsFlag $credentials $jnlpUrl $serverURL
|
||||
|
|
@ -0,0 +1,156 @@
|
|||
<#
|
||||
.SYNOPSIS
|
||||
Migrate-Image-From-Classic.ps1
|
||||
.DESCRIPTION
|
||||
Migrates an image from the classic image store to RM
|
||||
.PARAMETER ImageName
|
||||
Original image name
|
||||
.PARAMETER TargetStorageAccount
|
||||
Target account to copy to
|
||||
.PARAMETER TargetResourceGroup
|
||||
Resource group of the target storage account
|
||||
.PARAMETER TargetContainer
|
||||
Target container to put the VHD
|
||||
.PARAMETER TargetVirtualPath
|
||||
Virtual path to put the blob in. If not specified, defaults to the virtual path of the source URI
|
||||
.PARAMETER TargetBlobName
|
||||
Blob name to copy to. If not specified, defaults to the blob name of the source URI
|
||||
#>
|
||||
|
||||
param (
|
||||
[Parameter(Mandatory=$true)]
|
||||
[string]$ImageName,
|
||||
[Parameter(Mandatory=$true)]
|
||||
[string]$TargetBlob,
|
||||
[Parameter(Mandatory=$true)]
|
||||
$TargetStorageAccount = $null
|
||||
[Parameter(Mandatory=$true)]
|
||||
[string]$TargetResourceGroup,
|
||||
[string]$TargetContainer = 'system',
|
||||
[Parameter(Mandatory=$true)]
|
||||
[string]$TargetVirtualPath = 'Microsoft.Compute/Images/custom'
|
||||
)
|
||||
|
||||
# Ensure logged in
|
||||
$ctx = Get-AzureRmContext
|
||||
if (!$ctx) {
|
||||
Exit
|
||||
}
|
||||
|
||||
# First find the VM image and determine what account it is in.
|
||||
Write-Output "Looking up image $ImageName"
|
||||
$image = Get-AzureVMImage $ImageName
|
||||
|
||||
if (!$image) {
|
||||
throw "Could not find $ImageName"
|
||||
}
|
||||
|
||||
# Determine the current storage account location.
|
||||
$vhdURI = $null
|
||||
if ($image.MediaLink) {
|
||||
# Contains the media link URL in the image info, rather than the os disk config. Parse this
|
||||
$vhdURI = $image.MediaLink
|
||||
}
|
||||
else {
|
||||
$vhdURI = $image.OSDiskConfiguration.MediaLink.AbsoluteUri
|
||||
}
|
||||
|
||||
# Parse out the source URI info
|
||||
$uriInfo = .\Parse-VHD-Uri.ps1 $vhdURI -ErrorAction Stop
|
||||
|
||||
$sourceStorageAccountName = $uriInfo.StorageAccount
|
||||
$sourceStorageContainer = $uriInfo.ContainerName
|
||||
$sourceStorageBlob = $uriInfo.Blob
|
||||
$sourceStorageVirtualPath = $uriInfo.VirtualPath
|
||||
|
||||
Write-Output "Copy details:"
|
||||
Write-Output " Storage Account $sourceStorageAccountName -> $TargetStorageAccount"
|
||||
Write-Output " Container $sourceStorageContainer -> $TargetContainer"
|
||||
if ($TargetVirtualPath -or $sourceStorageVirtualPath) {
|
||||
Write-Output " Virtual Path $sourceStorageVirtualPath -> $TargetVirtualPath"
|
||||
}
|
||||
Write-Output " Blob $sourceStorageBlob -> $TargetBlob"
|
||||
|
||||
# Validate that we got the storage account right
|
||||
$storageAccount = Get-AzureStorageAccount $sourceStorageAccountName
|
||||
|
||||
if (!$storageAccount) {
|
||||
throw "Could not find storage account $sourceStorageAccountName"
|
||||
}
|
||||
|
||||
# Generate the source and target contexts
|
||||
$sourceKey = Get-AzureStorageKey -StorageAccountName $sourceStorageAccountName
|
||||
$sourceContext = New-AzureStorageContext -StorageAccountName $sourceStorageAccountName -StorageAccountKey $sourceKey.Primary
|
||||
|
||||
# Grab the source blob
|
||||
$sourceBlob = $null
|
||||
if ($sourceStorageVirtualPath) {
|
||||
$sourceBlob = Get-AzureStorageBlob -Blob "$sourceStorageVirtualPath/$sourceStorageBlob" -Container $sourceStorageContainer -Context $sourceContext -ErrorAction SilentlyContinue
|
||||
}
|
||||
else {
|
||||
$sourceBlob = Get-AzureStorageBlob -Blob $sourceStorageBlob -Container $sourceStorageContainer -Context $sourceContext -ErrorAction SilentlyContinue
|
||||
}
|
||||
if (!$sourceBlob) {
|
||||
Write-Error "Could not locate source blob $sourceStorageBlob"
|
||||
Exit
|
||||
}
|
||||
|
||||
if ($TargetVirtualPath) {
|
||||
$targetUri = "https://$TargetStorageAccount.blob.core.windows.net/$TargetContainer/$TargetVirtualPath/$TargetBlob"
|
||||
}
|
||||
else {
|
||||
$targetUri = "https://$TargetStorageAccount.blob.core.windows.net/$TargetContainer/$TargetBlob"
|
||||
}
|
||||
|
||||
# Locate the storage account key for the target
|
||||
$targetStorageAccountKeys = Get-AzureRmStorageAccountKey $TargetStorageAccount -ResourceGroupName $TargetResourceGroup -ErrorAction SilentlyContinue
|
||||
if ($targetStorageAccountKeys) {
|
||||
if ($targetStorageAccountKeys[0]) {
|
||||
$targetStorageAccountKey = $targetStorageAccountKeys[0].Value
|
||||
}
|
||||
else {
|
||||
$targetStorageAccountKey = $targetStorageAccountKeys.Key1
|
||||
}
|
||||
}
|
||||
if (!$targetStorageAccountKey) {
|
||||
Write-Error "Could not find target storage account $TargetStorageAccount or locate the storage key, skipping"
|
||||
Exit
|
||||
}
|
||||
|
||||
# Create a storage context for the target
|
||||
$targetContext = New-AzureStorageContext -StorageAccountName $TargetStorageAccount -StorageAccountKey $targetStorageAccountKey
|
||||
|
||||
# Ensure that the container is created if not existing
|
||||
$existingContainer = Get-AzureStorageContainer -Context $targetContext -Name $TargetContainer -ErrorAction SilentlyContinue
|
||||
|
||||
if (!$existingContainer) {
|
||||
Write-Output "Target storage container $TargetContainer doesn't exist, creating"
|
||||
New-AzureStorageContainer -Context $targetContext -Name $TargetContainer
|
||||
}
|
||||
|
||||
$fullTargetBlobName = $TargetBlob
|
||||
if ($TargetVirtualPath) {
|
||||
$fullTargetBlobName = "$TargetVirtualPath/$TargetBlob"
|
||||
}
|
||||
|
||||
$blobCopy = Start-AzureStorageBlobCopy -CloudBlob $sourceBlob.ICloudBlob -Context $sourceContext -DestContext $targetContext -DestContainer $TargetContainer -DestBlob $fullTargetBlobName
|
||||
|
||||
Write-Output "Started $vhdURI -> $targetUri"
|
||||
|
||||
# Waiting till all copies done
|
||||
$allFinished = $false
|
||||
while (!$allFinished) {
|
||||
$allFinished = $true
|
||||
$blobCopyState = $blobCopy | Get-AzureStorageBlobCopyState
|
||||
if ($blobCopyState.Status -eq "Pending")
|
||||
{
|
||||
$allFinished = $false
|
||||
$percent = ($blobCopyState.BytesCopied * 100) / $blobCopyState.TotalBytes
|
||||
$percent = [math]::round($percent,2)
|
||||
$blobCopyName = $blobCopyState.CopyId
|
||||
Write-Progress -Id 0 -Activity "Copying from classic... " -PercentComplete $percent -CurrentOperation "Copying $blobCopyName"
|
||||
}
|
||||
Start-Sleep -s 30
|
||||
}
|
||||
|
||||
Write-Output "All operations complete"
|
Загрузка…
Ссылка в новой задаче