|
| 1 | +--- |
| 2 | +title: "Integrate Azure App Configuration with Kubernetes Deployment using Helm" |
| 3 | +description: Learn how to use dynamic configurations in Kubernetes deployment with Helm. |
| 4 | +services: azure-app-configuration |
| 5 | +author: shuawan |
| 6 | +manager: zhenlwa |
| 7 | + |
| 8 | +ms.service: azure-app-configuration |
| 9 | +ms.topic: tutorial |
| 10 | +ms.date: 04/14/2020 |
| 11 | +ms.author: shuawan |
| 12 | + |
| 13 | +#Customer intent: I want to use Azure App Configuration data in Kubernetes deployment with Helm. |
| 14 | +--- |
| 15 | +# Integrate with Kubernetes Deployment Using Helm |
| 16 | + |
| 17 | +This article explains how to use data from Azure App Configuration in Kubernetes deployment with Helm. |
| 18 | + |
| 19 | +## Prerequisites |
| 20 | + |
| 21 | +- [!INCLUDE [quickstarts-free-trial-note](../../includes/quickstarts-free-trial-note.md)] |
| 22 | +- Install [Azure CLI](https://docs.microsoft.com/en-us/cli/azure/install-azure-cli?view=azure-cli-latest) |
| 23 | +- Install [Helm](https://helm.sh/docs/intro/install/) |
| 24 | +- Background knowledge for installing applications with Helm in [Azure Kubernetes Service](https://docs.microsoft.com/en-us/azure/aks/kubernetes-helm) |
| 25 | + |
| 26 | +## Create Helm chart ## |
| 27 | +```powershell |
| 28 | +# Create sample Helm chart |
| 29 | +helm create mychart |
| 30 | +``` |
| 31 | +Helm will create a new directory in your project called mychart with the structure shown below. |
| 32 | +``` |
| 33 | +mychart |
| 34 | +|-- Chart.yaml |
| 35 | +|-- charts |
| 36 | +|-- templates |
| 37 | +| |-- NOTES.txt |
| 38 | +| |-- _helpers.tpl |
| 39 | +| |-- deployment.yaml |
| 40 | +| |-- ingress.yaml |
| 41 | +| `-- service.yaml |
| 42 | +`-- values.yaml |
| 43 | +``` |
| 44 | + |
| 45 | +Details to understand [mychart](https://helm.sh/docs/chart_template_guide/getting_started/) |
| 46 | + |
| 47 | +Based on the sample **deployment.yaml** file, we modify the chart to add some environment variables to container under ```spec:template:spec:containers```. Although this setting won't be used by the application, it shows as an example for how to dynamically pass configurations into Helm deployment. |
| 48 | + |
| 49 | +```yaml |
| 50 | +env: |
| 51 | +- name: Color |
| 52 | + value: {{ .Values.color }} |
| 53 | +- name: Message |
| 54 | + value: {{ .Values.message }} |
| 55 | +``` |
| 56 | +
|
| 57 | +The modified deployment.yaml should look like below. |
| 58 | +
|
| 59 | +```yaml |
| 60 | +apiVersion: apps/v1beta2 |
| 61 | +kind: Deployment |
| 62 | +metadata: |
| 63 | + name: {{ include "mychart.fullname" . }} |
| 64 | + labels: |
| 65 | + app.kubernetes.io/name: {{ include "mychart.name" . }} |
| 66 | + helm.sh/chart: {{ include "mychart.chart" . }} |
| 67 | + app.kubernetes.io/instance: {{ .Release.Name }} |
| 68 | + app.kubernetes.io/managed-by: {{ .Release.Service }} |
| 69 | +spec: |
| 70 | + replicas: {{ .Values.replicaCount }} |
| 71 | + selector: |
| 72 | + matchLabels: |
| 73 | + app.kubernetes.io/name: {{ include "mychart.name" . }} |
| 74 | + app.kubernetes.io/instance: {{ .Release.Name }} |
| 75 | + template: |
| 76 | + metadata: |
| 77 | + labels: |
| 78 | + app.kubernetes.io/name: {{ include "mychart.name" . }} |
| 79 | + app.kubernetes.io/instance: {{ .Release.Name }} |
| 80 | + spec: |
| 81 | + containers: |
| 82 | + - name: {{ .Chart.Name }} |
| 83 | + image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}" |
| 84 | + imagePullPolicy: {{ .Values.image.pullPolicy }} |
| 85 | + env: |
| 86 | + - name: Color |
| 87 | + value: {{ .Values.color }} |
| 88 | + - name: Message |
| 89 | + value: {{ .Values.message }} |
| 90 | + ports: |
| 91 | + - name: http |
| 92 | + containerPort: 80 |
| 93 | + protocol: TCP |
| 94 | + livenessProbe: |
| 95 | + httpGet: |
| 96 | + path: / |
| 97 | + port: http |
| 98 | + readinessProbe: |
| 99 | + httpGet: |
| 100 | + path: / |
| 101 | + port: http |
| 102 | + resources: |
| 103 | +{{ toYaml .Values.resources | indent 12 }} |
| 104 | + {{- with .Values.nodeSelector }} |
| 105 | + nodeSelector: |
| 106 | +{{ toYaml . | indent 8 }} |
| 107 | + {{- end }} |
| 108 | + {{- with .Values.affinity }} |
| 109 | + affinity: |
| 110 | +{{ toYaml . | indent 8 }} |
| 111 | + {{- end }} |
| 112 | + {{- with .Values.tolerations }} |
| 113 | + tolerations: |
| 114 | +{{ toYaml . | indent 8 }} |
| 115 | + {{- end }} |
| 116 | +``` |
| 117 | + |
| 118 | +In addition, add **secrets.yaml** under templates for Kubernetes Secrets, which is used to store and manage sensitive information, such as passwords. Same with environment variables, Secrets can also be referenced by application. |
| 119 | +```yaml |
| 120 | +apiVersion: v1 |
| 121 | +kind: Secret |
| 122 | +metadata: |
| 123 | + name: mysecret |
| 124 | +type: Opaque |
| 125 | +data: |
| 126 | + password: {{ .Values.password }} |
| 127 | +``` |
| 128 | +
|
| 129 | +In **values.yaml**, there are some default settings used for chart. Let's add some place holder for configurations we added above. Settings in **values.yaml** can be later on combined and overwritten by configurations pulled from App Configuration. |
| 130 | +
|
| 131 | +```yaml |
| 132 | +# Default values for mychart. |
| 133 | +# This is a YAML-formatted file. |
| 134 | +# Declare variables to be passed into your templates. |
| 135 | + |
| 136 | +replicaCount: 1 |
| 137 | + |
| 138 | +image: |
| 139 | + repository: nginx |
| 140 | + tag: stable |
| 141 | + pullPolicy: IfNotPresent |
| 142 | + |
| 143 | +nameOverride: "" |
| 144 | +fullnameOverride: "" |
| 145 | + |
| 146 | +service: |
| 147 | + type: ClusterIP |
| 148 | + port: 80 |
| 149 | + |
| 150 | +ingress: |
| 151 | + enabled: false |
| 152 | + annotations: {} |
| 153 | + # kubernetes.io/ingress.class: nginx |
| 154 | + # kubernetes.io/tls-acme: "true" |
| 155 | + path: / |
| 156 | + hosts: |
| 157 | + - chart-example.local |
| 158 | + tls: [] |
| 159 | + # - secretName: chart-example-tls |
| 160 | + # hosts: |
| 161 | + # - chart-example.local |
| 162 | + |
| 163 | +resources: {} |
| 164 | + # We usually recommend not to specify default resources and to leave this as a conscious |
| 165 | + # choice for the user. This also increases chances charts run on environments with little |
| 166 | + # resources, such as Minikube. If you do want to specify resources, uncomment the following |
| 167 | + # lines, adjust them as necessary, and remove the curly braces after 'resources:'. |
| 168 | + # limits: |
| 169 | + # cpu: 100m |
| 170 | + # memory: 128Mi |
| 171 | + # requests: |
| 172 | + # cpu: 100m |
| 173 | + # memory: 128Mi |
| 174 | + |
| 175 | +nodeSelector: {} |
| 176 | + |
| 177 | +tolerations: [] |
| 178 | + |
| 179 | +affinity: {} |
| 180 | + |
| 181 | +# settings will be overwritten by App Configuration |
| 182 | +color: red |
| 183 | +message: myMessage |
| 184 | + |
| 185 | +password: null |
| 186 | +``` |
| 187 | +
|
| 188 | +## Create an App Configuration store |
| 189 | +
|
| 190 | +[!INCLUDE [azure-app-configuration-create](../../includes/azure-app-configuration-create.md)] |
| 191 | +
|
| 192 | +6. Select **Configuration Explorer** > **Create** to add the following key-value pairs: |
| 193 | +
|
| 194 | + | Key | Value | |
| 195 | + |---|---| |
| 196 | + | color | White | |
| 197 | + | message | Data from Azure App Configuration | |
| 198 | +
|
| 199 | + Leave **Label** and **Content Type** empty for now. |
| 200 | +
|
| 201 | +## Add a secret to Key Vault |
| 202 | +
|
| 203 | +To add a secret to the vault, you need to take just a few additional steps. In this case, add a message that you can use to test Key Vault retrieval. The message is called **Message**, and you store the value "Hello from Key Vault" in it. |
| 204 | +
|
| 205 | +1. From the Key Vault properties pages, select **Secrets**. |
| 206 | +1. Select **Generate/Import**. |
| 207 | +1. In the **Create a secret** pane, enter the following values: |
| 208 | + - **Upload options**: Enter **Manual**. |
| 209 | + - **Name**: Enter **Password**. |
| 210 | + - **Value**: Enter **myPassword**. |
| 211 | +1. Leave the other **Create a secret** properties with their default values. |
| 212 | +1. Select **Create**. |
| 213 | +
|
| 214 | +## Add a Key Vault reference to App Configuration |
| 215 | +
|
| 216 | +1. Sign in to the [Azure portal](https://portal.azure.com). Select **All resources**, and then select the App Configuration store instance that you created in the quickstart. |
| 217 | +
|
| 218 | +1. Select **Configuration Explorer**. |
| 219 | +
|
| 220 | +1. Select **+ Create** > **Key vault reference**, and then specify the following values: |
| 221 | + - **Key**: Select **KVRef_password**. |
| 222 | + - **Label**: Leave this value blank. |
| 223 | + - **Subscription**, **Resource group**, and **Key vault**: Enter the values corresponding to those in the key vault you created in the previous section. |
| 224 | + - **Secret**: Select the secret named **Password** that you created in the previous section. |
| 225 | +
|
| 226 | +## Merge data from App Configuration ## |
| 227 | +In App Configuration, there are normal configurations along with key vault references and if no need to resolve those references in deployment time, then pull all data in one shot. |
| 228 | +```PowerShell |
| 229 | +$ConfigFilePath="config.yaml" |
| 230 | + |
| 231 | +# Export configurations to local files |
| 232 | +az appconfig kv export -n myAppConfiguration -d file --path config.yaml --format yaml -y |
| 233 | +``` |
| 234 | + |
| 235 | +If there is a need to resolve the content of key vault references like secrets, then separate them into two files. |
| 236 | +```PowerShell |
| 237 | +$ConfigFilePath=config.yaml |
| 238 | +$SecretPath=secrets.yaml |
| 239 | +
|
| 240 | +# Export configurations excluding key vault reference to local files |
| 241 | +az appconfig kv export -n myAppConfiguration -d file --path $ConfigFilePath --skip-keyvault --format yaml -y |
| 242 | +
|
| 243 | +# Export content of key vault references to local files |
| 244 | +az appconfig kv export --key "KVRef_*" --prefix "KVRef_" -n myAppConfiguration -d file --path $SecretPath --resolve-keyvault --format yaml -y |
| 245 | +
|
| 246 | +# Export content of key vault references to memory if there is concern for putting sensitive data in persistent storage. |
| 247 | +$data = az appconfig kv list --key "KVRef_*" -n myAppConfiguration --resolve-keyvault |
| 248 | +``` |
| 249 | + |
| 250 | +There are [two ways](https://helm.sh/docs/intro/using_helm/) to pass configuration data during helm install. Helm allow passing files or literal key values to overwrite settings specified in values.yaml. |
| 251 | +```PowerShell |
| 252 | +# Deploy the helm chart. |
| 253 | +helm upgrade --install -f $ConfigFilePath -f $SecretPath --set service.type=NodePort "example" ./mychart |
| 254 | +``` |
| 255 | + |
| 256 | +We can verify by accessing [Kubernetes Dashboard](https://docs.microsoft.com/en-us/azure/aks/kubernetes-dashboard) |
| 257 | + |
| 258 | + |
| 259 | + |
| 260 | +## Clean up resources |
| 261 | + |
| 262 | +[!INCLUDE [azure-app-configuration-cleanup](../../includes/azure-app-configuration-cleanup.md)] |
| 263 | + |
| 264 | +## Next steps |
| 265 | + |
| 266 | +In this tutorial, you exported Azure App Configuration data to be used in a Kubernetes deployment with Helm. To learn more about how to use App Configuration, continue to the Azure CLI samples. |
| 267 | + |
| 268 | +> [!div class="nextstepaction"] |
| 269 | +> [Managed identity integration](./howto-integrate-azure-managed-service-identity.md) |
0 commit comments