These exercises require that several software packages have been installed:
\begin{itemize}
\item Git Bash.
\item Python 3.11, where python and pip should be in the \texttt{PATH}.
\item Azure command-line client.
\item Visual Studio Code.
\item Visual Studio Code ``Python'' extension, with Extension ID ``ms-python.python''.
\end{itemize}
\subsection{Azure command-line interface}
The Azure command-line interface (CLI) should be installed by following the instructions that are given at \href{https://docs.microsoft.com/en-us/cli/azure/install-azure-cli}{https://docs.microsoft.com/en-us/cli/azure/install-azure-cli}.
\subsection{Bash}
This document discusses the examples using the Bash shell. The Bash shell environment is normally part of a Linux or OSX installation. Bash is not installed on Microsoft Windows by default, but is available on Linux and OSX. Bash can be installed on Windows by installing Git for Windows from \href{https://gitforwindows.org/}{https://gitforwindows.org/}.
\section{Student account}
...
...
@@ -107,12 +108,8 @@ The CIS Azure teaching environment provides shared services and personalised acc
When a student account is created in the teaching environment, a matching service principal is created to allow authentication from DevOps. These service accounts are associated with each student and their resources.
\section{Azure CLI and account}
Before using the Azure CLI, the CLI should be associated with an Azure account and subscription. The CLI can be used from Bash, PowerShell and a Windows command prompt. The documentation discusses the CLI using Bash or PowerShell, where Bash is discussed in this document.
\begin{enumerate}
\item Open a Bash shell window, using a terminal window or Git Bash for windows.
\item Open a command prompt or PowerShell window.
\item Type the command that is given in Listing~\ref{listing:account-list} to list account information. An empty list is returned if the user has not logged in. If the user has logged in, the available subscriptions are provided.
\begin{lstlisting}[caption={Checking the login status.},label=listing:account-list,numbers=none,showspaces=true]]
az account list
...
...
@@ -122,9 +119,10 @@ az account list
\begin{lstlisting}[caption={Logging into Azure.},label=listing:az-login,numbers=none,showspaces=true]]
az login
\end{lstlisting}
A web browser window should appear. When prompted, choose the account that is associated with the subscriptions or login by providing a user name and password. If this is successful, a list of available subscriptions should be returned at the command line. It is not necessary to login from each command prompt window. The login details are cached for the user as a whole. Therefore, they are available when another command prompt window is opened.
\item Type the command that is given in Listing~\ref{listing:set-subscription}, where the text \texttt{<subscription name/id>} should be replaced with a subscription name or subscription id. This sets the default subscription for following commands.
\item When prompted, choose provide the user name and password that is associated with the teaching account.
\item If multiple account credentials are present on the local PC, the default subscription can be selected using the command given in Listing~\ref{listing:set-subscription}.
\begin{lstlisting}[caption={Setting the default Azure subscription.},label=listing:set-subscription,numbers=none,showspaces=true]]
az account set -s <subscription name/id>
...
...
@@ -132,14 +130,23 @@ az account set -s <subscription name/id>
\end{enumerate}
\section{Cloning the exercises \label{section:clone}}
\begin{itemize}
\item Open a Git Bash shell window.
\item Clone the repository that contains the exercises by typing the command that is given in Listing~\ref{listing:git-clone} on one line.
\begin{lstlisting}[caption={Cloning the exercises.},label=listing:git-clone,numbers=none,language=Bash,showspaces=true]
\section{Creating a DevOps project \label{section:create-project}}
The CIS teaching account can be used to login into DevOps, create a organisation and create a project. One organisation can contain zero or more projects. A project contains Boards, Repos, Pipelines, Test Plans and Artifacts. Other developers can be invited to contribute to projects.
DevOps contains organisations, which include zero or more projects. Each project contains Boards, Repos, Pipelines, Test Plans and Artifacts. Other developers can be invited to contribute to projects.
\begin{enumerate}
\item Open a browser and go to \href{https://dev.azure.com/}{https://dev.azure.com/}.
\item Click on ``Sign in to Azure DevOps''.
\item Provide your ``@strathcisedu.onmicrosoft.com'' email address, together with the associated password.
\item Open a browser and go to \href{https://aex.dev.azure.com/}{https://aex.dev.azure.com/}.
\item Provide the email address and password that is associated with the teaching account.
\item Create a new organisation, using the default name.
\item Create a project.
\begin{itemize}
...
...
@@ -166,37 +173,25 @@ Add a simple Python web service to a DevOps Git repository:
\begin{enumerate}
\item Within the DevOps project, click on``Repos''.
\item Scroll down to ``Initialize main branch with a README or gitignore'', click on ``Add a .gitignore'', select ``Python'' and click on ``Initialize''. Python is used in this case, since the example program is written in Python. The \texttt{.gitignore} file can be updated afterwards.
\item Clone the repository to the local directory by clicking on the ``Clone'' button. Then either use the HTTPS or SSH connection method. An example clone operation is given in Listing~ref{listing:git-clone}.
\begin{lstlisting}[caption={Cloning a DevOps Git repository.},label=listing:git-clone,numbers=none,language=bash,showspaces=true]]
Using HTTPS causes an authentication window to appear. The account details used to create the DevOps organisation should be entered into this Window. The authentication decision is cached locally.
\item Click on the ``Clone'' button.
\item Copy the HTTPS URL.
\item Open a Git Bash window.
\item Type \texttt{git clone}, paste the Git URL and press enter.
\item If prompted to do so, provide the teaching account user name used to create the DevOps organisation. The authentication decision is cached locally.
\itemIn the \texttt{FlaskWebSvc} directory, create a new file named \texttt{app.py} that contains the Python that is given in Listing~\ref{listing:flask-hello-world}.
\itemFrom the Git Bash window, copy the files from the \texttt{azure-devops-builds} directory to clone of the DevOps repository as suggested in Listing~\ref{listing:cp-files}.
\begin{lstlisting}[caption={The quickstart Flask application, provided by the Flask documentation team.},label=listing:flask-hello-world,numbers=none,language=python,showspaces=true]]
from flask import Flask
app = Flask(__name__)
@app.route("/")
def hello_world():
return "<p>Hello, World!</p>"
\begin{lstlisting}[caption={Copying files into the DevOps repository.},label=listing:cp-files,numbers=none, language=,showspaces=true]]
\item In the \texttt{FlaskWebSvc} directory, create a new file named \texttt{requirements.txt} that contains the text given in Listing~\ref{listing:requirements-flask}.
\begin{lstlisting}[caption={A requirements file with the Flask version.},label=listing:requirements-flask,numbers=none,showspaces=true]]
Flask>=2
\end{lstlisting}
\item Copy the file \texttt{src/simple-app-build.yml} from this repository into the \texttt{FlaskWebSvc} directory and rename it as \texttt{azure-pipelines.yml}. This file is needed in Section~\ref{section:configuring-build}.
\item Opening a command prompt or Bash window in the \texttt{FlaskWebSvc} directory, add the files to the Git repository and push them back to DevOps, using Listing~\ref{listing:git-push}.
\item Add, commit and push the files to the DevOps respository following the commands given in Listing~\ref{listing:git-push}.
\begin{lstlisting}[caption={Adding files to a DevOps Git repository.},label=listing:git-push,numbers=none,language=bash,showspaces=true]]
@@ -213,17 +208,18 @@ To allow a DevOps project to connect to Azure resources:
\item Under ``Pipelines'', click on ``Service connections''. The ``Service connections'' menu option is illustrated in Figure~\ref{figure:service-connections}.
\item Click on ``Create service connection''.
\item Select ``Azure Resource Manager'', scroll down to the end of the options and click on ``Next''. The ``Azure Resource Manager'' option is illustrated in Figure~\ref{figure:new-service-connection}.
\item Select ``Service principal (manual)'' and click on ``Next''. The options are illustrated in Figure~\ref{figure:az-resource-connection}.
\item Complete the connection settings, using the service principal settings that have been issued for the Azure teaching environment:
\begin{itemize}
\item Identity type - ``App registration or managed identity (manual)''.
\item Credential - ``Secret''.
\item Environment - ``Azure Cloud''.
\item Scope Level - ``Subscription''.
\item Subscription Id - Taken from Listing~\ref{listing:account-list} or the service principal details. It should be the value that is associated with the Azure teaching environment.
\item Subscription Name - Taken from Listing~\ref{listing:account-list} or the service principal details. It should be the value that is associated with the Azure teaching environment and the ``Subscription Id''.
\item Service Principal Id - Taken from the service principal details.
\item Subscription ID - associated with Azure teaching environment.
\item Subscription name - associated with Azure teaching environment.
\item Application (client) ID - Service Principal Id.
\item Directory (tenant) ID - associated with Azure teaching environment.
\item Credential - ``Service principal key''.
\item Service principal key - Taken from the service principal details.
\item Tenant ID - Taken from Listing~\ref{listing:account-list} or the service principal details.. It should be the value that is associated with the Azure teaching environment and the ``Subscription Id''.
\item Client secret - Service Principal Key value.
\item Click on ``Verify'' to verify the connection information. This should report ``Verification Succeeded''.
\item Service connection name - Taken from the service principal name or use a shortened version, such as ``sp-DevOps''.
\item Select ``Grant access permission to all pipelines''.
...
...
@@ -246,18 +242,11 @@ To allow a DevOps project to connect to Azure resources:
\caption{New service connection options.\label{figure:new-service-connection}}
\caption{Azure Resource Manager service connection options.\label{figure:az-resource-connection}}
\end{figure}
\clearpage
\section{Requesting a free build agent}
A build pipeline must be associated with a build agent. While it is possible to pay for a build agent, Microsoft provide a free build agent that can be used for a limited number of software build processes. To use the free build agent, complete the build agent request form at \href{https://aka.ms/azpipelines-parallelism-request}{https://aka.ms/azpipelines-parallelism-request}, providing your name, a university email address, the DevOps organisation name that is associated with your Azure teaching account, and select private use. An example complete form is shown in Figure~\ref{figure:parallelism-request}. It may take between one to three days for the request to be granted.
A build pipeline must be associated with a build agent. While it is possible to pay for a build agent, Microsoft provide a free build agent that can be used for a limited number of software build processes. To use the free build agent, complete the build agent request form at \href{https://aka.ms/azpipelines-parallelism-request}{https://aka.ms/azpipelines-parallelism-request}, providing your name, a university email address, the DevOps organisation name that is associated with your Azure teaching account, and select private use. An example complete form is shown in Figure~\ref{figure:parallelism-request}. It may take between four to five business days for the request to be granted.
\begin{figure}[h!]
\begin{center}
...
...
@@ -271,21 +260,37 @@ A build pipeline must be associated with a build agent. While it is possible to
\section{Configuring a DevOps pipeline \label{section:configuring-build}}
\subsection{Creating a Web App}
A Python web service can be deployed into an Azure Web App. The Web App could be created as part of the DevOps build deployment process or be created beforehand. To simplify the build process, create the Web App using Listing~\ref{listing:create-web-app}. This command assumes that the shared App Service Plan in the teaching environment is used to deploy the Web App and that the Bash variables have already been set appropriately.
\begin{lstlisting}[caption={Commands to create a Web App.},label=listing:create-web-app,numbers=none,language=bash,showspaces=true]]
az webapp create --name $app_name --resource-group $resource_group \
--plan $plan_name --runtime "python|3.9"
A Python web service can be deployed into an Azure Web App. The Web App can be created during the DevOps build process or beforehand.
\begin{enumerate}
\item Open a PowerShell window.
\item Find the \texttt{name} of the Azure teaching environment App Service Plan by reading the documentation for the teaching environment or by using Listing~\ref{listing:list-asp} where \texttt{services\_group} is the resource group that contains the shared services.
\begin{lstlisting}[caption={List the \texttt{id} of the shared App Service Plan, using PowerShell back tick line continuation characters.},label=listing:list-asp,numbers=none,language=bash,showspaces=true]]
az appservice plan list --resource-group $services_group `
--query "[].{plan_name:name,plan_id:id}"
\end{lstlisting}
\item Create a Web App using Listing~\ref{listing:create-web-app}, where \texttt{resource\_group} is the student resource group and \texttt{plan\_name} is the name of the shared App Service Plan.
\begin{lstlisting}[caption={Commands to create a Web App, using PowerShell back tick line continuation characters.},label=listing:create-web-app,numbers=none,language=bash,showspaces=true]]
az webapp create --name $app_name --resource-group $resource_group `
--plan $plan_name --runtime "python:3.11"
\end{lstlisting}
\end{enumerate}
\subsection{Using an existing service principal}
DevOps pipelines are expressed as YAML configuration files. DevOps provides a graphical user interface (GUI) that allows a used to create a complete YAML file. However, the GUI interface currently does not accept an existing service connection, such as the service connection that is discussed in Section~\ref{section:authentication}. To use an existing service connection, the YAML file has to be directly edited. To speed up this process, a template file named \texttt{src/simple-app-build.yml} is provided in this repository.
To create a build pipeline to deploy the Python web service to the Web App:
\begin{enumerate}
\item Click on ``Pipelines''.
\item Click on ``Azure Repos Git''.
\item Select the ``FlaskWebSvc'' repository.
\item Click on ``Repos''.
\item Click on ``Set up build''.
\item Then use the web browser editor to edit the \texttt{azure-pipelines.yml} file.
\begin{itemize}
\item\texttt{environmentName} - should be set to the Web App name that was used when the Web App was created using Listing~\ref{listing:create-web-app}.