Skip to content

Commit

Permalink
2. Devcontainer on Az CLI 2.37 (microsoft#2172)
Browse files Browse the repository at this point in the history
* Removed scripts folder

* Linting

* Linting #3

* Added in build step

* PR comment

* Revert db-migrate

* Admin Consent

* Workspace Admin Consent

* Removed unsued variables

* Split AAD scripts up

* Working on bash read prompt

* Add a final check

* Removing private file

* Moving to Az cli 2.37 for Graph

* Removed appName from credential reset

* update_resource_access

* Remove AAD_TENANT_ID

* Rp should use 2.37 az cli

* increase mgmt AzureRM version

* Bump version

* Pinning versions of apt-get packages

* pipe and copy

* WORKDIR

* Move requirements to /tmp folder

* --no-install-recommends

* --no-install-recommends
  • Loading branch information
ross-p-smith authored Jul 13, 2022
1 parent 1c059a5 commit bdb5e6e
Show file tree
Hide file tree
Showing 16 changed files with 160 additions and 170 deletions.
8 changes: 4 additions & 4 deletions .devcontainer/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,11 @@ RUN /tmp/docker-client.sh $USERNAME

# Install Docker
# hadolint ignore=DL3008,DL3004
RUN apt-get update && sudo apt-get install -y apt-transport-https ca-certificates curl gnupg lsb-release \
RUN apt-get update && sudo apt-get install -y apt-transport-https ca-certificates curl gnupg lsb-release --no-install-recommends \
&& curl -fsSL https://download.docker.com/linux/debian/gpg | gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg \
&& echo "deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/debian $(lsb_release -cs) stable" \
| tee /etc/apt/sources.list.d/docker.list > /dev/null \
&& apt-get update && apt-get install -y docker-ce docker-ce-cli containerd.io \
&& apt-get update && apt-get install -y docker-ce docker-ce-cli containerd.io --no-install-recommends \
&& apt-get clean -y && rm -rf /var/lib/apt/lists/*

# Install nekos act - run GitHub workflows locally https://github.com/nektos/act
Expand All @@ -47,7 +47,7 @@ RUN if [ "${INTERACTIVE}" = "true" ]; then curl https://raw.githubusercontent.co

# Install Certbot
# hadolint ignore=DL3008
RUN apt-get update && apt-get install -y python3 python3-venv libaugeas0 \
RUN apt-get update && apt-get install -y python3 python3-venv libaugeas0 --no-install-recommends \
&& python3 -m venv /opt/certbot/ \
&& /opt/certbot/bin/pip install --no-cache-dir --upgrade pip \
&& /opt/certbot/bin/pip install --no-cache-dir certbot \
Expand Down Expand Up @@ -79,7 +79,7 @@ COPY ["airlock_processor/requirements.txt", "/tmp/pip-tmp/airlock_processor/"]
RUN pip3 --disable-pip-version-check --no-cache-dir install -r /tmp/pip-tmp/requirements.txt && rm -rf /tmp/pip-tmp

# Install azure-cli
ARG AZURE_CLI_VERSION=2.36.0-1~buster
ARG AZURE_CLI_VERSION=2.37.0-1~buster
COPY .devcontainer/scripts/azure-cli.sh /tmp/
RUN export AZURE_CLI_VERSION=${AZURE_CLI_VERSION} \
&& /tmp/azure-cli.sh
Expand Down
58 changes: 20 additions & 38 deletions devops/scripts/aad/create_api_application.sh
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ if [[ -z "$appName" ]]; then
fi
uxAppName="$appName UX"
appName="$appName API"
currentUserId=$(az ad signed-in-user show --query 'objectId' --output tsv --only-show-errors)
currentUserId=$(az ad signed-in-user show --query 'id' --output tsv --only-show-errors)
tenant=$(az rest -m get -u "${msGraphUri}/domains" -o json | jq -r '.value[] | select(.isDefault == true) | .id')

echo -e "\e[96mCreating the API/UX Application in the \"${tenant}\" Azure AD tenant.\e[0m"
Expand All @@ -112,6 +112,8 @@ source "${DIR}/wait_for_new_app_registration.sh"
source "${DIR}/create_or_update_service_principal.sh"
# shellcheck disable=SC1091
source "${DIR}/get_msgraph_access.sh"
# shellcheck disable=SC1091
source "${DIR}/update_resource_access.sh"

# Generate GUIDS
userRoleId=$(cat /proc/sys/kernel/random/uuid)
Expand All @@ -122,17 +124,17 @@ appObjectId=""
# Get an existing object if it's been created before.
existingApp=$(get_existing_app --name "${appName}")
if [[ -n ${existingApp} ]]; then
appObjectId=$(echo "${existingApp}" | jq -r '.objectId')
appObjectId=$(echo "${existingApp}" | jq -r '.id')
userRoleId=$(echo "$existingApp" | jq -r '.appRoles[] | select(.value == "TREUser").id')
adminRoleId=$(echo "$existingApp" | jq -r '.appRoles[] | select(.value == "TREAdmin").id')
userImpersonationScopeId=$(echo "$existingApp" | jq -r '.oauth2Permissions[] | select(.value == "user_impersonation").id')
userImpersonationScopeId=$(echo "$existingApp" | jq -r '.api.oauth2PermissionScopes[] | select(.value == "user_impersonation").id')
if [[ -z "${userRoleId}" ]]; then userRoleId=$(cat /proc/sys/kernel/random/uuid); fi
if [[ -z "${adminRoleId}" ]]; then adminRoleId=$(cat /proc/sys/kernel/random/uuid); fi
if [[ -z "${userImpersonationScopeId}" ]]; then userImpersonationScopeId=$(cat /proc/sys/kernel/random/uuid); fi
fi

msGraphAppId="00000003-0000-0000-c000-000000000000"
msGraphObjectId=$(az ad sp show --id ${msGraphAppId} --query "objectId" --output tsv --only-show-errors)
msGraphObjectId=$(az ad sp show --id ${msGraphAppId} --query "id" --output tsv --only-show-errors)

roleUserReadAll=$(get_msgraph_role "User.Read.All" )
roleDirectoryReadAll=$(get_msgraph_role "Directory.Read.All" )
Expand Down Expand Up @@ -216,8 +218,8 @@ fi
az ad app owner add --id "${appId}" --owner-object-id "$currentUserId" --only-show-errors

# Create a Service Principal for the app.
spPassword=$(create_or_update_service_principal "${appId}" "${appName}")
spId=$(az ad sp list --filter "appId eq '${appId}'" --query '[0].objectId' --output tsv --only-show-errors)
spPassword=$(create_or_update_service_principal "${appId}")
spId=$(az ad sp list --filter "appId eq '${appId}'" --query '[0].id' --output tsv --only-show-errors)

# needed to make the API permissions change effective, this must be done after SP creation...
echo
Expand Down Expand Up @@ -274,7 +276,7 @@ JSON
# Is the UX app already registered?
existingUXApp=$(get_existing_app --name "${uxAppName}")
if [[ -n ${existingUXApp} ]]; then
uxObjectId=$(echo "${existingUXApp}" | jq -r '.objectId')
uxObjectId=$(echo "${existingUXApp}" | jq -r '.id')
echo "Updating \"${uxAppName}\" with ObjectId \"${uxObjectId}\""
az rest --method PATCH --uri "${msGraphUri}/applications/${uxObjectId}" --headers Content-Type=application/json --body "${uxAppDefinition}"
uxAppId=$(az ad app show --id "${uxObjectId}" --query "appId" --output tsv --only-show-errors)
Expand All @@ -288,11 +290,11 @@ else
fi

# See if a service principal already exists
uxSpId=$(az ad sp list --filter "appId eq '${uxAppId}'" --query '[0].objectId' --output tsv --only-show-errors)
uxSpId=$(az ad sp list --filter "appId eq '${uxAppId}'" --query '[0].id' --output tsv --only-show-errors)

# If not, create a new service principal
if [[ -z "$uxSpId" ]]; then
uxSpId=$(az ad sp create --id "${uxAppId}" --query 'objectId' --output tsv --only-show-errors)
uxSpId=$(az ad sp create --id "${uxAppId}" --query 'id' --output tsv --only-show-errors)
wait_for_new_service_principal "${uxSpId}"
fi

Expand All @@ -307,24 +309,12 @@ az ad app permission grant --id "$uxSpId" --api "$appId" --scope "user_impersona
if [[ -n ${automationAppId} ]]; then
existingAutomationApp=$(get_existing_app --id "${automationAppId}")

automationAppObjectId=$(echo "${existingAutomationApp}" | jq -r .objectId)
automationAppObjectId=$(echo "${existingAutomationApp}" | jq -r .id)
automationAppName=$(echo "${existingAutomationApp}" | jq -r .displayName)
echo "Found '${automationAppName}' with ObjectId: '${automationAppObjectId}'"

# Get the existing required resource access from the automation app,
# but remove the access that we are about to add for idempotency. We cant use
# the response from az cli as it returns an 'AdditionalProperties' element in
# the json
existingResourceAccess=$(az rest \
--method GET \
--uri "${msGraphUri}/applications/${automationAppObjectId}" \
--headers Content-Type=application/json -o json \
| jq -r --arg appId "${appId}" \
'del(.requiredResourceAccess[] | select(.resourceAppId==$appId)) | .requiredResourceAccess' \
)

# Add the existing resource access so we don't remove any existing permissions.
automationApiAccess=$(jq -c . << JSON
# This is the new API Access we require.
automationApiAccess=$(jq -c .requiredResourceAccess << JSON
{
"requiredResourceAccess": [
{
Expand All @@ -340,25 +330,18 @@ if [[ -n ${automationAppId} ]]; then
}
]
}
],
"existingAccess": ${existingResourceAccess}
]
}
JSON
)

# Manipulate the json (add existingAccess into requiredResourceAccess and then remove it)
requiredResourceAccess=$(echo "${automationApiAccess}" | \
jq '.requiredResourceAccess += .existingAccess | {requiredResourceAccess}')

az rest --method PATCH \
--uri "${msGraphUri}/applications/${automationAppObjectId}" \
--headers Content-Type=application/json \
--body "${requiredResourceAccess}"
# Utility function to add the required permissions.
update_resource_access "$msGraphUri" "${automationAppObjectId}" "${appId}" "${automationApiAccess}"

# Grant admin consent for the application scopes
if [[ $grantAdminConsent -eq 1 ]]; then
echo "Granting admin consent for \"${automationAppName}\" (App ID ${automationAppId})"
automationSpId=$(az ad sp list --filter "appId eq '${automationAppId}'" --query '[0].objectId' --output tsv --only-show-errors)
automationSpId=$(az ad sp list --filter "appId eq '${automationAppId}'" --query '[0].id' --output tsv --only-show-errors)
echo "Found Service Principal \"$automationSpId\" for \"${automationAppName}\"."

grant_admin_consent "${automationSpId}" "${spId}" "${adminRoleId}"
Expand All @@ -367,9 +350,8 @@ JSON
fi

# Output the variables for .env files
echo -e "\n\e[96mAAD_TENANT_ID=\"$(az account show --output json | jq -r '.tenantId')\""
echo -e "** Please copy the following variables to /templates/core/.env **"
echo -e "\n\e[33mAPI_CLIENT_ID=\"${appId}\""
echo -e "\n\e[96m** Please copy the following variables to /templates/core/.env **"
echo -e "\e[33mAPI_CLIENT_ID=\"${appId}\""
echo -e "API_CLIENT_SECRET=\"${spPassword}\""
echo -e "SWAGGER_UI_CLIENT_ID=\"${uxAppId}\"\e[0m"

Expand Down
24 changes: 9 additions & 15 deletions devops/scripts/aad/create_application_administrator.sh
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ function show_usage()
{
cat << USAGE
Utility script for creating an application administrator for TRE. This identity is mandatory and is used
to manage AAD Applications within TRE. This script is called when you run "make auth" and
Utility script for creating an application administrator for TRE. This is mandatory and is used
to manage AAD Application creation within TRE. This script is called when you run "make auth" and
the environment variable AUTO_WORKSPACE_APP_REGISTRATION determines the permission this identity has.
You must be logged in using Azure CLI with sufficient privileges to modify Azure Active Directory to run this script.
Expand Down Expand Up @@ -76,7 +76,7 @@ if [[ -z "$appName" ]]; then
show_usage
fi
appName="$appName Application Admin"
currentUserId=$(az ad signed-in-user show --query 'objectId' --output tsv --only-show-errors)
currentUserId=$(az ad signed-in-user show --query 'id' --output tsv --only-show-errors)
tenant=$(az rest -m get -u "${msGraphUri}/domains" -o json | jq -r '.value[] | select(.isDefault == true) | .id')

echo -e "\e[96mCreating the Application Admin in the \"${tenant}\" Azure AD tenant.\e[0m"
Expand All @@ -97,12 +97,12 @@ source "${DIR}/create_or_update_service_principal.sh"
appObjectId=""
existingApp=$(get_existing_app --name "${appName}") || null
if [ -n "${existingApp}" ]; then
appObjectId=$(echo "${existingApp}" | jq -r '.objectId')
appObjectId=$(echo "${existingApp}" | jq -r '.id')
fi

# Get the Required Resource Scope/Role
msGraphAppId="00000003-0000-0000-c000-000000000000"
msGraphObjectId=$(az ad sp show --id ${msGraphAppId} --query "objectId" --output tsv --only-show-errors)
msGraphObjectId=$(az ad sp show --id ${msGraphAppId} --query "id" --output tsv --only-show-errors)

applicationPermissionId=$(az ad sp show --id ${msGraphAppId} --query "appRoles[?value=='${applicationPermission}'].id" --output tsv --only-show-errors)
roleApplicationPermission=$(get_msgraph_role "${applicationPermission}")
Expand Down Expand Up @@ -140,13 +140,8 @@ fi
az ad app owner add --id "${appId}" --owner-object-id "$currentUserId" --only-show-errors

# Create a Service Principal for the app.
spPassword=$(create_or_update_service_principal "${appId}" "${appName}")
spId=$(az ad sp list --filter "appId eq '${appId}'" --query '[0].objectId' --output tsv --only-show-errors)

# needed to make the API permissions change effective, this must be done after SP creation...
echo
echo "Running 'az ad app permission grant' to make changes effective."
az ad app permission grant --id "${appId}" --api "${msGraphAppId}" --only-show-errors
spPassword=$(create_or_update_service_principal "${appId}")
spId=$(az ad sp list --filter "appId eq '${appId}'" --query '[0].id' --output tsv --only-show-errors)

# Grant admin consent on the required resource accesses (Graph API)
if [[ $grantAdminConsent -eq 1 ]]; then
Expand All @@ -155,9 +150,8 @@ if [[ $grantAdminConsent -eq 1 ]]; then
grant_admin_consent "${spId}" "$msGraphObjectId" "${applicationPermissionId}"
fi

echo -e "\n\e[96mAAD_TENANT_ID=\"$(az account show --output json | jq -r '.tenantId')\""
echo -e "** Please copy the following variables to /templates/core/.env **"
echo -e "\n\e[33mAPPLICATION_ADMIN_CLIENT_ID=\"${appId}\""
echo -e "\n\e[96m** Please copy the following variables to /templates/core/.env **"
echo -e "\e[33mAPPLICATION_ADMIN_CLIENT_ID=\"${appId}\""
echo -e "APPLICATION_ADMIN_CLIENT_SECRET=\"${spPassword}\"\e[0m"

if [[ $grantAdminConsent -eq 0 ]]; then
Expand Down
13 changes: 6 additions & 7 deletions devops/scripts/aad/create_automation_administrator.sh
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ if [[ -z "$appName" ]]; then
show_usage
fi
appName="$appName Automation Admin"
currentUserId=$(az ad signed-in-user show --query 'objectId' --output tsv --only-show-errors)
currentUserId=$(az ad signed-in-user show --query 'id' --output tsv --only-show-errors)
tenant=$(az rest -m get -u "${msGraphUri}/domains" -o json | jq -r '.value[] | select(.isDefault == true) | .id')

echo -e "\e[96mCreating the Automation Admin in the \"${tenant}\" Azure AD tenant.\e[0m"
Expand All @@ -79,7 +79,7 @@ appObjectId=""
appId=""
existingApp=$(get_existing_app --name "${appName}") || null
if [ -n "${existingApp}" ]; then
appObjectId=$(echo "${existingApp}" | jq -r '.objectId')
appObjectId=$(echo "${existingApp}" | jq -r '.id')
appId=$(echo "${existingApp}" | jq -r .appId)
fi

Expand Down Expand Up @@ -109,9 +109,8 @@ fi
az ad app owner add --id "${appId}" --owner-object-id "$currentUserId" --only-show-errors

# Create a Service Principal for the app.
spPassword=$(create_or_update_service_principal "${appId}" "${appName}")
spPassword=$(create_or_update_service_principal "${appId}")

echo -e "\n\e[96mAAD_TENANT_ID=\"$(az account show --output json | jq -r '.tenantId')\""
echo -e "** Please copy the following variables to /templates/core/.env **"
echo -e "\n\e[33mTEST_ACCOUNT_CLIENT_ID=\"${appId}\""
echo -e "TEST_ACCOUNT_CLIENT_SECRET=\"${spPassword}\"\e[0m"
echo -e "\n\e[96m** Please copy the following variables to /templates/core/.env **"
echo -e "\e[33mTEST_ACCOUNT_CLIENT_ID=\"${appId}\""
echo -e "TEST_ACCOUNT_CLIENT_SECRET=\"${spPassword}\"\e[0m"
12 changes: 6 additions & 6 deletions devops/scripts/aad/create_or_update_service_principal.sh
Original file line number Diff line number Diff line change
Expand Up @@ -31,22 +31,21 @@ function wait_for_new_service_principal()
function create_or_update_service_principal()
{
applicationId=$1
appName=$2

# See if a service principal already exists
spId=$(az ad sp list --filter "appId eq '${applicationId}'" --query '[0].objectId' --output tsv --only-show-errors)
spId=$(az ad sp list --filter "appId eq '${applicationId}'" --query '[0].id' --output tsv --only-show-errors)

resetPassword=0
REPLY=""

# If not, create a new service principal
if [[ -z "$spId" ]]; then
spId=$(az ad sp create --id "${applicationId}" --query 'objectId' --output tsv --only-show-errors)
spId=$(az ad sp create --id "${applicationId}" --query 'id' --output tsv --only-show-errors)
wait_for_new_service_principal "${spId}"
az ad app owner add --id "${applicationId}" --owner-object-id "${spId}" --only-show-errors
resetPassword=1
else
read -p "Service principal for \"${appName}\" already exists. Do you wish to reset the password. DO NOT PRESS ENTER. (y/N)? " -rN1
read -p "Service principal \"${spId}\" already exists. Do you wish to reset the password. DO NOT PRESS ENTER. (y/N)? " -rN1
if [[ ${REPLY::1} == [Yy] ]]; then
resetPassword=1
fi
Expand All @@ -55,11 +54,12 @@ function create_or_update_service_principal()
spPassword=""

if [[ "$resetPassword" == 1 ]]; then
spPassword=$(az ad sp credential reset --name "${applicationId}" --query 'password' --output tsv --only-show-errors)
spPassword=$(az ad sp credential reset --id "${spId}" --query 'password' --output tsv --only-show-errors)
fi

# This tag ensures the app is listed in "Enterprise applications"
az ad sp update --id "$spId" --set tags="['WindowsAzureActiveDirectoryIntegratedApp']" --only-show-errors
# az ad sp update --id "$spId" --set tags="['WindowsAzureActiveDirectoryIntegratedApp']" --only-show-errors
# Doesn't work in AZ CLI 2.37 - do we still need it?

echo "${spPassword}"
}
Loading

0 comments on commit bdb5e6e

Please sign in to comment.