Skip to content

Commit

Permalink
Merge pull request #45 from Azure-Samples/ignite
Browse files Browse the repository at this point in the history
Ignite lab
  • Loading branch information
chzbrgr71 authored Nov 20, 2024
2 parents 608c48a + 7f7b9a9 commit 48ef5ef
Show file tree
Hide file tree
Showing 16 changed files with 2,570 additions and 1 deletion.
22 changes: 21 additions & 1 deletion packages/website/src/app/workshop/workshop.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { getCurrentUrlWithQueryParams, MenuLink } from '../shared/link';
import { FileContents, LoaderOptions, loadFile } from '../shared/loader';
import { MarkdownHeading, getHeadings } from '../shared/markdown';

const sectionSeparator = /(?:\n\n|\r\n\r\n)---(?:\n\n|\r\n\r\n)/;
const sectionSeparator = /(?:\n\n|\r\n\r\n)(?:---|===)(?:\n\n|\r\n\r\n)/;

export interface WorkshopSection {
title: string;
Expand Down Expand Up @@ -33,6 +33,26 @@ export async function loadWorkshop(repoPath: string, options?: LoaderOptions): P
markdown = `<h1 class="visually-hidden">${fileContents.meta.title}</h1>\n\n${markdown}`;
}

function replaceMarkdownTag(markdown: string, tag: string, className: string, dataTitle: string): string {
const regex = new RegExp(`> \\[!${tag}]\\n(> .*\\n)*`, 'gi');
return markdown.replace(regex, (match) => {
const contentWithoutTag = match.replace(new RegExp(`> \\[!${tag}]\\n`, 'i'), '');
return `<div class="${className}" data-title="${dataTitle}">\n\n${contentWithoutTag}\n</div>\n`;
});
}

markdown = replaceMarkdownTag(markdown, 'KNOWLEDGE', 'info', 'info');
markdown = replaceMarkdownTag(markdown, 'ALERT', 'important', 'important');
markdown = replaceMarkdownTag(markdown, 'NOTE', 'info', 'note');
markdown = replaceMarkdownTag(markdown, 'HELP', 'warning', 'warning');
markdown = replaceMarkdownTag(markdown, 'HINT', 'tip', 'tip');

// Replace all occurrences of the @lab.CloudPortalCredential(*).Username markdown tag with a placeholder
markdown = markdown.replace(/@lab\.CloudPortalCredential\([^)]+\)\.Username/gi, '<replace_with_dev_user_principal_name>');

// Replace all occurences of the @lab.CloudResourceTemplate(*).Outputs[*] markdown
markdown = markdown.replace(/@lab\.CloudResourceTemplate\([^)]+\)\.Outputs\[[^\]]+\]/gi, '<your_container_registry_url>');

