Information in this document, including URL and other Internet Web site references, is subject to change without notice. Unless otherwise noted, the example companies, organizations, products, domain names, e-mail addresses, logos, people, places, and events depicted herein are fictitious, and no association with any real company, organization, product, domain name, e-mail address, logo, person, place or event is intended or should be inferred. Complying with all applicable copyright laws is the responsibility of the user. Without limiting the rights under copyright, no part of this document may be reproduced, stored in or introduced into a retrieval system, or transmitted in any form or by any means (electronic, mechanical, photocopying, recording, or otherwise), or for any purpose, without the express written permission of Microsoft Corporation.
Microsoft may have patents, patent applications, trademarks, copyrights, or other intellectual property rights covering subject matter in this document. Except as expressly provided in any written license agreement from Microsoft, the furnishing of this document does not give you any license to these patents, trademarks, copyrights, or other intellectual property.
The names of manufacturers, products, or URLs are provided for informational purposes only and Microsoft makes no representations and warranties, either expressed, implied, or statutory, regarding these manufacturers or the use of the products with any Microsoft technologies. The inclusion of a manufacturer or product does not imply endorsement of Microsoft of the manufacturer or product. Links may be provided to third party sites. Such sites are not under the control of Microsoft and Microsoft is not responsible for the contents of any linked site or any link contained in a linked site, or any changes or updates to such sites. Microsoft is not responsible for webcasting or any other form of transmission received from any linked site. Microsoft is providing these links to you only as a convenience, and the inclusion of any link does not imply endorsement of Microsoft of the site or the products contained therein.
© 2020 Microsoft Corporation. All rights reserved.
Contents
- Cloud-native applications before the hands-on lab setup guide
- Requirements
- Before the hands-on lab
- Task 1: Setup Azure Cloud Shell
- Task 2: Download Starter Files
- Task 3: Resource Group
- Task 4: Create an SSH key
- Task 5: Create a Service Principal
- Task 6: Deploy ARM Template
- Task 7: Setup Azure DevOps project
- Task 8: Connect securely to the build agent
- Task 9: Complete the build agent setup
- Task 10: Clone Repositories to the Build Agent
-
Microsoft Azure subscription must be pay-as-you-go or MSDN.
-
Trial subscriptions will not work.
-
To complete this lab setup (including Task 5: Create a Service Principal) ensure your account includes the following:
-
Has the Owner built-in role for the subscription you use.
-
Is a Member user in the Azure AD tenant you use. (Guest users will not have the necessary permissions).
Note If you do not meet these requirements, ask another member user with subscription owner rights to login to the portal and execute the task to create the service principal.
-
-
You must have enough cores available in your subscription to create the build agent and Azure Kubernetes Service cluster in Task 6: Deploy ARM Template. You'll need eight cores if following the exact instructions in the lab, more if you choose additional agents or larger VM sizes. Execute the steps required before the lab to see if you need to request more cores in your sub.
-
-
An account in Azure DevOps.
-
Local machine or a virtual machine configured with:
- A browser, preferably Chrome for consistency with the lab implementation tests.
-
You will be asked to install other tools throughout the exercises.
Duration: 1 hour
You should follow all of the steps provided in this section before taking part in the hands-on lab ahead of time as some of these steps take time.
-
Open a cloud shell by selecting the cloud shell icon in the menu bar.
-
The cloud shell opens in the browser window. Choose "Bash" if prompted or use the left-hand dropdown on the shell menu bar to choose "Bash" (as shown).
-
You should make sure to set your default subscription correctly. To view your current subscription type:
az account show
-
To list all of your subscriptions, type:
az account list
-
To set your default subscription to something other than the current selection, type the following, replacing {id} with the desired subscription id value:
az account set --subscription {id}
In this task, you use git
to copy the lab content to your cloud shell so that the lab starter files will be available.
Note: If you don't have a cloud shell available, refer back to Task 1: Setup Azure Cloud Shell.
-
Type the following command and press
<ENTER>
:git clone https://github.com/microsoft/MCW-Cloud-native-applications.git
-
The lab files download.
-
We do not need the
.git
folder, and later steps will be less complex if we remove it. Run this command:rm -rf MCW-Cloud-native-applications/.git
Create an Azure Resource Group to hold most of the resources that you create in this hands-on lab. This approach makes it easier to clean up later.
-
In your cloud shell window, you type a command similar to the following command:
Note: If you don't have a cloud shell available, refer back to Task 1: Setup Azure Cloud Shell.
az group create -l [LOCATION] -n fabmedical-[SUFFIX]
-
Suffix: Throughout the lab, suffix should be used to make resources unique, like your email prefix or your first initial and last name.
-
Location: Choose a region where all Azure Container Registry SKUs have to be available, which is currently: Canada Central, Canada East, North Central US, Central US, South Central US, East US, East US 2, West US, West US 2, West Central US, France Central, UK South, UK West, North Europe, West Europe, Australia East, Australia Southeast, Brazil South, Central India, South India, Japan East, Japan West, Korea Central, Southeast Asia, East Asia, and remember this for future steps so that the resources you create in Azure are all kept within the same region.
Example:
az group create -l westus -n fabmedical-sol
-
-
When this completes, the Azure Portal shows your Resource Group.
You create VMs during the upcoming exercises. In this section, you create an SSH key to access the VMs securely.
-
From the cloud shell command line, enter the following command to ensure that a directory for the SSH keys exists. You can ignore any errors you see in the output.
Note: If you don't have a cloud shell available, refer back to Task 1: Setup Azure Cloud Shell.
mkdir .ssh
-
From the cloud shell command line, enter the following command to generate an SSH key pair. You can replace "admin" with your preferred name or handle.
ssh-keygen -t RSA -b 2048 -C admin@fabmedical
-
When asked to save the generated key to a file, enter
.ssh/fabmedical
for the name. -
Enter a passphrase when prompted, and don't forget it!
-
Because you entered ".ssh/fabmedical", ssh-keygen generates the file in the ".ssh" folder in your user folder, where the cloud shell opens by default.
-
From the cloud shell command line, enter the following command to output the public key content. Copy this information to use later.
cat .ssh/fabmedical.pub
-
Keep this cloud shell open and remain in the default directory. You will use this shell in later tasks.
Azure Kubernetes Service requires an Azure Active Directory service principal to interact with Azure APIs. The service principal is needed to dynamically manage resources such as user-defined routes and the Layer 4 Azure Load Balancer. The easiest way to set up the service principal is by using the Azure cloud shell.
Note: To complete this task, ensure your account is an Owner built-in role for the subscription you use and is a Member user in the Azure AD tenant you use. You may have trouble creating a service principal if you do not meet these requirements.
-
To create a service principal, type the following command in the cloud shell command line, replacing {id} with your subscription identifier, and replacing suffix with your chosen suffix to make the name unique:
Note: If you don't have a cloud shell available, refer back to Task 1: Setup Azure Cloud Shell.
az ad sp create-for-rbac --role="Contributor" --scopes="/subscriptions/{id}" --name="http://Fabmedical-sp-{SUFFIX}"
-
The command produces output like this. Copy this information to use later.
-
To get the service principal object id, type the following command, replacing {appId} with your service principal appId:
az ad sp show --id {appId} --query "{objectId:@.objectId}"
-
The command produces output like this. Copy this information to use later.
In this section, you configure and execute an ARM template that creates all the resources that you need throughout the exercises.
-
In Azure cloud shell, switch to the ARM template directory:
Note: If you don't have a cloud shell available, refer back to Task 1: Setup Azure Cloud Shell.
cd MCW-Cloud-native-applications/Hands-on\ lab/arm/
-
Open the azuredeploy.parameters.json file for editing using Azure Cloud Shell editor.
code azuredeploy.parameters.json
-
Update the values for the various keys so that they match your environment:
- Suffix: Enter a shortened version of your SUFFIX with a max of 3 chars.
- VirtualMachineAdminUsernameLinux: The Linux Build Agent VM admin username (example:
"adminfabmedical"
). - VirtualMachineAdminPublicKeyLinux: The Linux Build Agent VM admin ssh public key. You find this value in the
.ssh/fabmedical.pub
file created previously (example:"ssh-rsa AAAAB3N(...)vPiybQV admin@fabmedical"
). - KubernetesServicePrincipalClientId: The Kubernetes Cluster Service Principal Client Id. Use the service principal “appId” from a previous step.
- KubernetesServicePrincipalClientSecret: The Kubernetes Cluster Service Principal Client Secret. Use the service principal “password” from a previous step.
- KubernetesServicePrincipalObjectId: The Kubernetes Cluster Service Principal Object Id. Use the service principal “objectId” from a previous step.
- CosmosLocation: The primary location of the Azure Cosmos DB. Use the same location as the resource group previously created (example:
"eastus"
). - CosmosLocationName: The name of the primary location of the Azure Cosmos DB. Use the name of the same location as the resource group previously created (example:
"East US"
). - CosmosPairedLocation: The secondary location of the Azure Cosmos DB. Use a location from the list below (example:
"westus"
). - CosmosPairedLocationName: The name of the secondary location of the Azure Cosmos DB. Use the location name from the list below that matches the secondary location defined in the previous key (example:
"West US"
).
Location Location Name canadacentral Canada Central canadaeast Canada East northcentralus North Central US centralus Central US southcentralus South Central US eastus East US eastus2 East US 2 westus West US westus2 West US 2 westcentralus West Central US francecentral France Central uksouth UK South ukwest UK West northeurope North Europe westeurope West Europe australiaeast Australia East australiasoutheast Australia Southeast brazilsouth Brazil South centralindia Central India southindia South India japaneast Japan East japanwest Japan West koreacentral Korea Central southeastasia Southeast Asia eastasia East Asia -
Select the ... button and select Save.
-
Select the ... button again and select Close Editor.
-
Create the needed resources by typing the following instruction (case sensitive), replacing {resourceGroup} with the name of the previously created resource group:
az deployment group create --resource-group {resourceGroup} --template-file azuredeploy.json --parameters azuredeploy.parameters.json
This command takes up to 30 to 60 minutes to deploy all lab resources. You can continue to the next task to setup Azure DevOps while the deployment runs.
FabMedical has provided starter files for you. They have taken a copy of the websites for their customer Contoso Neuro and refactored it from a single node.js site into a website with a content API that serves up the speakers and sessions. This refactored code is a starting point to validate the containerization of their websites. Use this to help them complete a POC that validates the development workflow for running the website and API as Docker containers and managing them within the Azure Kubernetes Service environment.
-
Open a new Azure Cloud Shell console.
-
Navigate to the FabMedical source code folder and list the contents.
cd ~/MCW-Cloud-native-applications/Hands-on\ lab/lab-files/developer/ ll
Important note: If you will be taking the Infrastructure edition of the lab, instead of using the above instructions, type the following ones:
cd ~/MCW-Cloud-native-applications/Hands-on\ lab/lab-files/infrastructure/ ll
This will take you to the version of the starter files that will be used by that edition of the lab.
-
You'll see the listing includes three folders, one for the web site, another for the content API and one to initialize API data:
content-api/ content-init/ content-web/
-
Set your username and email, which git uses for commits.
git config --global user.email "[email protected]" git config --global user.name "Your Name"
-
Configure git CLI to cache your credentials, so that you don't have to keep re-typing them.
git config --global credential.helper cache
-
Open a new browser tab to visit Azure DevOps and log into your account.
If you have never logged into this account, Azure DevOps takes you through a first-run experience:
- Confirm your contact information and select next.
- Select "Create new account".
- Enter a fabmedical-SUFFIX for your account name and select Continue.
-
Create an Azure DevOps Project.
- Enter fabmedical as the project name.
- Ensure the project is Private.
- Choose the "Advanced" dropdown.
- Ensure the Version control is set to Git.
- Select the "Create" button.
-
Enable multi-stage pipelines:
- Select your user icon in the top right corner.
- Then choose the three dots to access the "Preview Features" menu item.
- Toggle multi-stage pipelines to "On".
-
Next, add an Azure Service Connection to your Azure DevOps account. Select the Project settings gear icon to access your settings. Then select Service Connections.
-
Choose "+ New service connection". Then pick "Azure Resource Manager" from the menu.
-
Select the link indicated in the screenshot below to access the advanced settings.
-
Enter the required information using the service principal information you created earlier.
- Connection name: azurecloud
- Environment: AzureCloud
- Scope Level: Subscription
- Subscription ID: Enter
id
fromaz account show
output. - Subscription name: Enter
name
fromaz account show
output. - Service principal client ID: Enter
appId
from service principal output. - Service principal key: Enter
password
from service principal output. - Tenant ID: Enter
tenant
from service principal output.
-
Select "Verify connection" then select "OK".
Note: If the connection does not verify, then recheck and reenter the required data.
-
Next, add another Azure Service Connection to your Azure DevOps account. Select the Project settings gear icon to access your settings. Then choose Service Connections.
-
Choose "+ New service connection". Then pick "Docker Registry" from the menu.
-
Enter the required information using the service principal information you created earlier.
-
Environment: Azure Container Registry
-
Connection name: Fabmedical ACR
-
Azure Subscription: Choose the subscription you are using for the lab.
-
Azure Container Registry: Choose the registry created for you by the ARM deployment.
-
-
Select "OK".
-
Next, choose "Repos" then use the repository dropdown to create a new repository by selecting "+ New repository".
-
Enter "content-web" as the repository name.
-
Once Azure DevOps creates the repository, select "Generate Git credentials".
-
-
Copy the Personal Access Token and save it for later steps.
-
Using your cloud shell window, initialize a new git repository for
content-web
.cd content-web git init git add . git commit -m "Initial Commit"
-
Return to your Azure DevOps tab and copy the commands to add your Azure DevOps repository as a new remote for push. Copy the commands for "HTTPS" similar to this example:
git remote add origin https://[email protected]/fabmedical-sol/fabmedical/_git/content-web git push -u origin --all
-
Now use the commands copied from Azure DevOps to configure the remote repository and push the code to Azure DevOps. When prompted for a password, paste your Azure DevOps Personal Access Token you copied earlier in this task.
-
Return to Azure DevOps and use the repository dropdown to create a second repository called
content-api
.Note: You do not need to generate git credentials again. The same PAT works for both repositories.
-
Using your cloud shell window, initialize a new git repository in the
content-api
directory.cd ../content-api git init git add . git commit -m "Initial Commit"
-
Copy the commands to add your
content-api
repository as a new remote for push. Copy the commands for "HTTPS". -
Now use the commands copied from Azure DevOps to configure the remote repository and push the code to Azure DevOps. If prompted for a password, paste your Azure DevOps Personal Access Token you copied earlier in this task.
-
Use the repository drop down to create a third repository called
content-init
.Note: You do not need to generate git credentials again. The same PAT works for both repositories.
-
Using your cloud shell window, initialize a new git repository in the
content-init
directory.cd ../content-init git init git add . git commit -m "Initial Commit"
-
Copy the commands to add your
content-init
repository as a new remote for push. Copy the commands for "HTTPS". -
Now use the commands copied from Azure DevOps to configure the remote repository and push the code to Azure DevOps. If prompted for a password, paste your Azure DevOps Personal Access Token you copied earlier in this task.
In this section, you validate that you can connect to the new build agent VM.
-
Open a new Azure Cloud Shell console and run the following command to find the IP address for the build agent VM provisioned when you ran the ARM deployment:
Note: If you don't have a cloud shell available, refer back to Task 1: Setup Azure Cloud Shell.
az vm show -d -g fabmedical-[SUFFIX] -n fabmedical-[SHORT_SUFFIX] --query publicIps -o tsv
Example:
az vm show -d -g fabmedical-sol -n fabmedical-SOL --query publicIps -o tsv
-
In the cloud shell output, take note of the public IP address for the VM.
-
Connect to the new VM you created by typing the following command:
ssh -i [PRIVATEKEYNAME] [BUILDAGENTUSERNAME]@[BUILDAGENTIP]
Replace the bracketed values in the command as follows:
-
[PRIVATEKEYNAME]: Use the private key name ".ssh/fabmedical," created above.
-
[BUILDAGENTUSERNAME]: Use the username for the VM, such as adminfabmedical.
-
[BUILDAGENTIP]: The IP address for the build agent VM, retrieved in the previous step.
ssh -i .ssh/fabmedical [email protected]
-
-
When asked to confirm if you want to connect, as the authenticity of the connection cannot be validated, type "yes".
-
When asked for the passphrase for the private key you created previously, enter this value.
-
SSH connects to the VM and displays a command prompt such as the following. Keep this cloud shell window open for the next step:
adminfabmedical@fabmedical-SUFFIX:~$
Note: If you have issues connecting, you may have pasted the SSH public key incorrectly in the ARM template. Unfortunately, if this is the case, you will have to recreate the VM and try again.
In this task, you update the packages and install the Docker engine.
-
Go to the cloud shell window that has the SSH connection open to the build agent VM.
-
Update the Ubuntu packages and install curl and support for repositories over HTTPS in a single step by typing the following in a single line command. Respond by typing "Y" and pressing enter, if asked if you would like to proceed.
sudo apt-get update && sudo apt install apt-transport-https ca-certificates curl software-properties-common
-
Add Docker's official GPG key by typing the following in a single line command:
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
-
Add Docker's stable repository to Ubuntu packages list by typing the following in a single line command:
sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
-
Add NodeJs PPA to use NodeJS LTS release and update the Ubuntu packages and install Docker engine, node.js, and the node package manager by typing the following commands, each on their own line. If asked if you would like to proceed, respond by typing "Y" and pressing enter.
sudo apt-get install curl python-software-properties curl -sL https://deb.nodesource.com/setup_12.x | sudo -E bash - sudo apt-get update && sudo apt-get install -y docker-ce nodejs mongodb-clients
-
Now, upgrade the Ubuntu packages to the latest version by typing the following in a single line command. If asked if you would like to proceed, respond by typing "Y" and pressing enter.
sudo apt-get upgrade
-
Install
docker-compose
sudo curl -L https://github.com/docker/compose/releases/download/1.21.2/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose sudo chmod +x /usr/local/bin/docker-compose
-
When the command has completed, check the Docker version installed by executing this command. The output may look something like that shown in the following screenshot. Note that the server version is not shown yet, because you didn't run the command with elevated privileges (to be addressed shortly).
docker version
-
You may check the versions of node.js and npm as well, just for information purposes, using these commands:
nodejs --version npm -version
-
Install the Angular CLI.
sudo npm install -g @angular/cli
-
To remove the requirement to use sudo, add your user to the Docker group. You can ignore any errors you see in the output.
sudo usermod -aG docker $USER
-
For the user permission changes to take effect, exit the SSH session by typing 'exit', then press <Enter>. Reconnect to the build agent VM using SSH as you did in the previous task.
-
Repeat the Docker version command, and note the output now shows the server version as well.
-
Run a few Docker commands:
-
One to see if there are any containers presently running.
docker container ls
-
One to see if any containers exist, whether running or not.
docker container ls -a
-
-
In both cases, you have an empty list but no errors while running the command. Your build agent is ready with the Docker engine running correctly.
In this task, you clone your repositories from Azure DevOps so you can work with them on the build agent.
-
As you previously did in cloud shell, set your username and email which are used for git commits.
git config --global user.email "[email protected]" git config --global user.name "Your Name"
Note: In some cases, the
root
user owns your user's.config
folder. If this happens, run the following command to return ownership toadminfabmedical
and then try thegit
command again:sudo chown -R $USER:$(id -gn $USER) /home/adminfabmedical/.config
-
Configure git CLI to cache your credentials, so that you don't have to keep re-typing them.
git config --global credential.helper cache
Note: In some cases, the
root
user owns your user's.config
folder. If this happens, run the following command to return ownership toadminfabmedical
and then try thegit
command again:sudo chown -R $USER:$(id -gn $USER) /home/adminfabmedical/.config
-
Visit the
content-web
repository in Azure DevOps and select "Clone" in the right corner. -
Copy the repository URL.
-
Use the repository URL to clone the content-web code to your build agent machine.
git clone <REPOSITORY_URL>
Note: In some cases, the
root
user owns your user's.config
folder. If this happens, run the following command to return ownership toadminfabmedical
and then try thegit
command again:sudo chown -R $USER:$(id -gn $USER) /home/adminfabmedical/.config
-
When prompted for a password, use your PAT token from previous steps.
-
In your browser, switch to the
content-api
repository and select "Clone" to see and copy the repository URL. -
Use the repository URL and
git clone
to copy the content-api code to your build agent. -
In your browser, switch to the
content-init
repository and select "Clone" to see and copy the repository URL. -
Use the repository URL and
git clone
to copy the content-init code to your build agent.
Note: Keep this cloud shell window open as your build agent SSH connection. The lab instructs you to open additional cloud shell sessions as and when needed.
You should follow all steps provided before performing the Hands-on lab.