Bash 用の Azure CLI スクリプトを作成する
Azure portal で完了できるほぼすべてのタスクは、Azure CLI 参照コマンドを使用して完了できます。 Azure portal を使用して Azure について学習することは、最初に最適な場所です。 ただし、 Azure CLI または Azure PowerShell を使用して、Azure リソース を大規模に管理することをお勧めします。
世界中の企業向けに Azure を管理するシナリオを考えてみましょう。 新しい リソース グループ、 Azure Logic Apps、 ストレージ アカウント、 Azure Data Factory パイプライン、 Azure SQL データベースに対して、毎日複数の要求を受け取ります。 すべてのチームは、開発、ステージング、運用環境で作業します。 要求ごとに、会社の名前付け基準とセキュリティ ポリシーに従う 3 つの類似した Azure リソース を作成する必要があります。 次は、Azure CLI スクリプトを使用します。
Azure CLI スクリプトについて
Azure CLI スクリプトを使用すると、反復的なタスクとインフラストラクチャのデプロイを大規模に自動化できます。 スクリプトは一貫性を提供し、人為的なエラーを減らし、コードとしてのインフラストラクチャ (IaC) プラクティスを有効にします。 開発、ステージング、運用環境のいずれを管理する場合でも、 Azure CLI スクリプトを使用すると、リソースのプロビジョニングと管理が効率化されます。
スクリプト構造の基本
適切に構造化された Azure CLI スクリプトには、通常、次のものが含まれます。
-
Shebang (
#!/bin/bashまたは#!/usr/bin/env bash): スクリプトを実行するためのインタープリターを指定します。 - 変数: リソース名、場所、SKU 構成などの再利用可能な値を格納します。
- コメント: 保守容易性のためのドキュメント スクリプトのロジックとパラメーター。
- エラー処理: エラーを適切に処理するためのチェックを実装します。
- ループと条件: 複数のリソースを作成するか、条件に基づいてロジックを適用します。
- 出力の書式設定: 検証用の読み取り可能な形式で結果を表示します。
リソースデプロイスクリプトを作成する
一貫性のある反復可能な方法で複数の Azure ストレージ アカウントを作成する実用的な Bash スクリプトを見てみましょう。
#!/bin/bash
# Script: Create multiple Azure storage accounts
# Description: Automates storage account creation with consistent naming and configuration
# Define deployment parameters
resourceGroupName="rg-storage-prod-eastus"
saCount=3
saLocation="eastus"
saNamePrefix="stprod"
saSku="Standard_GRS"
saKind="StorageV2"
# Validate Azure CLI is installed and authenticated
if ! command -v az &> /dev/null; then
echo "Error: Azure CLI is not installed. Please install Azure CLI first."
exit 1
fi
if ! az account show &> /dev/null; then
echo "Error: Not authenticated to Azure. Please run 'az login' first."
exit 1
fi
echo "Starting storage account deployment..."
echo "Resource Group: $resourceGroupName"
echo "Location: $saLocation"
echo "Count: $saCount"
echo ""
# Create resource group if it doesn't exist
if ! az group show --name $resourceGroupName &> /dev/null; then
echo "Creating resource group $resourceGroupName..."
az group create --name $resourceGroupName --location $saLocation
else
echo "Resource group $resourceGroupName already exists."
fi
# Loop to create multiple storage accounts
for i in $(seq 1 $saCount)
do
# Generate unique identifier using timestamp and random number
timestamp=$(date +%s)
let "randomIdentifier=$RANDOM"
saName="${saNamePrefix}${timestamp}${randomIdentifier}"
# Ensure name is lowercase and within 24 character limit
saName=$(echo $saName | tr '[:upper:]' '[:lower:]' | cut -c1-24)
echo "Creating storage account $saName..."
# Create storage account with error handling
if az storage account create \
--name $saName \
--resource-group $resourceGroupName \
--location $saLocation \
--sku $saSku \
--kind $saKind \
--tags Environment=Production ManagedBy=AzureCLI \
--output none; then
echo "✓ Successfully created storage account $saName"
else
echo "✗ Failed to create storage account $saName"
fi
done
echo ""
echo "Deployment complete. Verifying results..."
echo ""
# Verify results with formatted output
az storage account list \
--resource-group $resourceGroupName \
--query "[].{Name:name, Location:location, SKU:sku.name, Status:statusOfPrimary}" \
--output table
スクリプトの内訳
主なコンポーネントを調べてみましょう。
認証の検証:
if ! az account show &> /dev/null; then
echo "Error: Not authenticated to Azure. Please run 'az login' first."
exit 1
fi
リソース操作を実行する前にユーザーが認証されていることを確認し、スクリプトの失敗を防ぎます。
存在チェックを使用したリソース グループの作成:
if ! az group show --name $resourceGroupName &> /dev/null; then
az group create --name $resourceGroupName --location $saLocation
fi
リソース グループがまだ存在しない場合にのみ作成し、スクリプトをべき等にします。
一意の名前の生成:
timestamp=$(date +%s)
let "randomIdentifier=$RANDOM"
saName="${saNamePrefix}${timestamp}${randomIdentifier}"
saName=$(echo $saName | tr '[:upper:]' '[:lower:]' | cut -c1-24)
タイムスタンプと乱数を組み合わせて一意のストレージ アカウント名を生成し、小文字に変換し、Azure の名前付け要件ごとに 24 文字に制限します。
エラー処理:
if az storage account create ...; then
echo "✓ Successfully created storage account $saName"
else
echo "✗ Failed to create storage account $saName"
fi
各ストレージ アカウントの作成を検証し、成功/失敗に関する明確なフィードバックを提供します。
パラメーター化されたスクリプトを作成する
運用環境のスクリプトでは、環境間で柔軟性を確保するためにパラメーターを受け入れる必要があります。
#!/bin/bash
# Script: create-storage-accounts.sh
# Usage: ./create-storage-accounts.sh <resource-group> <location> <count> <environment>
# Accept command-line parameters
resourceGroupName=$1
saLocation=$2
saCount=$3
environment=$4
# Validate parameters
if [ -z "$resourceGroupName" ] || [ -z "$saLocation" ] || [ -z "$saCount" ] || [ -z "$environment" ]; then
echo "Usage: $0 <resource-group> <location> <count> <environment>"
echo "Example: $0 rg-storage-dev eastus 3 Development"
exit 1
fi
# Validate count is a number
if ! [[ "$saCount" =~ ^[0-9]+$ ]]; then
echo "Error: Count must be a number"
exit 1
fi
echo "Parameters received:"
echo " Resource Group: $resourceGroupName"
echo " Location: $saLocation"
echo " Count: $saCount"
echo " Environment: $environment"
echo ""
# Set environment-specific configurations
case $environment in
Development)
saSku="Standard_LRS"
saKind="StorageV2"
;;
Staging)
saSku="Standard_GRS"
saKind="StorageV2"
;;
Production)
saSku="Standard_RAGRS"
saKind="StorageV2"
;;
*)
echo "Error: Environment must be Development, Staging, or Production"
exit 1
;;
esac
echo "Using SKU: $saSku for $environment environment"
echo ""
# Continue with resource creation...
パラメーター化されたスクリプトを実行する
# Make script executable
chmod +x create-storage-accounts.sh
# Execute with parameters
./create-storage-accounts.sh rg-storage-dev eastus 3 Development
構成ドリブン スクリプトを作成する
複雑なデプロイの場合は、外部構成ファイルを使用します。
config.json:
{
"resourceGroup": {
"name": "rg-app-prod-eastus",
"location": "eastus"
},
"storageAccounts": [
{
"namePrefix": "stappdata",
"sku": "Standard_RAGRS",
"kind": "StorageV2",
"count": 2
},
{
"namePrefix": "stappbackup",
"sku": "Standard_GRS",
"kind": "StorageV2",
"count": 1
}
],
"tags": {
"Environment": "Production",
"CostCenter": "Engineering",
"ManagedBy": "AzureCLI"
}
}
deploy-from-config.sh:
#!/bin/bash
# Load configuration file
configFile="config.json"
if [ ! -f "$configFile" ]; then
echo "Error: Configuration file $configFile not found"
exit 1
fi
# Parse configuration using jq (JSON processor)
resourceGroupName=$(jq -r '.resourceGroup.name' $configFile)
resourceGroupLocation=$(jq -r '.resourceGroup.location' $configFile)
tagsJson=$(jq -r '.tags | to_entries | map("\(.key)=\(.value)") | join(" ")' $configFile)
echo "Deploying resources from configuration file..."
echo "Resource Group: $resourceGroupName"
echo "Location: $resourceGroupLocation"
echo ""
# Create resource group
az group create --name $resourceGroupName --location $resourceGroupLocation
# Read storage account configurations
storageConfigCount=$(jq '.storageAccounts | length' $configFile)
for i in $(seq 0 $(($storageConfigCount - 1)))
do
namePrefix=$(jq -r ".storageAccounts[$i].namePrefix" $configFile)
sku=$(jq -r ".storageAccounts[$i].sku" $configFile)
kind=$(jq -r ".storageAccounts[$i].kind" $configFile)
count=$(jq -r ".storageAccounts[$i].count" $configFile)
echo "Creating $count storage account(s) with prefix: $namePrefix"
for j in $(seq 1 $count)
do
timestamp=$(date +%s)
saName="${namePrefix}${timestamp}${RANDOM}"
saName=$(echo $saName | tr '[:upper:]' '[:lower:]' | cut -c1-24)
az storage account create \
--name $saName \
--resource-group $resourceGroupName \
--location $resourceGroupLocation \
--sku $sku \
--kind $kind \
--tags $tagsJson \
--output none
echo " ✓ Created: $saName"
done
done
echo ""
echo "Deployment complete."
設定に基づく利点
- 懸念事項の分離: デプロイ ロジックとは別の構成。
- 環境の昇格: 開発、ステージング、運用用に異なる構成ファイルを含む同じスクリプト。
- バージョン 管理: コードと共に構成の変更を追跡します。
- 検証: デプロイ前に構成構造を検証します。
スクリプトを使用して Azure リソースを削除する
スクリプトを作成してテストするときは、不要なコストを回避するために、必ずテスト リソースを削除してください。 Azure CLI スクリプトを使用すると、安全で一貫性のあるリソースのクリーンアップが可能になります。
作成日でストレージ アカウントを削除する
特定の日時以降に作成されたすべての ストレージ アカウント を削除します。
#!/bin/bash
# Define cleanup parameters
cutoffDate="2025-10-08T00:00:00.000000+00:00"
resourceGroup="rg-storage-dev-eastus"
echo "Finding storage accounts created on or after $cutoffDate..."
# Get list of storage accounts matching criteria
saList=$(az storage account list \
--resource-group $resourceGroup \
--query "[?creationTime >='$cutoffDate'].{Name:name, Created:creationTime}" \
--output table)
echo "$saList"
echo ""
# Confirm deletion
read -p "Delete these storage accounts? (yes/no): " confirm
if [ "$confirm" == "yes" ]; then
for saId in $(az storage account list \
--resource-group $resourceGroup \
--query "[?creationTime >='$cutoffDate'].id" \
--output tsv); do
echo "Deleting storage account: $saId"
az storage account delete --ids $saId --yes
done
echo "Cleanup complete."
else
echo "Deletion cancelled."
fi
ログ記録を使用してリソース グループを削除する
包括的なログ記録を使用して、名前付けパターンに一致する リソース グループ を削除します。
#!/bin/bash
# Define cleanup parameters
namePattern="rg-dev-*"
logFileLocation="cleanup-$(date +%Y%m%d-%H%M%S).log"
echo "Resource Group Cleanup" > $logFileLocation
echo "Started: $(date)" >> $logFileLocation
echo "Pattern: $namePattern" >> $logFileLocation
echo "----------------------------------------" >> $logFileLocation
# Find matching resource groups
echo "Finding resource groups matching pattern: $namePattern"
matchingGroups=$(az group list \
--query "[?starts_with(name, 'rg-dev-')].name" \
--output tsv)
if [ -z "$matchingGroups" ]; then
echo "No resource groups found matching pattern: $namePattern"
echo "No resource groups found" >> $logFileLocation
exit 0
fi
# Display matches
echo "Found resource groups:"
echo "$matchingGroups"
echo ""
# Log matches
echo "Resource groups found:" >> $logFileLocation
echo "$matchingGroups" >> $logFileLocation
echo "" >> $logFileLocation
# Confirm deletion
read -p "Delete these resource groups? (yes/no): " confirm
if [ "$confirm" == "yes" ]; then
echo "Starting deletion..." >> $logFileLocation
for rgName in $matchingGroups
do
echo "Deleting resource group: $rgName"
echo "$(date): Deleting $rgName" >> $logFileLocation
# Delete with --no-wait for background execution
if az group delete --name $rgName --yes --no-wait; then
echo " ✓ Deletion initiated for $rgName"
echo "$(date): ✓ Deletion initiated for $rgName" >> $logFileLocation
else
echo " ✗ Failed to initiate deletion for $rgName"
echo "$(date): ✗ Failed to delete $rgName" >> $logFileLocation
fi
done
echo ""
echo "Deletion operations initiated. Resources will be removed in the background."
echo "Check deletion status with: az group list --query \"[?starts_with(name, 'rg-dev-')].name\""
echo "" >> $logFileLocation
echo "Completed: $(date)" >> $logFileLocation
echo "Log saved to: $logFileLocation"
# Display log
echo ""
echo "=== Cleanup Log ==="
cat $logFileLocation
else
echo "Deletion cancelled by user" >> $logFileLocation
echo "Deletion cancelled."
fi
安全な削除のプラクティス
削除前に安全チェックを実装します。
#!/bin/bash
# Delete resources safely with multiple confirmations
resourceGroup="rg-storage-test-eastus"
# Check if resource group exists
if ! az group show --name $resourceGroup &> /dev/null; then
echo "Error: Resource group '$resourceGroup' not found"
exit 1
fi
# Display resources that will be deleted
echo "Resources in resource group '$resourceGroup':"
az resource list --resource-group $resourceGroup \
--query "[].{Name:name, Type:type, Location:location}" \
--output table
echo ""
echo "⚠️ WARNING: This will delete ALL resources in '$resourceGroup'"
echo ""
# First confirmation
read -p "Are you sure you want to delete '$resourceGroup'? (yes/no): " confirm1
if [ "$confirm1" != "yes" ]; then
echo "Deletion cancelled."
exit 0
fi
# Second confirmation with exact name
read -p "Type the resource group name to confirm: " confirm2
if [ "$confirm2" != "$resourceGroup" ]; then
echo "Resource group name does not match. Deletion cancelled."
exit 1
fi
# Final countdown
echo "Deleting in 5 seconds. Press Ctrl+C to cancel."
sleep 5
echo "Deleting resource group '$resourceGroup'..."
az group delete --name $resourceGroup --yes
echo "Resource group deleted successfully."
Warnung
削除する前に必ずリソースを確認してください。 リソース グループを削除すると、その中のすべてのリソースが完全に削除されます。 この操作を元に戻すことはできません。
運用スクリプトのベスト プラクティス
運用対応の Azure CLI スクリプトには、慎重な計画と実装が必要です。 このユニットで提供されるスクリプトは基本的な概念を示していますが、運用環境では追加の考慮事項が必要です。
基本的な運用スクリプト コンポーネント
運用環境用の堅牢な Azure CLI スクリプトには、次のものが含まれている必要があります。
1. 認証と承認:
#!/bin/bash
# Authenticate with service principal (for automation)
if [ -n "$AZURE_CLIENT_ID" ] && [ -n "$AZURE_CLIENT_SECRET" ] && [ -n "$AZURE_TENANT_ID" ]; then
echo "Authenticating with service principal..."
az login --service-principal \
--username $AZURE_CLIENT_ID \
--password $AZURE_CLIENT_SECRET \
--tenant $AZURE_TENANT_ID
else
echo "Error: Service principal credentials not found"
exit 1
fi
# Set subscription
az account set --subscription $AZURE_SUBSCRIPTION_ID
# Verify authentication
if ! az account show &> /dev/null; then
echo "Error: Authentication failed"
exit 1
fi
2. 包括的なエラー処理:
#!/bin/bash
# Exit immediately if command fails
set -e
# Trap errors and perform cleanup
trap 'cleanup_on_error' ERR
cleanup_on_error() {
echo "Error occurred on line $1"
echo "Performing cleanup..."
# Add cleanup logic here
exit 1
}
# Enable error trapping with line numbers
trap 'cleanup_on_error $LINENO' ERR
3. イデンプテンシーチェック:
#!/bin/bash
# Check if resource group exists before creation
create_resource_group() {
local rgName=$1
local location=$2
if az group show --name $rgName &> /dev/null; then
echo "Resource group $rgName already exists. Skipping creation."
else
echo "Creating resource group $rgName..."
az group create --name $rgName --location $location
fi
}
# Check if storage account exists
create_storage_account() {
local saName=$1
local rgName=$2
if az storage account show --name $saName --resource-group $rgName &> /dev/null; then
echo "Storage account $saName already exists. Skipping creation."
return 0
else
echo "Creating storage account $saName..."
az storage account create --name $saName --resource-group $rgName --location eastus
fi
}
4. 構造化ログ:
#!/bin/bash
# Define log file with timestamp
logFile="deployment-$(date +%Y%m%d-%H%M%S).log"
errorLog="errors-$(date +%Y%m%d-%H%M%S).log"
# Logging function
log() {
local level=$1
shift
local message="$@"
local timestamp=$(date "+%Y-%m-%d %H:%M:%S")
echo "[$timestamp] [$level] $message" | tee -a $logFile
if [ "$level" == "ERROR" ]; then
echo "[$timestamp] $message" >> $errorLog
fi
}
# Usage
log "INFO" "Starting deployment..."
log "ERROR" "Failed to create resource"
log "SUCCESS" "Deployment complete"
5. 構成の検証:
#!/bin/bash
# Validate required configuration
validate_config() {
local errors=0
if [ -z "$RESOURCE_GROUP" ]; then
echo "Error: RESOURCE_GROUP not defined"
((errors++))
fi
if [ -z "$LOCATION" ]; then
echo "Error: LOCATION not defined"
((errors++))
fi
# Validate location exists
if ! az account list-locations --query "[?name=='$LOCATION']" | grep -q "$LOCATION"; then
echo "Error: Invalid location: $LOCATION"
((errors++))
fi
if [ $errors -gt 0 ]; then
echo "Configuration validation failed with $errors error(s)"
exit 1
fi
echo "Configuration validation passed"
}
6. タグ付け戦略:
#!/bin/bash
# Define standard tags
environment=$1 # Development, Staging, Production
costCenter=$2
owner=$3
# Create tags string
tags="Environment=$environment CostCenter=$costCenter Owner=$owner \
CreatedBy=AzureCLI CreatedDate=$(date +%Y-%m-%d) \
ManagedBy=Infrastructure-Team Project=WebApp"
# Apply tags to resources
az group create \
--name $resourceGroup \
--location $location \
--tags $tags
az storage account create \
--name $saName \
--resource-group $resourceGroup \
--location $location \
--tags $tags
7. ロールバック機能:
#!/bin/bash
# Track created resources for rollback
createdResources=()
create_with_tracking() {
local resourceType=$1
local resourceName=$2
# Attempt resource creation
if create_resource "$resourceType" "$resourceName"; then
createdResources+=("$resourceType:$resourceName")
echo "✓ Created: $resourceType - $resourceName"
return 0
else
echo "✗ Failed: $resourceType - $resourceName"
return 1
fi
}
rollback() {
echo "Rolling back created resources..."
for resource in "${createdResources[@]}"; do
IFS=':' read -r type name <<< "$resource"
echo "Deleting $type: $name"
delete_resource "$type" "$name"
done
echo "Rollback complete"
}
# Use trap to rollback on error
trap rollback ERR
スクリプト編成の構造
スクリプトを論理モジュールに整理します。
azure-infrastructure/
├── config/
│ ├── dev.json
│ ├── staging.json
│ └── prod.json
├── scripts/
│ ├── deploy-infrastructure.sh
│ ├── deploy-storage.sh
│ └── cleanup.sh
├── lib/
│ ├── common-functions.sh
│ ├── logging.sh
│ └── validation.sh
├── logs/
└── README.md
再利用可能な関数ライブラリ
common-functions.sh:
#!/bin/bash
# Load this file in other scripts: source ./lib/common-functions.sh
# Check if Azure CLI is installed
check_azure_cli() {
if ! command -v az &> /dev/null; then
echo "Error: Azure CLI not installed"
exit 1
fi
}
# Wait for resource to be ready
wait_for_resource() {
local resourceId=$1
local maxAttempts=30
local attempt=1
echo "Waiting for resource to be ready..."
while [ $attempt -le $maxAttempts ]; do
if az resource show --ids $resourceId &> /dev/null; then
echo "Resource is ready"
return 0
fi
echo "Attempt $attempt/$maxAttempts - waiting..."
sleep 10
((attempt++))
done
echo "Timeout waiting for resource"
return 1
}
# Generate unique name
generate_unique_name() {
local prefix=$1
local timestamp=$(date +%s)
local random=$RANDOM
echo "${prefix}${timestamp}${random}" | tr '[:upper:]' '[:lower:]' | cut -c1-24
}
スクリプトを安全にテストする
分離された環境でスクリプトをテストする:
#!/bin/bash
# Test mode flag
TEST_MODE=${TEST_MODE:-false}
execute_command() {
local command=$1
if [ "$TEST_MODE" == "true" ]; then
echo "[TEST MODE] Would execute: $command"
else
echo "Executing: $command"
eval $command
fi
}
# Usage
execute_command "az group create --name rg-test --location eastus"
テスト モードで実行します。
TEST_MODE=true ./deploy-infrastructure.sh
その他のリソース
- Azure CLI サンプル リポジトリ:github.com/Azure-Samples/azure-cli-samples。
- Azure CLI スクリプト ガイド:learn.microsoft.com/cli/azure/azure-cli-vm-tutorial。
Bash スクリプトのベスト プラクティス: www.gnu.org/software/bash/manual/
このユニットのスクリプトは、変数、ループ、条件、およびエラー処理を Azure CLI コマンドと組み合わせる場合の Azure CLI 機能を示しています。 これらのパターンは、いくつかのリソースの管理から複雑なエンタープライズ インフラストラクチャのデプロイの調整まで拡張されます。