aks-baseline-automation/.github/workflows/IaC-bicep-AKS.yml

179 строки
8.4 KiB
YAML

name: 'IaC Deploy CARML based AKS Cluster'
on:
workflow_dispatch:
inputs:
ENVIRONMENT:
description: 'A GitHub Environment to pull action secrets from'
required: true
type: environment
REGION:
description: 'The Azure region to deploy to'
required: true
default: westus2
clusterAdminAadGroupObjectId:
description: 'K8S Admin Azure AAD Group ObjectID'
required: true
type: string
a0008NamespaceReaderAadGroupObjectId:
description: 'K8S Reader Azure AAD Group ObjectID'
required: true
type: string
env:
event_sha: +refs/pull/${{ github.event.issue.number }}/merge
permissions:
id-token: write
contents: read
jobs:
prereqs:
runs-on: ubuntu-latest
environment: ${{ github.event.inputs.ENVIRONMENT }}
name: Prerequisite Checks
steps:
- name: "Checkout"
uses: actions/checkout@v2
with:
fetch-depth: 0
- name: "Parameter Check"
run: |
echo "Environment : ${{ github.event.inputs.ENVIRONMENT }}"
echo "REGION : ${{ github.event.inputs.REGION }}"
- name: Azure Login
uses: Azure/login@v1.4.3
with:
client-id: ${{ secrets.AZURE_CLIENT_ID }}
tenant-id: ${{ secrets.AZURE_TENANT_ID }}
subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
- name: "Check Preview Features"
shell: pwsh
run: |
write-output "Verifying required Resource Providers Features are registered"
$aksfeatures = az feature list --query "[?contains(name, 'Microsoft.ContainerService')]" | ConvertFrom-Json
$featureName='AKS-ExtensionManager'
write-output "-- $featureName"
$feature = $aksfeatures | Where-Object {$_.name -like "*$featureName"}
$feature.properties.state
if ($feature.properties.state -ne 'Registered') {
Write-Output $feature
Write-Error "$featureName NOT registered"
}
$featureName='EnableOIDCIssuerPreview'
write-output "-- $featureName"
$feature = $aksfeatures | Where-Object {$_.name -like "*$featureName"}
$feature.properties.state
if ($feature.properties.state -ne 'Registered') {
Write-Output $feature
Write-Error "$featureName NOT registered"
}
$featureName='AKS-AzureDefender'
write-output "-- $featureName"
$feature = $aksfeatures | Where-Object {$_.name -like "*$featureName"}
$feature.properties.state
if ($feature.properties.state -ne 'Registered') {
Write-Output $feature
Write-Error "$featureName NOT registered"
}
deployment:
runs-on: ubuntu-latest
environment: ${{ github.event.inputs.ENVIRONMENT }}
name: Deployment
needs: [prereqs]
steps:
- name: "Checkout"
uses: actions/checkout@v2
with:
fetch-depth: 0
# This step is just used for convenience as you won't be using self-signed certificate in your production environment.
# The certificate used in your environment will likely be generated and imported into KeyVault by your security team
- name: "Cert Generation"
id: cert
run: |
export DOMAIN_NAME_AKS_BASELINE="contoso.com"
export CN="bicycle"
openssl req -x509 -nodes -days 365 -newkey rsa:2048 -out appgw.crt -keyout appgw.key -subj "/CN=${CN}.${DOMAIN_NAME_AKS_BASELINE}/O=Contoso Bicycle" -addext "subjectAltName = DNS:${CN}.${DOMAIN_NAME_AKS_BASELINE}" -addext "keyUsage = digitalSignature" -addext "extendedKeyUsage = serverAuth"
openssl pkcs12 -export -out appgw.pfx -in appgw.crt -inkey appgw.key -passout pass:
export APP_GATEWAY_LISTENER_CERTIFICATE_AKS_BASELINE=$(cat appgw.pfx | base64 | tr -d '\n')
echo "APP_GATEWAY_LISTENER_CERTIFICATE=$APP_GATEWAY_LISTENER_CERTIFICATE_AKS_BASELINE" >> $GITHUB_ENV
openssl req -x509 -nodes -days 365 -newkey rsa:2048 -out traefik-ingress-internal-aks-ingress-tls.crt -keyout traefik-ingress-internal-aks-ingress-tls.key -subj "/CN=*.aks-ingress.${DOMAIN_NAME_AKS_BASELINE}/O=Contoso AKS Ingress"
export AKS_INGRESS_CONTROLLER_CERTIFICATE_BASE64_AKS_BASELINE=$(cat traefik-ingress-internal-aks-ingress-tls.crt | base64 | tr -d '\n')
echo "AKS_INGRESS_CONTROLLER_CERTIFICATE=$AKS_INGRESS_CONTROLLER_CERTIFICATE_BASE64_AKS_BASELINE" >> $GITHUB_ENV
- name: Azure Login
uses: Azure/login@v1.4.3
with:
client-id: ${{ secrets.AZURE_CLIENT_ID }}
tenant-id: ${{ secrets.AZURE_TENANT_ID }}
subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
- name: "Deploy AKS Landingzone"
id: akslz
uses: azure/arm-deploy@v1
with:
subscriptionId: ${{ secrets.SUBSCRIPTION_ID }}
region: ${{ github.event.inputs.REGION }}
scope: subscription
template: ./IaC/bicep/main.bicep
parameters: ./IaC/bicep/main.parameters.json clusterAdminAadGroupObjectId=${{ github.event.inputs.clusterAdminAadGroupObjectId }} a0008NamespaceReaderAadGroupObjectId=${{ github.event.inputs.a0008NamespaceReaderAadGroupObjectId }} appGatewayListenerCertificate=${{ env.APP_GATEWAY_LISTENER_CERTIFICATE }} aksIngressControllerCertificate=${{ env.AKS_INGRESS_CONTROLLER_CERTIFICATE }}
failOnStdErr: false
deploymentName: carml-aks-landingzone-${{ github.event.inputs.REGION }}
# Import core images hosted in public container registries to be used during bootstrapping
- name: "Import Images into ACR for flux"
id: image_import
run: |
az acr import --source docker.io/weaveworks/kured:1.10.1 -n ${{ steps.akslz.outputs.containerRegistryName }} --force
az acr import --source docker.io/library/traefik:v2.8.1 -n ${{ steps.akslz.outputs.containerRegistryName }} --force
# Temporary workaround until we figure out why steps.cluster.outputs.keyVaultName is blank
- name: "Get KeyVault Name"
id: akv_name
run: |
export AKV_NAME=$(az keyvault list -g rg-bu0001a0008 -o table | grep "kv-aks" | awk '{print $2}')
echo "AKV_NAME=${AKV_NAME}" >> $GITHUB_ENV
echo "AKV Name from bicep output is ${{ steps.akslz.outputs.keyVaultName }}"
echo "aksIngressControllerPodManagedIdentityResourceId from bicep output is ${{ steps.akslz.outputs.aksIngressControllerPodManagedIdentityResourceId }}"
echo "To prove that this should work: hubVnetId is ${{ steps.akslz.outputs.hubVnetId }}"
# Re-authentication is required for the commands that follow
- name: Azure Login
uses: Azure/login@v1.4.3
with:
client-id: ${{ secrets.AZURE_CLIENT_ID }}
tenant-id: ${{ secrets.AZURE_TENANT_ID }}
subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
# This step is just used for convenience as the certificate used in your environment will likely be generated and imported into KeyVault by your security team
# This step imports into KeyVault the same backend cert that was generated above for the App Gateway. This cert will be used by the Ingress Controller Traefik.
- name: "Cert Import into Key Vault for Traefik"
id: cert_import
run: |
ASSIGNEE_OBJ_ID=$(az ad sp show --id ${{ secrets.AZURE_CLIENT_ID }} --query id -o tsv)
AKV_RESOURCE_ID=$(az keyvault show -n ${{ env.AKV_NAME }} --query id -o tsv)
TEMP_ROLEASSIGNMENT_TO_UPLOAD_CERT=$(az role assignment create --role a4417e6f-fecd-4de8-b567-7b0420556985 --assignee-principal-type serviceprincipal --assignee-object-id $ASSIGNEE_OBJ_ID --scope $AKV_RESOURCE_ID | jq '.id' )
sleep 60
CURRENT_IP_ADDRESS=$(curl -s -4 https://ifconfig.io)
az keyvault network-rule add -n ${{ env.AKV_NAME }} --ip-address ${CURRENT_IP_ADDRESS}
sleep 30
cat traefik-ingress-internal-aks-ingress-tls.crt traefik-ingress-internal-aks-ingress-tls.key > traefik-ingress-internal-aks-ingress-tls.pem
az keyvault certificate import -f traefik-ingress-internal-aks-ingress-tls.pem -n traefik-ingress-internal-aks-ingress-tls --vault-name ${{ env.AKV_NAME }}
az keyvault network-rule remove -n ${{ env.AKV_NAME }} --ip-address ${CURRENT_IP_ADDRESS}
az role assignment delete --role a4417e6f-fecd-4de8-b567-7b0420556985 --assignee $ASSIGNEE_OBJ_ID --scope $AKV_RESOURCE_ID