Initial check in of Build Out Traefik for Flux Deployment
This commit is contained in:
Родитель
0fe6ab0a5c
Коммит
d51f4e960b
|
@ -1,24 +1,158 @@
|
|||
name: "CD Build for Traefik"
|
||||
# Populates your CD repo for flux or argo deployment of traefik
|
||||
|
||||
on:
|
||||
name: CD Build - Traefik
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
test:
|
||||
description: "testing"
|
||||
default: "cset"
|
||||
required: true
|
||||
inputs:
|
||||
ENVIRONMENT:
|
||||
description: 'A GitHub Environment to pull action secrets from'
|
||||
required: true
|
||||
default: 'cset'
|
||||
type: string
|
||||
RG:
|
||||
description: 'The Resource Group where your resources are deployed'
|
||||
required: true
|
||||
type: string
|
||||
ACRNAME:
|
||||
description: 'The Name of the ACR resource'
|
||||
required: true
|
||||
type: string
|
||||
AKVNAME:
|
||||
description: 'The Name of the AKV resource'
|
||||
required: true
|
||||
type: string
|
||||
MINAME:
|
||||
description: 'The Name of the Managed Identity for traefik to access secrets in the AKV'
|
||||
required: true
|
||||
type: string
|
||||
|
||||
|
||||
secrets:
|
||||
AZURE_CLIENT_ID:
|
||||
required: true
|
||||
AZURE_TENANT_ID:
|
||||
required: true
|
||||
AZURE_SUBSCRIPTION_ID:
|
||||
required: true
|
||||
|
||||
env:
|
||||
event_sha: +refs/pull/${{ github.event.issue.number }}/merge
|
||||
|
||||
permissions:
|
||||
id-token: write
|
||||
contents: write
|
||||
|
||||
jobs:
|
||||
Explore-GitHub-Actions:
|
||||
App_Init:
|
||||
runs-on: ubuntu-latest
|
||||
environment: ${{ inputs.ENVIRONMENT }}
|
||||
env:
|
||||
RG: "${{ inputs.RG }}"
|
||||
ACRNAME: "${{ inputs.ACRNAME}}"
|
||||
AKVNAME: "${{ inputs.AKVNAME}}"
|
||||
MINAME: "${{ inputs.MINAME}}"
|
||||
|
||||
steps:
|
||||
- run: echo "🎉 The job was automatically triggered by a ${{ github.event_name }} event."
|
||||
- run: echo "🐧 This job is now running on a ${{ runner.os }} server hosted by GitHub!"
|
||||
- run: echo "🔎 The name of your branch is ${{ github.ref }} and your repository is ${{ github.repository }}."
|
||||
- name: Check out repository code
|
||||
uses: actions/checkout@v3
|
||||
- run: echo "💡 The ${{ github.repository }} repository has been cloned to the runner."
|
||||
- run: echo "🖥️ The workflow is now ready to test your code on the runner."
|
||||
- name: List files in the repository
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
persist-credentials: false # otherwise, the token used is the GITHUB_TOKEN, instead of your personal token
|
||||
fetch-depth: 0 # otherwise, you will failed to push refs to dest repo
|
||||
- name: Job parameter inspection
|
||||
run: |
|
||||
ls ${{ github.workspace }}
|
||||
- run: echo "🍏 This job's status is ${{ job.status }}."
|
||||
echo "RG is ${{ inputs.RG }}"
|
||||
echo "ACR name is ${{ inputs.ACRNAME }}"
|
||||
echo "AKV name is ${{ inputs.AKVNAME }}"
|
||||
echo "MI name is ${{ inputs.MINAME }}"
|
||||
|
||||
- name: Azure Login
|
||||
uses: Azure/login@v1
|
||||
with:
|
||||
client-id: ${{ secrets.AZURE_CLIENT_ID }}
|
||||
tenant-id: ${{ secrets.AZURE_TENANT_ID }}
|
||||
subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
|
||||
|
||||
- name: Push to a Azure Container Registry (ACR)
|
||||
run: |
|
||||
az acr import --source docker.io/library/traefik:v2.5.3 -n ${{ inputs.ACRNAME }} --force
|
||||
|
||||
- name: Pull identity information
|
||||
run: |
|
||||
echo "TRAEFIK_USER_ASSIGNED_IDENTITY_RESOURCE_ID=$(az identity show -n $MINAME -g $RG --query id -o tsv)" >> $GITHUB_ENV
|
||||
echo "TRAEFIK_USER_ASSIGNED_IDENTITY_CLIENT_ID=$(az identity show -n $MINAME -g $RG --query principalId -o tsv)" >> $GITHUB_ENV
|
||||
echo "TRAEFIK_USER_ASSIGNED_IDENTITY_RESOURCE_ID= ${{ env.TRAEFIK_USER_ASSIGNED_IDENTITY_RESOURCE_ID }}"
|
||||
echo "TRAEFIK_USER_ASSIGNED_IDENTITY_CLIENT_ID= ${{ env.TRAEFIK_USER_ASSIGNED_IDENTITY_CLIENT_ID }}"
|
||||
|
||||
- name: Create Working Directory
|
||||
run: |
|
||||
mkdir tmpworking
|
||||
echo "TMPWORKDIR=$(pwd)/tmpworking" >> $GITHUB_ENV
|
||||
|
||||
- name: Copy Templates to Working Directory
|
||||
run: |
|
||||
cp shared-services/templates/a0008/azureidentity.yaml ${{ env.TMPWORKDIR }}/
|
||||
cp shared-services/templates/a0008/secretproviderclass.yaml ${{ env.TMPWORKDIR }}/
|
||||
cp shared-services/templates/a0008/traefik.yaml ${{ env.TMPWORKDIR }}/
|
||||
ls -al ${{ env.TMPWORKDIR }}
|
||||
|
||||
- name: Dump variables used to populate yaml files
|
||||
run: |
|
||||
echo "TMPWORKDIR=${{ env.TMPWORKDIR }}"
|
||||
echo "TRAEFIK_USER_ASSIGNED_IDENTITY_RESOURCE_ID=${{ env.TRAEFIK_USER_ASSIGNED_IDENTITY_RESOURCE_ID }}"
|
||||
echo "TRAEFIK_USER_ASSIGNED_IDENTITY_CLIENT_ID=${{ env.TRAEFIK_USER_ASSIGNED_IDENTITY_CLIENT_ID }}"
|
||||
echo "KEYVAULT_NAME_AKS_BASELINE=${{ env.KEYVAULT_NAME_AKS_BASELINE }}"
|
||||
echo "TENANTID_AZURERBAC_AKS_BASELINE=${{ env.TENANTID_AZURERBAC_AKS_BASELINE }}"
|
||||
echo "ACR_NAME_AKS_BASELINE=${{ env.ACR_NAME_AKS_BASELINE }}"
|
||||
|
||||
|
||||
- name: Populate variables in yaml files
|
||||
run: |
|
||||
escaped_var=$( echo ${{ env.TRAEFIK_USER_ASSIGNED_IDENTITY_RESOURCE_ID }} | sed 's;/;\\/;g')
|
||||
echo "Escaped TRAEFIK_USER_ASSIGNED_IDENTITY_RESOURCE_ID for sed usage: $escaped_var"
|
||||
sed -i "s/\${TRAEFIK_USER_ASSIGNED_IDENTITY_RESOURCE_ID}/$escaped_var/g" ${{ env.TMPWORKDIR }}/azureidentity.yaml
|
||||
sed -i "s/\${TRAEFIK_USER_ASSIGNED_IDENTITY_CLIENT_ID}/${{ env.TRAEFIK_USER_ASSIGNED_IDENTITY_CLIENT_ID }}/g" ${{ env.TMPWORKDIR }}/azureidentity.yaml
|
||||
sed -i "s/\${KEYVAULT_NAME_AKS_BASELINE}/${{ inputs.AKVNAME }}/g" ${{ env.TMPWORKDIR }}/secretproviderclass.yaml
|
||||
sed -i "s/\${TENANTID_AZURERBAC_AKS_BASELINE}/${{ secrets.AZURE_TENANT_ID }}/g" ${{ env.TMPWORKDIR }}/secretproviderclass.yaml
|
||||
sed -i "s/\${ACR_NAME_AKS_BASELINE}/${{ inputs.ACRNAME }}/g" ${{ env.TMPWORKDIR }}/traefik.yaml
|
||||
|
||||
- name: Move yaml files to cluster mainifest directory and remove temp working dir
|
||||
run: |
|
||||
cp ${{ env.TMPWORKDIR }}/*.yaml shared-services/cluster-manifests/a0008/
|
||||
rm -rf ${{ env.TMPWORKDIR }}
|
||||
|
||||
- name: Check AzureIdentity yaml
|
||||
run: |
|
||||
echo "Traefiks AzureIdentity yaml file:"
|
||||
cat shared-services/cluster-manifests/a0008/azureidentity.yaml
|
||||
|
||||
- name: Check SecretProviderClass yaml
|
||||
run: |
|
||||
echo "Traefiks secretproviderclass yaml file:"
|
||||
cat shared-services/cluster-manifests/a0008/secretproviderclass.yaml
|
||||
|
||||
- name: Check Traefiks deployment yaml
|
||||
run: |
|
||||
echo "Traefiks deployment yaml file:"
|
||||
cat shared-services/cluster-manifests/a0008/traefik.yaml
|
||||
|
||||
- name: Commit files
|
||||
run: |
|
||||
git config --local user.email "github-actions[bot]@users.noreply.github.com"
|
||||
git config --local user.name "github-actions[bot]"
|
||||
if [[ "$(git status)" != *"nothing to commit"* ]];then
|
||||
git add .
|
||||
git commit -a -m "Add Traefik manifest files"
|
||||
else
|
||||
echo "No changes to traefik yaml files, therefore nothing to commit"
|
||||
fi
|
||||
|
||||
- name: Dump github ref
|
||||
run: |
|
||||
echo "Preparing to push files to ${{ github.ref}}"
|
||||
|
||||
- name: Push changes
|
||||
uses: ad-m/github-push-action@master
|
||||
with:
|
||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
branch: ${{ github.ref }}
|
||||
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
apiVersion: aadpodidentity.k8s.io/v1
|
||||
kind: AzureIdentity
|
||||
metadata:
|
||||
name: podmi-ingress-controller-identity
|
||||
namespace: a0008
|
||||
spec:
|
||||
type: 0
|
||||
resourceID: ${TRAEFIK_USER_ASSIGNED_IDENTITY_RESOURCE_ID}
|
||||
clientID: ${TRAEFIK_USER_ASSIGNED_IDENTITY_CLIENT_ID}
|
||||
---
|
||||
apiVersion: aadpodidentity.k8s.io/v1
|
||||
kind: AzureIdentityBinding
|
||||
metadata:
|
||||
name: podmi-ingress-controller-binding
|
||||
namespace: a0008
|
||||
spec:
|
||||
azureIdentity: podmi-ingress-controller-identity
|
||||
selector: podmi-ingress-controller
|
|
@ -0,0 +1,22 @@
|
|||
apiVersion: secrets-store.csi.x-k8s.io/v1
|
||||
kind: SecretProviderClass
|
||||
metadata:
|
||||
name: aks-ingress-tls-secret-csi-akv
|
||||
namespace: a0008
|
||||
spec:
|
||||
provider: azure
|
||||
parameters:
|
||||
usePodIdentity: "true"
|
||||
useVMManagedIdentity: "false"
|
||||
keyvaultName: ${KEYVAULT_NAME_AKS_BASELINE}
|
||||
objects: |
|
||||
array:
|
||||
- |
|
||||
objectName: traefik-ingress-internal-aks-ingress-tls
|
||||
objectAlias: tls.crt
|
||||
objectType: cert
|
||||
- |
|
||||
objectName: traefik-ingress-internal-aks-ingress-tls
|
||||
objectAlias: tls.key
|
||||
objectType: secret
|
||||
tenantId: ${TENANTID_AZURERBAC_AKS_BASELINE}
|
|
@ -0,0 +1,305 @@
|
|||
kind: ServiceAccount
|
||||
apiVersion: v1
|
||||
metadata:
|
||||
name: traefik-ingress-controller
|
||||
namespace: a0008
|
||||
labels:
|
||||
app.kubernetes.io/name: traefik-ingress-ilb
|
||||
app.kubernetes.io/instance: traefik-ingress-ilb
|
||||
---
|
||||
kind: ClusterRole
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
metadata:
|
||||
name: traefik-ingress-controller
|
||||
namespace: a0008
|
||||
labels:
|
||||
app.kubernetes.io/name: traefik-ingress-ilb
|
||||
app.kubernetes.io/instance: traefik-ingress-ilb
|
||||
rules:
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- services
|
||||
- endpoints
|
||||
- secrets
|
||||
verbs:
|
||||
- get
|
||||
- list
|
||||
- watch
|
||||
- apiGroups:
|
||||
- extensions
|
||||
- networking.k8s.io
|
||||
resources:
|
||||
- ingresses
|
||||
- ingressclasses
|
||||
verbs:
|
||||
- get
|
||||
- list
|
||||
- watch
|
||||
- apiGroups:
|
||||
- extensions
|
||||
- networking.k8s.io
|
||||
resources:
|
||||
- ingresses/status
|
||||
verbs:
|
||||
- update
|
||||
- apiGroups:
|
||||
- traefik.containo.us
|
||||
resources:
|
||||
- middlewares
|
||||
- middlewaretcps
|
||||
- ingressroutes
|
||||
- traefikservices
|
||||
- ingressroutetcps
|
||||
- ingressrouteudps
|
||||
- tlsoptions
|
||||
- tlsstores
|
||||
- serverstransports
|
||||
verbs:
|
||||
- get
|
||||
- list
|
||||
- watch
|
||||
---
|
||||
kind: ClusterRoleBinding
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
metadata:
|
||||
name: traefik-watch-workloads
|
||||
namespace: a0008
|
||||
labels:
|
||||
app.kubernetes.io/name: traefik-ingress-ilb
|
||||
app.kubernetes.io/instance: traefik-ingress-ilb
|
||||
roleRef:
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: ClusterRole
|
||||
name: traefik-ingress-controller
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: traefik-ingress-controller
|
||||
namespace: a0008
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: traefik-ingress-config
|
||||
namespace: a0008
|
||||
labels:
|
||||
app.kubernetes.io/name: traefik-ingress-ilb
|
||||
app.kubernetes.io/instance: traefik-ingress-ilb
|
||||
data:
|
||||
traefik.toml: |
|
||||
[metrics]
|
||||
[metrics.prometheus]
|
||||
entryPoint = "metrics"
|
||||
addEntryPointsLabels = true
|
||||
addServicesLabels = true
|
||||
[accessLog]
|
||||
filePath = "/data/access.log"
|
||||
bufferingSize = 100
|
||||
[global]
|
||||
# prevent Traefik from checking newer versions in production
|
||||
checknewversion = false
|
||||
# prevent Traefik from collecting and sending stats from production
|
||||
sendanonymoususage = false
|
||||
[log]
|
||||
level = "ERROR"
|
||||
format = "json"
|
||||
[api]
|
||||
dashboard = false
|
||||
[providers]
|
||||
# Configuration reload frequency:
|
||||
# * duration that Traefik waits for, after a configuration reload, before taking into account any new configuration refresh event
|
||||
# * the most recent one is taken into account, and all the previous others are dropped.
|
||||
providersThrottleDuration = 10
|
||||
[providers.file]
|
||||
filename = "/config/traefik.toml"
|
||||
watch = true
|
||||
# Traefik provider that supports the native Kubernetes Ingress specification
|
||||
# and derives the corresponding dynamic configuration from it. https://kubernetes.io/docs/concepts/services-networking/ingress/
|
||||
[providers.kubernetesingress]
|
||||
ingressClass = "traefik-internal"
|
||||
namespaces = ["a0008"]
|
||||
[providers.kubernetesIngress.ingressEndpoint]
|
||||
publishedService = "a0008/traefik-ingress-service"
|
||||
# Enable gzip compression
|
||||
[http.middlewares]
|
||||
[http.middlewares.gzip-compress.compress]
|
||||
[http.middlewares.app-gateway-snet.ipWhiteList]
|
||||
sourceRange = ["10.240.5.0/24"]
|
||||
[entryPoints]
|
||||
[entryPoints.metrics]
|
||||
address = ":8082"
|
||||
[entryPoints.traefik]
|
||||
address = ":9000"
|
||||
[entryPoints.websecure]
|
||||
address = ":8443"
|
||||
[entryPoints.websecure.forwardedHeaders]
|
||||
trustedIPs = ["10.240.5.0/24"]
|
||||
[entryPoints.websecure.http.tls]
|
||||
options = "default"
|
||||
[ping]
|
||||
entryPoint = "traefik"
|
||||
[tls]
|
||||
# without duplicating this cert config and with SNI enabled, Traefik won't
|
||||
# find the certificates for your host. It may be a Traefik's issue.
|
||||
[[tls.certificates]]
|
||||
certFile = "/certs/tls.crt"
|
||||
keyFile = "/certs/tls.key"
|
||||
stores = ["default"]
|
||||
[tls.stores]
|
||||
[tls.stores.default]
|
||||
[tls.stores.default.defaultCertificate]
|
||||
# without specifying in here your certs, Traefik will create its own
|
||||
# certificate
|
||||
certFile = "/certs/tls.crt"
|
||||
keyFile = "/certs/tls.key"
|
||||
[tls.options.default]
|
||||
minVersion = "VersionTLS12"
|
||||
sniStrict = true
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: traefik-ingress-service
|
||||
namespace: a0008
|
||||
labels:
|
||||
app.kubernetes.io/name: traefik-ingress-ilb
|
||||
app.kubernetes.io/instance: traefik-ingress-ilb
|
||||
annotations:
|
||||
service.beta.kubernetes.io/azure-load-balancer-internal: "true"
|
||||
service.beta.kubernetes.io/azure-load-balancer-internal-subnet: "snet-clusteringressservices"
|
||||
spec:
|
||||
type: LoadBalancer
|
||||
loadBalancerIP: 10.240.4.4
|
||||
externalTrafficPolicy: Local
|
||||
selector:
|
||||
app.kubernetes.io/name: traefik-ingress-ilb
|
||||
app.kubernetes.io/instance: traefik-ingress-ilb
|
||||
ports:
|
||||
- port: 443
|
||||
name: "https"
|
||||
targetPort: "websecure"
|
||||
protocol: "TCP"
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: traefik-ingress-controller
|
||||
namespace: a0008
|
||||
labels:
|
||||
app.kubernetes.io/name: traefik-ingress-ilb
|
||||
app.kubernetes.io/instance: traefik-ingress-ilb
|
||||
aadpodidbinding: podmi-ingress-controller
|
||||
spec:
|
||||
replicas: 2
|
||||
selector:
|
||||
matchLabels:
|
||||
app.kubernetes.io/name: traefik-ingress-ilb
|
||||
app.kubernetes.io/instance: traefik-ingress-ilb
|
||||
strategy:
|
||||
type: RollingUpdate
|
||||
rollingUpdate:
|
||||
maxSurge: 1
|
||||
maxUnavailable: 1
|
||||
template:
|
||||
metadata:
|
||||
annotations:
|
||||
prometheus.io/scrape: "true"
|
||||
prometheus.io/port: "8082"
|
||||
labels:
|
||||
app.kubernetes.io/name: traefik-ingress-ilb
|
||||
app.kubernetes.io/instance: traefik-ingress-ilb
|
||||
aadpodidbinding: podmi-ingress-controller
|
||||
spec:
|
||||
hostNetwork: false
|
||||
serviceAccountName: traefik-ingress-controller
|
||||
terminationGracePeriodSeconds: 60
|
||||
affinity:
|
||||
podAntiAffinity:
|
||||
requiredDuringSchedulingIgnoredDuringExecution:
|
||||
- labelSelector:
|
||||
matchExpressions:
|
||||
- key: app.kubernetes.io/name
|
||||
operator: In
|
||||
values:
|
||||
- traefik-ingress-ilb
|
||||
topologyKey: "kubernetes.io/hostname"
|
||||
containers:
|
||||
# PRODUCTION READINESS CHANGE REQUIRED
|
||||
# This image should be sourced from a non-public container registry, such as the
|
||||
# one deployed along side of this reference implementation.
|
||||
# az acr import --source docker.io/library/traefik:v2.5.3 -n <your-acr-instance-name>
|
||||
# and then set this to
|
||||
# image: <your-acr-instance-name>.azurecr.io/library/traefik:v2.5.3
|
||||
# in order to use the public image, replace the image setting with the following line
|
||||
# - image: docker.io/library/traefik:v2.5.3
|
||||
- image: ${ACR_NAME_AKS_BASELINE}.azurecr.io/library/traefik:v2.5.3
|
||||
name: traefik-ingress-controller
|
||||
resources:
|
||||
requests:
|
||||
cpu: 100m
|
||||
memory: 64Mi
|
||||
limits:
|
||||
cpu: 200m
|
||||
memory: 128Mi
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: /ping
|
||||
port: "traefik"
|
||||
failureThreshold: 1
|
||||
initialDelaySeconds: 10
|
||||
periodSeconds: 10
|
||||
successThreshold: 1
|
||||
timeoutSeconds: 2
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: /ping
|
||||
port: "traefik"
|
||||
failureThreshold: 3
|
||||
initialDelaySeconds: 10
|
||||
periodSeconds: 10
|
||||
successThreshold: 1
|
||||
timeoutSeconds: 2
|
||||
ports:
|
||||
- name: "traefik"
|
||||
containerPort: 9000
|
||||
protocol: TCP
|
||||
- name: "websecure"
|
||||
containerPort: 8443
|
||||
protocol: TCP
|
||||
- name: "metrics"
|
||||
containerPort: 8082
|
||||
protocol: TCP
|
||||
securityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
capabilities:
|
||||
drop:
|
||||
- ALL
|
||||
readOnlyRootFilesystem: true
|
||||
runAsGroup: 65532
|
||||
runAsNonRoot: true
|
||||
runAsUser: 65532
|
||||
volumeMounts:
|
||||
- name: data
|
||||
mountPath: /data
|
||||
- name: config
|
||||
mountPath: /config
|
||||
readOnly: true
|
||||
- name: ssl-csi
|
||||
mountPath: /certs
|
||||
readOnly: true
|
||||
args:
|
||||
- --configfile=/config/traefik.toml
|
||||
volumes:
|
||||
- name: config
|
||||
configMap:
|
||||
name: traefik-ingress-config
|
||||
- name: ssl-csi
|
||||
csi:
|
||||
driver: secrets-store.csi.k8s.io
|
||||
readOnly: true
|
||||
volumeAttributes:
|
||||
secretProviderClass: aks-ingress-tls-secret-csi-akv
|
||||
- name: data
|
||||
emptyDir: {}
|
||||
nodeSelector:
|
||||
agentpool: npuser01
|
Загрузка…
Ссылка в новой задаче