Skip to content

Commit

Permalink
Merge pull request #47 from Microsoft/acr-setup-02
Browse files Browse the repository at this point in the history
#37 Change acr-sp-init.sh to adhere to naming convention
  • Loading branch information
code4clouds authored Apr 2, 2019
2 parents 06a80e6 + 9173ec5 commit 2bffe16
Show file tree
Hide file tree
Showing 3 changed files with 164 additions and 88 deletions.
79 changes: 20 additions & 59 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
<<<<<<< HEAD

# Setup

The artifacts used to deploy this project include bash scripts and Terraform templates. The sections below provide guidance to deploy this project into your Azure environment.
Expand All @@ -14,15 +12,27 @@ The artifacts used to deploy this project include bash scripts and Terraform tem

1. Open a bash command prompt.
2. Navigate to the `./setup` folder.
3. Run `acr-sp-init.sh`. For example, the command below will provdision an Azure Container Registry (ACR) in East US and configure the two service principals in Azure Active Directory; one with AcrPush permission and another with AcrPull permission scoped to the ACR. The company name parameter ( `-c` ) is used to construct the name of the resource group, ACR, and service principals.
3. Authenticate to Azure.
``` bash
az login
```
4. Run `acr-sp-init.sh`. For example, the command below will provdision an Azure Container Registry (ACR) in East US and configure the two service principals in Azure Active Directory; one with AcrPush permission and another with AcrPull permission scoped to the ACR. The script parameter values are used to construct the name of the resource group, ACR, and service principals.

``` bash
$ ./acr-sp-init.sh -c Cobalt -l eastus
$ ./acr-sp-init.sh -a Cblt -l eastus -s CoreProd
```

> Note: The script configures service principals in Azure AD and therefore requires elevated privileges. As such, it is recommended that an interactive user with permissions to configure Azure AD run the script.


### Automated Test

The automated test for this setup step is in `./tests/acr-sp-init-test.sh`. It can be executed at the command line as shown below, or as part of a CI pipeline.

``` bash
az login
./tests/acr-sp-init-sh
```

## Setup Shared / Core Infrastructure

### Requirements
Expand Down Expand Up @@ -70,28 +80,27 @@ After saving the file set environment using:

Alternative use the variable.tf files in the directories and add the default key on the file as shown on the example below:

``` json
```
variable "location" {
type = "string"
description = "The name of the target location"
default = "eastus"
}
variable "env" {
type = "string",
type = "string"
description = "The short name of the target env (i.e. dev, staging, or prod)"
defailt = "dev"
}
variable "org" {
type = "string",
type = "string"
description = "The short name of the organization"
default = "cse"
}
variable "app_name" {
type = "string",
type = "string"
description = "The short name of the application"
default = "cblt"
}