return { title, headings, markdown };
});
return {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
apiVersion: azconfig.io/v1
kind: AzureAppConfigurationProvider
metadata:
name: devconfigs
spec:
endpoint: ${AC_ENDPOINT}
configuration:
refresh:
enabled: true
interval: 10s
monitoring:
keyValues:
- key: MyKey1
target:
configMapName: myconfigmap
auth:
workloadIdentity:
serviceAccountName: ${SA_NAME}
secret:
auth:
workloadIdentity:
serviceAccountName: ${SA_NAME}
target:
secretName: mysecret
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
{
"properties": {
"policyType": "Custom",
"mode": "Microsoft.Kubernetes.Data",
"displayName": "Approved registries only",
"description": "This policy requires that all containers in a Kubernetes cluster are sourced from approved container registries.",
"policyRule": {
"if": {
"field": "type",
"in": [
"Microsoft.ContainerService/managedClusters"
]
},
"then": {
"effect": "[parameters('effect')]",
"details": {
"templateInfo": {
"sourceType": "Base64Encoded",
"content": "YXBpVmVyc2lvbjogdGVtcGxhdGVzLmdhdGVrZWVwZXIuc2gvdjFiZXRhMQpraW5kOiBDb25zdHJhaW50VGVtcGxhdGUKbWV0YWRhdGE6CiAgbmFtZTogazhzcmVxdWlyZWRyZWdpc3RyeQpzcGVjOgogIGNyZDoKICAgIHNwZWM6CiAgICAgIG5hbWVzOgogICAgICAgIGtpbmQ6IEs4c1JlcXVpcmVkUmVnaXN0cnkKICAgICAgdmFsaWRhdGlvbjoKICAgICAgICBvcGVuQVBJVjNTY2hlbWE6CiAgICAgICAgICBwcm9wZXJ0aWVzOgogICAgICAgICAgICByZWdpc3RyeToKICAgICAgICAgICAgICB0eXBlOiBzdHJpbmcKICB0YXJnZXRzOgogICAgLSB0YXJnZXQ6IGFkbWlzc2lvbi5rOHMuZ2F0ZWtlZXBlci5zaAogICAgICByZWdvOiB8CiAgICAgICAgcGFja2FnZSBrOHNyZXF1aXJlZHJlZ2lzdHJ5CiAgICAgICAgdmlvbGF0aW9uW3sibXNnIjogbXNnLCAiZGV0YWlscyI6IHsiUmVnaXN0cnkgbXVzdCBiZSI6IHJlcXVpcmVkfX1dIHsKICAgICAgICAgIGlucHV0LnJldmlldy5vYmplY3Qua2luZCA9PSAiUG9kIgogICAgICAgICAgc29tZSBpCiAgICAgICAgICBpbWFnZSA6PSBpbnB1dC5yZXZpZXcub2JqZWN0LnNwZWMuY29udGFpbmVyc1tpXS5pbWFnZQogICAgICAgICAgcmVxdWlyZWQgOj0gaW5wdXQucGFyYW1ldGVycy5yZWdpc3RyeQogICAgICAgICAgbm90IHN0YXJ0c3dpdGgoaW1hZ2UscmVxdWlyZWQpCiAgICAgICAgICBtc2cgOj0gc3ByaW50ZigiRm9yYmlkZGVuIHJlZ2lzdHJ5OiAldiIsIFtpbWFnZV0pCiAgICAgICAgfQo="
},
"apiGroups": [
""
],
"kinds": [
"Pod"
],
"namespaces": "[parameters('namespaces')]",
"excludedNamespaces": "[parameters('excludedNamespaces')]",
"labelSelector": "[parameters('labelSelector')]",
"values": {
"registry": "[parameters('registry')]"
}
}
}
},
"parameters": {
"effect": {
"type": "String",
"metadata": {
"displayName": "Effect",
"description": "'audit' allows a non-compliant resource to be created or updated, but flags it as non-compliant. 'deny' blocks the non-compliant resource creation or update. 'disabled' turns off the policy."
},
"allowedValues": [
"audit",
"deny",
"disabled"
],
"defaultValue": "audit"
},
"excludedNamespaces": {
"type": "Array",
"metadata": {
"displayName": "Namespace exclusions",
"description": "List of Kubernetes namespaces to exclude from policy evaluation."
},
"defaultValue": [
"kube-system",
"gatekeeper-system",
"azure-arc"
]
},
"namespaces": {
"type": "Array",
"metadata": {
"displayName": "Namespace inclusions",
"description": "List of Kubernetes namespaces to only include in policy evaluation. An empty list means the policy is applied to all resources in all namespaces."
},
"defaultValue": []
},
"labelSelector": {
"type": "Object",
"metadata": {
"displayName": "Kubernetes label selector",
"description": "Label query to select Kubernetes resources for policy evaluation. An empty label selector matches all Kubernetes resources."
},
"defaultValue": {},
"schema": {
"description": "A label selector is a label query over a set of resources. The result of matchLabels and matchExpressions are ANDed. An empty label selector matches all resources.",
"type": "object",
"properties": {
"matchLabels": {
"description": "matchLabels is a map of {key,value} pairs.",
"type": "object",
"additionalProperties": {
"type": "string"
},
"minProperties": 1
},
"matchExpressions": {
"description": "matchExpressions is a list of values, a key, and an operator.",
"type": "array",
"items": {
"type": "object",
"properties": {
"key": {
"description": "key is the label key that the selector applies to.",
"type": "string"
},
"operator": {
"description": "operator represents a key's relationship to a set of values.",
"type": "string",
"enum": [
"In",
"NotIn",
"Exists",
"DoesNotExist"
]
},
"values": {
"description": "values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty.",
"type": "array",
"items": {
"type": "string"
}
}
},
"required": [
"key",
"operator"
],
"additionalProperties": false
},
"minItems": 1
}
},
"additionalProperties": false
}
},
"registry": {
"type": "String",
"metadata": {
"displayName": "Image registry",
"description": "The container image registry to allow."
}
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
apiVersion: templates.gatekeeper.sh/v1beta1
kind: ConstraintTemplate
metadata:
name: k8srequiredregistry
spec:
crd:
spec:
names:
kind: K8sRequiredRegistry
validation:
openAPIV3Schema:
properties:
registry:
type: string
targets:
- target: admission.k8s.gatekeeper.sh
rego: |
package k8srequiredregistry
violation[{"msg": msg, "details": {"Registry must be": required}}] {
input.review.object.kind == "Pod"
some i
image := input.review.object.spec.containers[i].image
required := input.parameters.registry
not startswith(image,required)
msg := sprintf("Forbidden registry: %v", [image])
}
27 changes: 27 additions & 0 deletions workshops/operating-aks-automatic/assets/files/nginx.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
apiVersion: v1
kind: Pod
metadata:
labels:
run: mynginx
name: mynginx
spec:
containers:
- image: nginx:latest
name: mynginx
resources:
limits:
cpu: 5m
memory: 4Mi
requests:
cpu: 3m
memory: 2Mi
livenessProbe:
tcpSocket:
port: 80
initialDelaySeconds: 3
periodSeconds: 3
readinessProbe:
tcpSocket:
port: 80
initialDelaySeconds: 3
periodSeconds: 3
40 changes: 40 additions & 0 deletions workshops/operating-aks-automatic/assets/files/nodepool.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
apiVersion: karpenter.sh/v1beta1
kind: NodePool
metadata:
annotations:
kubernetes.io/description: General purpose NodePool for dev workloads
name: devpool
spec:
disruption:
budgets:
- nodes: 100%
consolidationPolicy: WhenUnderutilized
expireAfter: Never
template:
metadata:
labels:
team: dev
spec:
nodeClassRef:
name: default
taints:
- key: team
value: dev
effect: NoSchedule
requirements:
- key: kubernetes.io/arch
operator: In
values:
- arm64
- key: kubernetes.io/os
operator: In
values:
- linux
- key: karpenter.sh/capacity-type
operator: In
values:
- on-demand
- key: karpenter.azure.com/sku-family
operator: In
values:
- D
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: product-service
namespace: dev
spec:
replicas: 3
selector:
matchLabels:
app: product-service
template:
metadata:
labels:
app: product-service
spec:
containers:
- name: product-service
image: ${ACR_NAME}.azurecr.io/product-service:1.5.2
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: team
operator: In
values:
- dev
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: app
operator: In
values:
- product-service
topologyKey: "kubernetes.io/hostname"
tolerations:
- key: "team"
operator: "Equal"
value: "dev"
effect: "NoSchedule"
topologySpreadConstraints:
- maxSkew: 1
topologyKey: "topology.kubernetes.io/zone"
whenUnsatisfiable: DoNotSchedule
labelSelector:
matchLabels:
app: product-service
32 changes: 32 additions & 0 deletions workshops/operating-aks-automatic/assets/files/productservice.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: product-service
namespace: dev
spec:
replicas: 3
selector:
matchLabels:
app: product-service
template:
metadata:
labels:
app: product-service
spec:
containers:
- name: product-service
image: ${ACR_NAME}.azurecr.io/product-service:1.5.2
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: team
operator: In
values:
- dev
tolerations:
- key: "team"
operator: "Equal"
value: "dev"
effect: "NoSchedule"
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
apiVersion: "autoscaling.k8s.io/v1"
kind: VerticalPodAutoscaler
metadata:
name: product-service-vpa
namespace: dev
spec:
targetRef:
apiVersion: "apps/v1"
kind: Deployment
name: product-service
Loading

0 comments on commit 48ef5ef

Please sign in to comment.