-
Notifications
You must be signed in to change notification settings - Fork 150
Expand file tree
/
Copy pathcreate-cosmos-db-resources.sh
More file actions
207 lines (173 loc) · 7.41 KB
/
create-cosmos-db-resources.sh
File metadata and controls
207 lines (173 loc) · 7.41 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
#!/bin/bash
# filepath: create-resources.sh
# Prerequisites:
# - Install the Azure CLI and run: az login
#
# This script now fetches the role definition id for "Cosmos DB Operator" automatically.
# Exit if any command returns a non-zero status
set -euo pipefail
echo "Script started - checking prerequisites..."
# Verify that the user is logged in
echo "Checking Azure CLI login status..."
if ! az account show > /dev/null 2>&1; then
echo "Error: Not logged in to Azure CLI. Please run 'az login' and try again."
exit 1
fi
echo "Azure CLI login verified."
random_string() {
# More reliable random string generation with multiple fallback methods
# Method 1: Using built-in RANDOM variable (most compatible)
local result=""
local chars="abcdefghijklmnopqrstuvwxyz0123456789"
local length=6 # Shorter 6-character string
# Generate random string using bash's RANDOM
for i in {1..6}; do
local idx=$((RANDOM % 36))
result+=${chars:$idx:1}
done
# If result is empty for some reason, use timestamp as fallback
if [ -z "$result" ]; then
result=$(date +%s | cut -c 7-12)
fi
echo "$result"
}
echo "Generating random string..."
RANDOM_STRING=$(random_string)
echo "Random string generated successfully: $RANDOM_STRING"
echo "Getting Azure subscription information..."
SUBSCRIPTION_ID=$(az account show --query id -o tsv)
echo "Subscription ID retrieved: $SUBSCRIPTION_ID"
LOCATION="centralus"
RESOURCE_GROUP_NAME="sdk-test-cosmosdb-rg-$RANDOM_STRING"
COSMOS_DB_RESOURCE_NAME="sdk-test-cosmosdb-$RANDOM_STRING"
echo "Getting principal ID..."
# Try different approaches to get the user's principal ID, with verbose error handling
if ! PRINCIPAL_ID=$(az ad signed-in-user show --query id -o tsv 2>/dev/null); then
echo "Failed to get principal ID using signed-in-user, trying alternative method..."
USER_NAME=$(az account show --query user.name -o tsv)
echo "Got user name: $USER_NAME, looking up user ID..."
if ! PRINCIPAL_ID=$(az ad user show --id "$USER_NAME" --query id -o tsv 2>/dev/null); then
echo "Error: Could not determine principal ID. Using current account credentials for roles."
PRINCIPAL_ID=$(az account show --query id -o tsv)
fi
fi
echo "Principal ID retrieved: $PRINCIPAL_ID"
# Create a unique resource group and cosmos db name using a random suffix.
RG="$RESOURCE_GROUP_NAME"
printf "Resource Group: %s\n" "$RG"
RESOURCE_NAME="$COSMOS_DB_RESOURCE_NAME"
printf "Resource Name: %s\n" "$RESOURCE_NAME"
# Create a resource group
az group create \
--subscription "$SUBSCRIPTION_ID" \
--name "$RG" \
--location "$LOCATION"
printf "Resource Group created\n"
# Create a Cosmos DB account (for example, using MongoDB API)
az cosmosdb create \
--subscription "$SUBSCRIPTION_ID" \
--resource-group "$RG" \
--name "$RESOURCE_NAME" \
--kind GlobalDocumentDB \
--locations regionName="$LOCATION" failoverPriority=0 isZoneRedundant=False
printf "Cosmos DB account created\n"
# Get the Cosmos DB account endpoint
COSMOS_DB_ENDPOINT=$(az cosmosdb show \
--subscription "$SUBSCRIPTION_ID" \
--resource-group "$RG" \
--name "$RESOURCE_NAME" \
--query "documentEndpoint" \
--output tsv)
printf "Cosmos DB Endpoint: %s\n" "$COSMOS_DB_ENDPOINT"
# Append the endpoint to the .env file if not already populated
if [ ! -f .env ]; then
touch .env
fi
echo "COSMOS_DB_ENDPOINT=$COSMOS_DB_ENDPOINT" >> .env
echo "Cosmos DB Endpoint: $COSMOS_DB_ENDPOINT"
# --------------------------------------------------------------------------
# Create a Cosmos DB SQL database and container, and update .env with their values
# Set database and container names
DB_NAME="db-$RANDOM_STRING"
CONTAINER_NAME="container-$RANDOM_STRING"
# Create a database (using throughput of 400 RU/s as an example)
az cosmosdb sql database create \
--account-name "$RESOURCE_NAME" \
--name "$DB_NAME" \
--resource-group "$RG" \
--subscription "$SUBSCRIPTION_ID" \
--throughput 400
echo "COSMOS_DATABASE_NAME=$DB_NAME" >> .env
printf "Cosmos DB SQL database '%s' created\n" "$DB_NAME"
# Create a container (using throughput of 400 RU/s as an example)
az cosmosdb sql container create \
--account-name "$RESOURCE_NAME" \
--database-name "$DB_NAME" \
--name "$CONTAINER_NAME" \
--partition-key-path "/name" \
--resource-group "$RG" \
--subscription "$SUBSCRIPTION_ID" \
--throughput 400
echo "COSMOS_CONTAINER_NAME=$CONTAINER_NAME" >> .env
printf "Cosmos DB SQL container '%s' created\n" "$CONTAINER_NAME"
printf "Database and container names appended to .env\n"
# --------------------------------------------------------------------------
# Role assignment for Cosmos DB access
# Get the role definition ID for "Cosmos DB Built-in Data Contributor"
echo "Getting role definitions..."
ROLE_DEFS=$(az cosmosdb sql role definition list \
--resource-group "$RG" \
--account-name "$RESOURCE_NAME")
echo "Role definitions retrieved: $ROLE_DEFS"
echo "Querying for Cosmos DB Built-in Data Contributor role..."
ROLE_DEF_ID=$(az cosmosdb sql role definition list \
--resource-group "$RG" \
--account-name "$RESOURCE_NAME" \
--query "[?roleName=='Cosmos DB Built-in Data Contributor'].id" \
--output tsv)
if [ -z "$ROLE_DEF_ID" ]; then
echo "Role definition ID not found. Using fallback ID."
# Fallback to the well-known ID if not found
ROLE_DEF_ID="/subscriptions/$SUBSCRIPTION_ID/resourceGroups/$RG/providers/Microsoft.DocumentDB/databaseAccounts/$RESOURCE_NAME/sqlRoleDefinitions/00000000-0000-0000-0000-000000000002"
printf "Using fallback role definition ID: %s\n" "$ROLE_DEF_ID"
else
printf "Found role definition ID: %s\n" "$ROLE_DEF_ID"
fi
# Create a role assignment using the built-in data contributor role
echo "Creating role assignment..."
if ! az cosmosdb sql role assignment create \
--resource-group "$RG" \
--account-name "$RESOURCE_NAME" \
--role-definition-id "$ROLE_DEF_ID" \
--principal-id "$PRINCIPAL_ID" \
--scope "/subscriptions/$SUBSCRIPTION_ID/resourceGroups/$RG/providers/Microsoft.DocumentDB/databaseAccounts/$RESOURCE_NAME"; then
echo "Warning: Failed to create role assignment. This might be because it already exists or due to permission issues."
echo "Continuing with script execution..."
else
printf "Role assignment created successfully\n"
fi
# List role assignments to verify
az cosmosdb sql role assignment list \
--resource-group "$RG" \
--account-name "$RESOURCE_NAME"
# Ensure we have all the required values before completing
echo "Verifying all required values are present..."
# Check for empty values
if [ -z "$RG" ] || [ -z "$RESOURCE_NAME" ] || [ -z "$DB_NAME" ] || [ -z "$CONTAINER_NAME" ] || [ -z "$COSMOS_DB_ENDPOINT" ]; then
printf "Warning: One or more required values is empty:\n"
printf " Resource Group: %s\n" "$RG"
printf " Cosmos DB Account: %s\n" "$RESOURCE_NAME"
printf " Database: %s\n" "$DB_NAME"
printf " Container: %s\n" "$CONTAINER_NAME"
printf " Endpoint: %s\n" "$COSMOS_DB_ENDPOINT"
printf "Script may have encountered issues.\n"
else
printf "Script completed successfully!\n"
printf "Resources created:\n"
printf " Resource Group: %s\n" "$RG"
printf " Cosmos DB Account: %s\n" "$RESOURCE_NAME"
printf " Database: %s\n" "$DB_NAME"
printf " Container: %s\n" "$CONTAINER_NAME"
printf " Endpoint: %s\n" "$COSMOS_DB_ENDPOINT"
printf "Environment variables have been added to .env file\n"
fi