```

## Setup Application Infrastructure
Expand All @@ -111,52 +120,4 @@ provided by the bot. You will only need to do this once across all repos using o

This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/).
For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or
contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments.
=======

# Setup

The artifacts used to deploy this project include bash scripts and Terraform templates. The sections below provide guidance to deploy this project into your Azure environment.

> The setup instructions below assume the following requirements:
> - bash v4.0 (or newer)
> - **NOTE FOR MAC!** The default version of bash installed on Mac is older than 4.0. Be sure to update bash using brew before executing the script. Instructions to update bash can be found [here](http://macappstore.org/bash/).
> - Terraform v0.11.13 (or newer)

## Setup the Azure Container Registry and Service Principals

1. Open a bash command prompt.
2. Navigate to the `./setup` folder.
3. Run `acr-sp-init.sh`. For example, the command below will provdision an Azure Container Registry (ACR) in East US and configure the two service principals in Azure Active Directory; one with AcrPush permission and another with AcrPull permission scoped to the ACR. The company name parameter ( `-c` ) is used to construct the name of the resource group, ACR, and service principals.

``` bash
$ ./acr-sp-init.sh -c Cobalt -l eastus
```

> Note: The script configures service principals in Azure AD and therefore requires elevated privileges. As such, it is recommended that an interactive user with permissions to configure Azure AD run the script.


## Setup Shared / Core Infrastructure

> Coming soon!

## Setup Application Infrastructure

> Coming soon!


# Contributing

This project welcomes contributions and suggestions. Most contributions require you to agree to a
Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us
the rights to use your contribution. For details, visit https://cla.microsoft.com.

When you submit a pull request, a CLA-bot will automatically determine whether you need to provide
a CLA and decorate the PR appropriately (e.g., label, comment). Simply follow the instructions
provided by the bot. You will only need to do this once across all repos using our CLA.

This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/).
For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or
contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments.
>>>>>>> master
contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments.
75 changes: 46 additions & 29 deletions setup/acr-sp-init.sh
Original file line number Diff line number Diff line change
@@ -1,37 +1,44 @@
#!/bin/bash -e

while getopts "c:l:" opt; do
while getopts "a:l:s:" opt; do
case $opt in
c)
# Company name
company=$OPTARG
a)
# Application name
appname=$OPTARG
;;
l)
# Location/region where resource group will deploy to
location=$OPTARG
;;
s)
# Suffix
suffix=$OPTARG
;;
esac
done

# If user did not provide required parameters then show usage.
[[ $# -eq 0 || -z $company || -z $location ]] &&
{
if [[ $# -eq 0 || -z $appname || -z $location || -z $suffix ]]; then
echo "Usage:";
echo " $0 -c <company name> -l <location/region>";
echo " $0 -a <app name> -l <location/region> -s <suffix>";
echo " Use \"az account list-locations --query '[].name'\" to list supported regions for a subscription.'"
echo "";
echo "Example:";
echo " $0 -c contoso -l eastus";
echo " $0 -a cblt -l eastus -s prod";
exit 1;
}
fi

# Convert to lowercase, remove whitespace, and trim lenght if needed.
appname=${appname// /}
appname=${appname,,}
appname=${appname:0:4}

location=${location// /}
location=${location,,}

company=${company// /}
company=${company,,}
company=${company:0:8}
suffix=${suffix// /}
suffix=${suffix,,}
suffix=${suffix:0:8}

# Translate location to an abbreviated location code.
locationCode=""
Expand Down Expand Up @@ -87,28 +94,25 @@ declare -A locationCodes=(

locationCode=${locationCodes[$location]}

[[ -z ${locationCode} ]] && {
if [[ -z ${locationCode} ]]; then
echo "Invalid value '${location}' for location parameter.";
exit 1;
}

# Authenticate user.
az login
fi

# Create the resource group.
rgName="acr-${locationCode}-${company}"
rgName="${appname}-${locationCode}-rg-${suffix}"
az group create --name $rgName --location $location

# Create the container registry.
acrName=${rgName//-/}
acrName="${appname}${locationCode}acr${suffix}"
acrId=$(az acr create --resource-group $rgName --name $acrName --sku Standard --query id)
acrId="${acrId//\"}"
# ToDo: Should parameterize 'sku' in the future

# Used to find/create service principals and role assignments to ACR.
declare -A spAcrNameAndRole=(
["http://acr-${company}-pull"]="AcrPull"
["http://acr-${company}-push"]="AcrPush"
["http://${appname}-${locationCode}-sp-${suffix}-pull"]="AcrPull"
["http://${appname}-${locationCode}-sp-${suffix}-push"]="AcrPush"
)

for spName in ${!spAcrNameAndRole[@]}
Expand All @@ -119,23 +123,36 @@ do
spAppId="${spAppId//\"}"

# Create a new service principal if it doesn't already exist.
[[ -z ${spAppId} ]] && {
if [[ -z ${spAppId} ]]; then
echo "Creating service principal '${spName}'."
az ad sp create-for-rbac --name $spName --skip-assignment

echo "Waiting for service principal '${spName}' to propagate in Azure AD."
sleep 20s
}
fi

# Get the role assignment scoped to the ACR for the service principal if it already exists.
roleAssignment=""
roleAssignment=$(az role assignment list --assignee ${spName} --scope ${acrId} --role ${spAcrNameAndRole[$spName]} --query 'length(@)')

# Create a new role assignment if it doesn't already exist.
[[ $roleAssignment -eq 0 ]] && {
if [[ $roleAssignment -eq 0 ]]; then
echo "Creating role assignment for service principal '${spName}'."
az role assignment create --assignee $spName --scope $acrId --role ${spAcrNameAndRole[$spName]}
}
roleAssignmentId=""
retryCount=0
maxRetries=10
while [[ -z $roleAssignmentId && $retryCount -lt $maxRetries ]]
do
sleep 2s
((retryCount++))
roleAssignmentId=$(az role assignment create --assignee $spName --scope $acrId --role ${spAcrNameAndRole[$spName]} --query 'id')
done

# Abort if role assignment could not be created.
if [[ -z $roleAssignmentId ]]; then
echo "Error creating role assignment '${spAcrNameAndRole[$spName]}' for service principal '${spName}'."
exit 1
fi

echo "Role assignment created for service principal '${spName}'."
fi
done

echo "Successfully completed"
98 changes: 98 additions & 0 deletions tests/acr-sp-init-test.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
#!/bin/bash -e

# Test Input Values
appName="CbltApp"
location="eastus"
suffix="Cntso Dev"

bash ../setup/acr-sp-init.sh -a $appName -l $location -s "${suffix}"

# Expected resource group properties
rgName="cblt-usea-rg-cntsodev"
rgLocation="eastus"
expectedRgValues='['${rgName}','${rgLocation}']'

# Expected ACR properties
acrName="cbltuseaacrcntsodev"
acrLocation="eastus"
expectedAcrValues='['${acrName}','${acrLocation}']'

# Expected service principal properties
declare -A spAcrNameAndRole=(
["http://cblt-usea-sp-cntsodev-pull"]="AcrPull"
["http://cblt-usea-sp-cntsodev-push"]="AcrPush"
)

# Assertions
# Test resource group
echo "Testing resource group..."
resourceValues=$(az group show --name $rgName --query '[name,location]' --output JSON)
resourceValues=${resourceValues//[[:space:]]/}
resourceValues=${resourceValues//\"/}

if [[ "$resourceValues" != "$expectedRgValues" ]]; then
echo "Error: Unexpected resource group values."
echo " Results returned '${resourceValues}'"
echo " expected '${expectedRgValues}'"
exit 1;
fi

# Test ACR
echo "Testing container registry..."
resourceValues=$(az acr show --name $acrName --query '[name,location]' --output JSON)
resourceValues=${resourceValues//[[:space:]]/}
resourceValues=${resourceValues//\"/}

if [[ "$resourceValues" != "$expectedAcrValues" ]]; then
echo "Error: Unexpected container registry values."
echo " Results returned '${resourceValues}'"
echo " expected '${expectedAcrValues}'"
exit 1;
fi

# Test service principals
echo "Testing service principals..."

# Get the ACR ID for the container registry the service principal role assignments should be scoped to.
acrId=$(az acr show --name $acrName --query id)
acrId="${acrId//\"}"

for spName in ${!spAcrNameAndRole[@]}
do
# Get the appId of the expected service principal
spAppId=$(az ad sp show --id ${spName} --query appId)
spAppId="${spAppId//\"}"

# Get the role assignment scoped to the ACR for the service principal.
roleAssignment=$(az role assignment list --assignee ${spName} --scope ${acrId} --role ${spAcrNameAndRole[$spName]} --query 'length(@)')
if [[ roleAssignment -eq 0 ]]; then
echo "Error: Role assignmet to ACR '${acrName}' for service principal '$spName' is missing."
exit 1;
fi
done

echo "Tests passed successfully"

# Clean up tests results
echo "Cleaning up test resources"

echo " Cleaning up service principals and role assignments..."
for spName in ${!spAcrNameAndRole[@]}
do
# Clean up service principals and role assignments
spAppId=$(az ad sp show --id ${spName} --query appId)
spAppId="${spAppId//\"}"
az ad sp delete --id ${spAppId}
done

# Clean up container registry
echo " Cleaning up container registry..."
az acr delete --name ${acrName}

# Clean up resource group
echo " Cleaning up resource group..."
az group delete --name ${rgName} --yes




0 comments on commit 2bffe16

Please sign in to comment.