Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

#37 Change acr-sp-init.sh to adhere to naming convention #47

Merged
merged 9 commits into from
Apr 2, 2019
69 changes: 11 additions & 58 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,10 +12,14 @@ 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.
Expand Down Expand Up @@ -70,28 +72,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 +112,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.
62 changes: 40 additions & 22 deletions setup/acr-sp-init.sh
Original file line number Diff line number Diff line change
@@ -1,37 +1,45 @@
#!/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 ]] &&
[[ $# -eq 0 || -z $appname || -z $location || -z $suffix ]] &&
{
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;
}

# 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 @@ -92,23 +100,20 @@ locationCode=${locationCodes[$location]}
exit 1;
}

# Authenticate user.
az login

# 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 @@ -122,19 +127,32 @@ do
[[ -z ${spAppId} ]] && {
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
}

# 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 ]] && {
[[ $roleAssignment -eq 0 ]] && {
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.
[[ -z $roleAssignmentId ]] && {
echo "Error creating role assignment '${spAcrNameAndRole[$spName]}' for service principal '${spName}'.";
exit 1;
}

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

Expand Down
76 changes: 76 additions & 0 deletions tests/acr-sp-init-test.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
#!/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//\"/}

[[ "$resourceValues" != "$expectedRgValues" ]] && {
code4clouds marked this conversation as resolved.
Show resolved Hide resolved
echo "Error: Unexpected resource group values."
echo " Results returned '${resourceValues}'"
echo " expected '${expectedRgValues}'"
exit 1;
}

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

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

# Test service principals
echo "Testing service principals..."
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 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//\"}"

# 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(@)')
[[ roleAssignment -eq 0 ]] && {
echo "Error: Role assignmet to ACR '${acrName}' for service principal '$spName' is missing."
exit 1;
}
done

echo "Tests passed successfully"