Skip to content

Commit

Permalink
PR - review cicd workflow for aro (Azure-Samples#17)
Browse files Browse the repository at this point in the history
* changes for aro cluster

* change secret name

* rename variable rpObjectId

* disable resourceGroupId warning

* add aro connection

* comment bicep file

* change password

* change password variable

* update workflow

* add variable _ImageUrlApp_

* add conditional for create secret

* remove comment lines

* update readme file

* changes docs
  • Loading branch information
leandromsft authored Feb 2, 2023
1 parent bf8dfbb commit 3dcf935
Show file tree
Hide file tree
Showing 11 changed files with 199 additions and 82 deletions.
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: k8s-aspnetcore.deployment
name: aks-aspnetcore.deployment

on: workflow_dispatch

Expand Down
112 changes: 74 additions & 38 deletions .github/workflows/aro-aspnetcore-deployment.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@ on: workflow_dispatch
# branches: [ main ]

env:
AZ_RG_NAME: 'rg-dotnetcontainerapp'
AZ_RG_NAME: 'rg-dotnetcontainerapp-aro'
AZ_RG_LOCATION: 'eastus'
AZ_ACR_NAME: 'acrdotnetcontainerapp'
AZ_AKS_NAME: 'aksdotnetcontainerapp'
AZ_ARO_NAME: 'arodotnetcontainerapp'
AZ_SQLSERVER_NAME: 'sqldotnetcontainerapp'
AZ_KV_NAME: 'kvdotnetcontainerap'
AZ_LOADTEST_NAME: 'ltstdotnetcontainerap'
Expand Down Expand Up @@ -42,15 +42,15 @@ jobs:
fi
# Deploy Bicep file
- name: Deploy Template
uses: Azure/arm-deploy@v1
with:
resourceGroupName: ${{ env.AZ_RG_NAME }}
region: ${{ env.AZ_RG_LOCATION }}
template: src/ContainerApp.IAC/main.bicep
deploymentMode: Incremental
deploymentName: 'gh-actions'
parameters: acrName=${{ env.AZ_ACR_NAME }} clusterName=${{ env.AZ_AKS_NAME }} sqlserverName=${{ env.AZ_SQLSERVER_NAME }} sqlAdminLogin=${{ secrets.AZURE_SQL_USERNAME }} sqlAdminPassword=${{ secrets.AZURE_SQL_PASSWORD }} kvName=${{ env.AZ_KV_NAME }} loadTestName=${{ env.AZ_LOADTEST_NAME }}
#- name: Deploy Template
# uses: Azure/arm-deploy@v1
# with:
# resourceGroupName: ${{ env.AZ_RG_NAME }}
# region: ${{ env.AZ_RG_LOCATION }}
# template: src/ContainerApp.IAC/aro.bicep
# deploymentMode: Incremental
# deploymentName: 'gh-actions'
# parameters: acrName=${{ env.AZ_ACR_NAME }} clusterName=${{ env.AZ_ARO_NAME }} aadClientId=${{ secrets.ARO_CLIENT_ID }} aadClientSecret=${{ secrets.ARO_CLIENT_SECRET }} aadObjectId=${{ secrets.ARO_AAD_OBJECT_ID }} rpObjectId=${{ secrets.ARO_RP_OBJECT_ID }} sqlserverName=${{ env.AZ_SQLSERVER_NAME }} sqlAdminLogin=${{ secrets.AZURE_SQL_USERNAME }} sqlAdminPassword=${{ secrets.AZURE_SQL_PASSWORD }} kvName=${{ env.AZ_KV_NAME }} loadTestName=${{ env.AZ_LOADTEST_NAME }}

build:
needs: iac
Expand All @@ -73,8 +73,7 @@ jobs:
with:
creds: ${{ secrets.AZURE_CREDENTIALS }}

- name: Set the value in bash
id: setup-variables
- name: Set ACR variables
run: |
url_acr=$(az acr show -n ${{ env.AZ_ACR_NAME }} --query loginServer --output tsv)
login_acr=$(az acr credential show -n ${{ env.AZ_ACR_NAME }} --query username --output tsv)
Expand Down Expand Up @@ -137,24 +136,24 @@ jobs:
echo URL TODO API = $urlTodoApi
echo URL WEATHER API = $urlWeatherApi
echo "*** Replace ContainerApp.WebApp/k8s-deployment.yaml ***"
sed -i "s|_ImageUrlApp_|$urlApp|g" src/ContainerApp.WebApp/k8s-deployment.yaml
echo "*** Replace ContainerApp.WebApp/aro-deployment.yaml ***"
sed -i "s|_ImageUrlApp_|$urlApp|g" src/ContainerApp.WebApp/aro-deployment.yaml
echo "*** Replace ContainerApp.TodoApi/k8s-deployment.yaml ***"
sed -i "s|_ImageUrlApi_|$urlTodoApi|g" src/ContainerApp.TodoApi/k8s-deployment.yaml
sed -i "s|_ConnString_|$sqlConnString|g" src/ContainerApp.TodoApi/k8s-deployment.yaml
echo "*** Replace ContainerApp.TodoApi/aro-deployment.yaml ***"
sed -i "s|_ImageUrlApi_|$urlTodoApi|g" src/ContainerApp.TodoApi/aro-deployment.yaml
sed -i "s|_ConnString_|$sqlConnString|g" src/ContainerApp.TodoApi/aro-deployment.yaml
echo "*** Replace ContainerApp.WeatherApi/k8s-deployment.yaml ***"
sed -i "s|_ImageUrlApi_|$urlWeatherApi|g" src/ContainerApp.WeatherApi/k8s-deployment.yaml
echo "*** Replace ContainerApp.WeatherApi/aro-deployment.yaml ***"
sed -i "s|_ImageUrlApi_|$urlWeatherApi|g" src/ContainerApp.WeatherApi/aro-deployment.yaml
- name: Upload Kubernetes files
uses: actions/[email protected]
with:
name: k8s
path: |
src/ContainerApp.WebApp/k8s-deployment.yaml
src/ContainerApp.TodoApi/k8s-deployment.yaml
src/ContainerApp.WeatherApi/k8s-deployment.yaml
src/ContainerApp.WebApp/aro-deployment.yaml
src/ContainerApp.TodoApi/aro-deployment.yaml
src/ContainerApp.WeatherApi/aro-deployment.yaml
release-to-dev:
needs: build
Expand All @@ -167,26 +166,63 @@ jobs:
name: k8s
path: my-app-artifact

- name: Install CLI tools from OpenShift Mirror
uses: redhat-actions/openshift-tools-installer@v1
with:
source: "mirror"
oc: "3"

# Log into Azure
- name: Login
uses: azure/login@v1
with:
creds: ${{ secrets.AZURE_CREDENTIALS }}

# Set the target Azure Kubernetes Service (AKS) cluster.
- name: Deploy set context
uses: azure/aks-set-context@v1
with:
creds: '${{ secrets.AZURE_CREDENTIALS }}'
cluster-name: ${{ env.AZ_AKS_NAME }}
resource-group: ${{ env.AZ_RG_NAME }}
- name: Set ARO variables
id: aro-variables
run: |
aroApiServer=$(az aro show --name ${{ env.AZ_ARO_NAME }} --resource-group ${{ env.AZ_RG_NAME }} --query "apiserverProfile.url" -o tsv)
aroPass=$(az aro list-credentials --name ${{ env.AZ_ARO_NAME }} --resource-group ${{ env.AZ_RG_NAME }} --query "kubeadminPassword" -o tsv)
echo "::add-mask::$aroApiServer"
echo "::add-mask::$aroPass"
echo "ARO_API_SERVER=$aroApiServer" >> $GITHUB_ENV
echo "ARO_API_PASS=$aroPass" >> $GITHUB_ENV
# Deploy app to AKS
- name: Deploy to k8s
uses: azure/k8s-deploy@v1
- name: Log in to OpenShift
uses: redhat-actions/oc-login@v1
with:
namespace: default
manifests: |
my-app-artifact/ContainerApp.WebApp/k8s-deployment.yaml
my-app-artifact/ContainerApp.TodoApi/k8s-deployment.yaml
my-app-artifact/ContainerApp.WeatherApi/k8s-deployment.yaml
openshift_server_url: ${{ env.ARO_API_SERVER }}
openshift_username: 'kubeadmin'
openshift_password: ${{ env.ARO_API_PASS }}
insecure_skip_tls_verify: true
namespace: 'default'

- name: Set ACR variables
run: |
url_acr=$(az acr show -n ${{ env.AZ_ACR_NAME }} --query loginServer --output tsv)
login_acr=$(az acr credential show -n ${{ env.AZ_ACR_NAME }} --query username --output tsv)
password_acr=$(az acr credential show -n ${{ env.AZ_ACR_NAME }} --query passwords[0].value --output tsv)
echo "::add-mask::$url_acr"
echo "::add-mask::$login_acr"
echo "::add-mask::$password_acr"
echo "ACR_URL=$url_acr" >> $GITHUB_ENV
echo "ACR_LOGIN=$login_acr" >> $GITHUB_ENV
echo "ACR_PASSWORD=$password_acr" >> $GITHUB_ENV
- name: Create ACR Secret
run: |
if [ $(oc get secret acr-secret --ignore-not-found) = false ]; then
oc create secret docker-registry --docker-server=${{ env.ACR_URL }} --docker-username=${{ env.ACR_LOGIN }} --docker-password=${{ env.ACR_PASSWORD }} --docker-email=unused acr-secret
else
echo "Secrete already exists"
fi
- name: Apply Deployment
run: |
oc apply -f my-app-artifact/ContainerApp.WebApp/aro-deployment.yaml
oc apply -f my-app-artifact/ContainerApp.TodoApi/aro-deployment.yaml
oc apply -f my-app-artifact/ContainerApp.WeatherApi/aro-deployment.yaml
21 changes: 8 additions & 13 deletions ARO.md
Original file line number Diff line number Diff line change
@@ -1,22 +1,13 @@
# the location of your cluster
$LOCATION="eastus"

# the name of the resource group where you want to create your cluster
$RESOURCEGROUP="rg-aro"

# the name of your cluster
$CLUSTER="leandroarocluster"

# the name of container registry
$RESOURCEGROUP = "rg-dotnetcontainerapp-aro"
$LOCATION = "eastus"
$CLUSTER = "arodotnetcontainerapp"
$ACR="crcontainerappdemo"

# Create a resource group.
az group create --name $RESOURCEGROUP --location $LOCATION

# Create Service Principal
az ad sp create-for-rbac --name "sp-$RESOURCEGROUP-$CLUSTER" > app-service-principal.json

az ad sp list --show-mine -o table
az ad sp create-for-rbac --name "sp-$RESOURCEGROUP-$CLUSTER"

$SP_CLIENT_ID = <appId>
$SP_CLIENT_SECRET = <password>
Expand All @@ -30,6 +21,10 @@ az role assignment create --role 'Contributor' --assignee-object-id $SP_OBJECT_I
# Get the service principal object ID for the OpenShift
$ARO_RP_SP_OBJECT_ID = $(az ad sp list --display-name "Azure Red Hat OpenShift RP" --query [0].id -o tsv)


# Create GitHub Secrets


# Create ACR
az acr create --resource-group $RESOURCEGROUP --name $ACR --sku Basic

Expand Down
143 changes: 114 additions & 29 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Dotnet Container App

This .NET 6 example application to demonstrate the process of creating a container application and deploying it to Azure Kubernetes Services (AKS)
This .NET 6 example application to demonstrate the process of creating a container application. You can choose to publish the application to Azure Kubernetes Services (AKS) or Azure RedHat OpenShift (ARO).

![Application](/docs/images/img01.png "Application")

Expand All @@ -16,6 +16,20 @@ The project is divided as follows:
- **src/ContainerApp.WebApp:** Web Application interact with rest TODO API and
- **src/ContainerApp.Test:** Unit Testing project

This sample application can use the following Azure features:

- **[Azure Container Registry (ACR)](https://docs.microsoft.com/en-us/azure/container-registry/)** ACR allows you to build, store, and manage container images and artifacts in a private registry for all types of container deployments

- **[Azure Kubernetes Services (AKS)](https://docs.microsoft.com/en-us/azure/aks/intro-kubernetes)** AKS simplifies deploying a managed Kubernetes cluster in Azure by offloading the operational overhead to Azure

- **[Azure RedHat OpenShift (ARO)](https://learn.microsoft.com/en-us/azure/openshift/)** Azure Red Hat OpenShift provides highly available, fully managed OpenShift clusters on demand, monitored and operated jointly by Microsoft and Red Hat. Kubernetes is at the core of Red Hat OpenShift

- **[SQL Server Database](https://docs.microsoft.com/en-us/azure/azure-sql/azure-sql-iaas-vs-paas-what-is-overview?view=azuresql)** is a relational database-as-a-service (DBaaS) hosted in Azure that falls into the industry category of Platform-as-a-Service (PaaS).

- **[Azure Monitor](https://docs.microsoft.com/en-us/azure/azure-monitor/overview)** helps you maximize the availability and performance of your applications and services. It delivers a comprehensive solution for collecting, analyzing, and acting on telemetry from your cloud and on-premises environments.

- **[Azure Key Vault](https://learn.microsoft.com/en-us/azure/key-vault/general/)** is a cloud service for securely storing and accessing secrets. A secret is anything that you want to tightly control access to, such as API keys, passwords, certificates, or cryptographic keys.

## Getting Started

### Prerequisites
Expand Down Expand Up @@ -59,22 +73,10 @@ docker-compose -f 'DockerCompose.yml' up --build -d

![Docker Compose](/docs/images/img04.png "DockerCompose")

## Publish to Azure

In this section I will show you the steps to publish the application in Azure. To create the environment in Azure we are using the concept of Infrastructure as Code (IAC) where we have a bicep file that we declare all the resources we need to create in Azure. You can see this [main.bicep](src/aspnetcoreiac/main.bicep) file.

This bicep file will create the following resources in Azure.

- **[Azure Container Registry (ACR)](https://docs.microsoft.com/en-us/azure/container-registry/)** ACR allows you to build, store, and manage container images and artifacts in a private registry for all types of container deployments

- **[Azure Kubernetes Services (AKS)](https://docs.microsoft.com/en-us/azure/aks/intro-kubernetes)** AKS simplifies deploying a managed Kubernetes cluster in Azure by offloading the operational overhead to Azure

- **[SQL Server Database](https://docs.microsoft.com/en-us/azure/azure-sql/azure-sql-iaas-vs-paas-what-is-overview?view=azuresql)** is a relational database-as-a-service (DBaaS) hosted in Azure that falls into the industry category of Platform-as-a-Service (PaaS).

- **[Azure Monitor](https://docs.microsoft.com/en-us/azure/azure-monitor/overview)** helps you maximize the availability and performance of your applications and services. It delivers a comprehensive solution for collecting, analyzing, and acting on telemetry from your cloud and on-premises environments.

- **[Azure Key Vault](https://learn.microsoft.com/en-us/azure/key-vault/general/)** is a cloud service for securely storing and accessing secrets. A secret is anything that you want to tightly control access to, such as API keys, passwords, certificates, or cryptographic keys
## Publishing the application
Now you can choose to publish the application to Azure Kubernetes Services (AKS) or Azure RedHat OpenShift (ARO).

## Connect GitHub and Azure Cloud
First step is create a Service Principal identity to GitHub connect to Azure Subscription

```sh
Expand Down Expand Up @@ -120,7 +122,21 @@ Create other two secrets
1. Store SQL username 'AZURE_SQL_USERNAME'
2. Store SQL password 'AZURE_SQL_PASSWORD'

Now we are ready to start the workflow [aspnetcore-deployment.yml](.github/workflows/aspnetcore-deployment.yml). This workflow has the following these steps
## Deploy to Azure Kubernetes Services (AKS)

In this section I will show you the steps to publish the application in **Azure Kubernetes Services**. To create the environment we are using the concept of Infrastructure as Code (IAC) where we have a bicep file that we declare all the resources we need to create in Azure. You can see this [aks.bicep](src/ContainerApp.IAC/aks.bicep) file.

To create the environment, you need to configure the following variables in the workflow [aks-aspnetcore-deployment.yml](.github/workflows/aks-aspnetcore-deployment.yml).

- AZ_RG_NAME
- AZ_RG_LOCATION
- AZ_ACR_NAME
- AZ_AKS_NAME
- AZ_SQLSERVER_NAME
- AZ_KV_NAME
- AZ_LOADTEST_NAME

This workflow has the following steps:

- **IAC**
- Run the Bicep file to create environment
Expand All @@ -133,22 +149,12 @@ Now we are ready to start the workflow [aspnetcore-deployment.yml](.github/workf
- **Release**
- Download the kubernetes YML artifact
- Configure the AKS context
- Create Secret
- Deploy the application to AKS

Navigate to the file [aspnetcore-deployment.yml](.github/workflows/aspnetcore-deployment.yml) and replace the variable values.
- AZ_RG_NAME
- AZ_RG_LOCATION
- AZ_ACR_NAME
- AZ_AKS_NAME
- AZ_SQLSERVER_NAME
- AZ_KV_NAME
- AZ_LOADTEST_NAME

This example using manual trigger, to start the workflow following these steps:

- Under your repository name, click *Actions* tab.
- In the left sidebar, click the workflow *aspnetcore-deployment*.
- In the left sidebar, click the workflow *aks-aspnetcore-deployment*.
- Above the list of workflow runs, select *Run workflow*.
- Use the Branch dropdown to select the workflow's main branch, Click *Run workflow*.

Expand All @@ -172,8 +178,87 @@ After the workflow ends, our application will be available for use.

![Kubernetes Services](/docs/images/img09.png "Kubernetes Services")

# Contributing
## Deploy to Azure RedHat OpenShift (ARO)
In this section I will show you the steps to publish the application in **Azure RedHat OpenShift**. To publish this application in ARO it is necessary to follow the following manual steps.

```ps
# Variables
$RESOURCEGROUP = "rg-dotnetcontainerapp-aro"
$LOCATION = "eastus"
$CLUSTER = "arodotnetcontainerapp"
# Create a resource group.
az group create --name $RESOURCEGROUP --location $LOCATION
# Create Service Principal
az ad sp create-for-rbac --name "sp-$RESOURCEGROUP-$CLUSTER"
# Save the values into variables
$SP_CLIENT_ID = <appId returned from above command >
$SP_CLIENT_SECRET = <password returned from above command>
$SP_OBJECT_ID = $(az ad sp show --id $SP_CLIENT_ID --query id --output tsv)
# Assign the Contributor role to the new service principal
az role assignment create --role 'User Access Administrator' --assignee-object-id $SP_OBJECT_ID --resource-group $RESOURCEGROUP --assignee-principal-type 'ServicePrincipal'
az role assignment create --role 'Contributor' --assignee-object-id $SP_OBJECT_ID --resource-group $RESOURCEGROUP --assignee-principal-type 'ServicePrincipal'
# Get the service principal object ID for the OpenShift
$ARO_RP_SP_OBJECT_ID = $(az ad sp list --display-name "Azure Red Hat OpenShift RP" --query [0].id -o tsv)
```

Now let's create Secrets on GitHub to store these informations

![ARO Secrets](/docs/images/img15.png "ARO Secrets")

To create the environment we are using this bicep file [aro.bicep](src/ContainerApp.IAC/aro.bicep).

Now you need to configure the following variables in the workflow [aro-aspnetcore-deployment.yml](.github/workflows/aro-aspnetcore-deployment.yml).

- AZ_RG_NAME
- AZ_RG_LOCATION
- AZ_ACR_NAME
- AZ_ARO_NAME
- AZ_SQLSERVER_NAME
- AZ_KV_NAME
- AZ_LOADTEST_NAME

This example using manual trigger, to start the workflow following these steps:

- Under your repository name, click *Actions* tab.
- In the left sidebar, click the workflow *aro-aspnetcore.deployment*.
- Above the list of workflow runs, select *Run workflow*.
- Use the Branch dropdown to select the workflow's main branch, Click *Run workflow*.

![Bicep Workflow](/docs/images/img16.png "Bicep Workflow")

Workflow result

![Azure Resources](/docs/images/img17.png "Azure Resources")

After deployment, below resources will be created in your Azure subscription

![Azure Resources](/docs/images/img18.png "Azure Resources")

For you to manage your application in ARO it is necessary to execute the command below to return the URL of the ARO administration portal

```ps
# View Console URL
az aro show --name $CLUSTER --resource-group $RESOURCEGROUP --query "consoleProfile.url" -o tsv
# Run the following command to find the password for the kubeadmin
az aro list-credentials --name $CLUSTER --resource-group $RESOURCEGROUP
```

- Log in ARO Portal with console URL and password
- Select *Developer* mode
- Select *Topology*
- Select the *containerapp-webapp-deploy*
- Check the external IP in the Routes section

![ARO portal](/docs/images/img19.png "ARO Portal")

# 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.opensource.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., status check, comment). Simply follow the instructions provided by the bot. You will only need to do this once across all repos using our CLA.
Expand Down
Binary file added docs/images/img15.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/images/img16.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/images/img17.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/images/img18.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/images/img19.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading

0 comments on commit 3dcf935

Please sign in to comment.