gopkg.in/mitchellh/packer.v1@v1.3.2/contrib/azure-setup.sh (about) 1 #!/usr/bin/env bash 2 set -e 3 4 meta_name= 5 azure_client_id= # Derived from application after creation 6 azure_client_name= # Application name 7 azure_client_secret= # Application password 8 azure_group_name= 9 azure_storage_name= 10 azure_subscription_id= # Derived from the account after login 11 azure_tenant_id= # Derived from the account after login 12 location= 13 azure_object_id= 14 azureversion= 15 create_sleep=10 16 17 showhelp() { 18 echo "azure-setup" 19 echo "" 20 echo " azure-setup helps you generate packer credentials for azure" 21 echo "" 22 echo " The script creates a resource group, storage account, application" 23 echo " (client), service principal, and permissions and displays a snippet" 24 echo " for use in your packer templates." 25 echo "" 26 echo " For simplicity we make a lot of assumptions and choose reasonable" 27 echo " defaults. If you want more control over what happens, please use" 28 echo " the azure-cli directly." 29 echo "" 30 echo " Note that you must already have an Azure account, username," 31 echo " password, and subscription. You can create those here:" 32 echo "" 33 echo " - https://account.windowsazure.com/" 34 echo "" 35 echo "REQUIREMENTS" 36 echo "" 37 echo " - azure-cli" 38 echo " - jq" 39 echo "" 40 echo " Use the requirements command (below) for more info." 41 echo "" 42 echo "USAGE" 43 echo "" 44 echo " ./azure-setup.sh requirements" 45 echo " ./azure-setup.sh setup" 46 echo "" 47 } 48 49 requirements() { 50 found=0 51 52 azureversion=$(az --version) 53 if [ $? -eq 0 ]; then 54 found=$((found + 1)) 55 echo "Found azure-cli version: $azureversion" 56 else 57 echo "azure-cli is missing. Please install azure-cli from" 58 echo "https://docs.microsoft.com/en-us/cli/azure/install-azure-cli?view=azure-cli-latest" 59 echo "Alternatively, you can use the Cloud Shell https://docs.microsoft.com/en-us/azure/cloud-shell/overview right from the Azure Portal or even VS Code." 60 fi 61 62 jqversion=$(jq --version) 63 if [ $? -eq 0 ]; then 64 found=$((found + 1)) 65 echo "Found jq version: $jqversion" 66 else 67 echo "jq is missing. Please install jq from" 68 echo "https://stedolan.github.io/jq/" 69 fi 70 71 if [ $found -lt 2 ]; then 72 exit 1 73 fi 74 } 75 76 askSubscription() { 77 az account list -otable 78 echo "" 79 echo "Please enter the Id of the account you wish to use. If you do not see" 80 echo "a valid account in the list press Ctrl+C to abort and create one." 81 echo "If you leave this blank we will use the Current account." 82 echo -n "> " 83 read azure_subscription_id 84 85 if [ "$azure_subscription_id" != "" ]; then 86 az account set --subscription $azure_subscription_id 87 else 88 azure_subscription_id=$(az account list --output json | jq -r '.[] | select(.isDefault==true) | .id') 89 fi 90 azure_tenant_id=$(az account list --output json | jq -r '.[] | select(.id=="'$azure_subscription_id'") | .tenantId') 91 echo "Using subscription_id: $azure_subscription_id" 92 echo "Using tenant_id: $azure_tenant_id" 93 } 94 95 askName() { 96 echo "" 97 echo "Choose a name for your resource group, storage account and client" 98 echo "client. This is arbitrary, but it must not already be in use by" 99 echo "any of those resources. ALPHANUMERIC ONLY. Ex: mypackerbuild" 100 echo -n "> " 101 read meta_name 102 } 103 104 askSecret() { 105 echo "" 106 echo "Enter a secret for your application. We recommend generating one with" 107 echo "openssl rand -base64 24. If you leave this blank we will attempt to" 108 echo "generate one for you using openssl. THIS WILL BE SHOWN IN PLAINTEXT." 109 echo "Ex: mypackersecret8734" 110 echo -n "> " 111 read azure_client_secret 112 if [ "$azure_client_secret" = "" ]; then 113 azure_client_secret=$(openssl rand -base64 24) 114 if [ $? -ne 0 ]; then 115 echo "Error generating secret" 116 exit 1 117 fi 118 echo "Generated client_secret: $azure_client_secret" 119 fi 120 } 121 122 askLocation() { 123 az account list-locations -otable 124 echo "" 125 echo "Choose which region your resource group and storage account will be created. example: westus" 126 echo -n "> " 127 read location 128 } 129 130 createResourceGroup() { 131 echo "==> Creating resource group" 132 az group create -n $meta_name -l $location 133 if [ $? -eq 0 ]; then 134 azure_group_name=$meta_name 135 else 136 echo "Error creating resource group: $meta_name" 137 return 1 138 fi 139 } 140 141 createStorageAccount() { 142 echo "==> Creating storage account" 143 az storage account create --name $meta_name --resource-group $meta_name --location $location --kind Storage --sku Standard_LRS 144 if [ $? -eq 0 ]; then 145 azure_storage_name=$meta_name 146 else 147 echo "Error creating storage account: $meta_name" 148 return 1 149 fi 150 } 151 152 createApplication() { 153 echo "==> Creating application" 154 echo "==> Does application exist?" 155 azure_client_id=$(az ad app list --output json | jq -r '.[] | select(.displayName | contains("'$meta_name'")) ') 156 157 if [ "$azure_client_id" != "" ]; then 158 echo "==> application already exist, grab appId" 159 azure_client_id=$(az ad app list --output json | jq -r '.[] | select(.displayName | contains("'$meta_name'")) .appId') 160 else 161 echo "==> application does not exist" 162 azure_client_id=$(az ad app create --display-name $meta_name --identifier-uris http://$meta_name --homepage http://$meta_name --password $azure_client_secret --output json | jq -r .appId) 163 fi 164 165 if [ $? -ne 0 ]; then 166 echo "Error creating application: $meta_name @ http://$meta_name" 167 return 1 168 fi 169 } 170 171 createServicePrincipal() { 172 echo "==> Creating service principal" 173 azure_object_id=$(az ad sp create --id $azure_client_id --output json | jq -r .objectId) 174 echo $azure_object_id "was selected." 175 176 if [ $? -ne 0 ]; then 177 echo "Error creating service principal: $azure_client_id" 178 return 1 179 fi 180 } 181 182 createPermissions() { 183 echo "==> Creating permissions" 184 az role assignment create --assignee $azure_object_id --role "Owner" --scope /subscriptions/$azure_subscription_id 185 # If the user wants to use a more conservative scope, she can. She must 186 # configure the Azure builder to use build_resource_group_name. The 187 # easiest solution is subscription wide permission. 188 # az role assignment create --spn http://$meta_name -g $azure_group_name -o "API Management Service Contributor" 189 if [ $? -ne 0 ]; then 190 echo "Error creating permissions for: http://$meta_name" 191 return 1 192 fi 193 } 194 195 showConfigs() { 196 echo "" 197 echo "Use the following configuration for your packer template:" 198 echo "" 199 echo "{" 200 echo " \"client_id\": \"$azure_client_id\"," 201 echo " \"client_secret\": \"$azure_client_secret\"," 202 echo " \"object_id\": \"$azure_object_id\"," 203 echo " \"subscription_id\": \"$azure_subscription_id\"," 204 echo " \"tenant_id\": \"$azure_tenant_id\"," 205 echo " \"resource_group_name\": \"$azure_group_name\"," 206 echo " \"storage_account\": \"$azure_storage_name\"," 207 echo "}" 208 echo "" 209 } 210 211 doSleep() { 212 local sleep_time=${PACKER_SLEEP_TIME-$create_sleep} 213 echo "" 214 echo "Sleeping for ${sleep_time} seconds to wait for resources to be " 215 echo "created. If you get an error about a resource not existing, you can " 216 echo "try increasing the amount of time we wait after creating resources " 217 echo "by setting PACKER_SLEEP_TIME to something higher than the default." 218 echo "" 219 sleep $sleep_time 220 } 221 222 retryable() { 223 n=0 224 until [ $n -ge $1 ] 225 do 226 $2 && return 0 227 echo "$2 failed. Retrying..." 228 n=$[$n+1] 229 doSleep 230 done 231 echo "$2 failed after $1 tries. Exiting." 232 exit 1 233 } 234 235 236 setup() { 237 requirements 238 239 az login 240 241 askSubscription 242 askName 243 askSecret 244 askLocation 245 246 # Some of the resources take a while to converge in the API. To make the 247 # script more reliable we'll add a sleep after we create each resource. 248 249 retryable 3 createResourceGroup 250 retryable 3 createStorageAccount 251 retryable 3 createApplication 252 retryable 3 createServicePrincipal 253 retryable 3 createPermissions 254 255 showConfigs 256 } 257 258 case "$1" in 259 requirements) 260 requirements 261 ;; 262 setup) 263 setup 264 ;; 265 *) 266 showhelp 267 ;; 268 esac