|
| 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: shenmuxiaosen |
| 6 | +manager: zhenlan |
| 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 | +Helm provides a way to define, install, and upgrade applications running in Kubernetes. A Helm chart contains the information necessary to create an instance of a Kubernetes application. Configuration is stored outside of the chart itself, in a file called *values.yaml*. |
| 18 | + |
| 19 | +During the release process, Helm merges the chart with the proper configuration to run the application. For example, variables defined in *values.yaml* can be referenced as environment variables inside the running containers. Helm also supports creation of Kubernetes Secrets, which can be mounted as data volumes or exposed as environment variables. |
| 20 | + |
| 21 | +You can override the values stored in *values.yaml* by providing additional YAML-based configuration files on the command line when running Helm. Azure App Configuration supports exporting configuration values to YAML files. Integrating this export capability into your deployment allows your Kubernetes applications to leverage configuration values stored in App Configuration. |
| 22 | + |
| 23 | +In this tutorial, you learn how to: |
| 24 | +> [!div class="checklist"] |
| 25 | +> * Use values from App Configuration when deploying an application to Kubernetes using Helm. |
| 26 | +> * Create a Kubernetes Secret based on a Key Vault reference in App Configuration. |
| 27 | +
|
| 28 | +This tutorial assumes basic understanding of managing Kubernetes with Helm. |
| 29 | +Learn more about installing applications with Helm in [Azure Kubernetes Service](https://docs.microsoft.com/azure/aks/kubernetes-helm). |
| 30 | + |
| 31 | +## Prerequisites |
| 32 | + |
| 33 | +- [!INCLUDE [quickstarts-free-trial-note](../../includes/quickstarts-free-trial-note.md)] |
| 34 | +- Install [Azure CLI](https://docs.microsoft.com/cli/azure/install-azure-cli?view=azure-cli-latest) (version 2.4.0 or later) |
| 35 | +- Install [Helm](https://helm.sh/docs/intro/install/) (version 2.14.0 or later) |
| 36 | +- A Kubernetes cluster. |
| 37 | + |
| 38 | +## Create an App Configuration store |
| 39 | + |
| 40 | +[!INCLUDE [azure-app-configuration-create](../../includes/azure-app-configuration-create.md)] |
| 41 | + |
| 42 | +6. Select **Configuration Explorer** > **Create** to add the following key-value pairs: |
| 43 | + |
| 44 | + | Key | Value | |
| 45 | + |---|---| |
| 46 | + | settings.color | White | |
| 47 | + | settings.message | Data from Azure App Configuration | |
| 48 | + |
| 49 | + Leave **Label** and **Content Type** empty for now. |
| 50 | + |
| 51 | +## Add a Key Vault reference to App Configuration |
| 52 | +1. Sign in to the [Azure portal](https://portal.azure.com) and add a secret to [Key Vault](https://docs.microsoft.com/azure/key-vault/secrets/quick-create-portal#add-a-secret-to-key-vault) with name **Password** and value **myPassword**. |
| 53 | +2. Select the App Configuration store instance that you created in previous section. |
| 54 | + |
| 55 | +3. Select **Configuration Explorer**. |
| 56 | + |
| 57 | +4. Select **+ Create** > **Key vault reference**, and then specify the following values: |
| 58 | + - **Key**: Select **secrets.password**. |
| 59 | + - **Label**: Leave this value blank. |
| 60 | + - **Subscription**, **Resource group**, and **Key vault**: Enter the values corresponding to those in the key vault you created in previous step. |
| 61 | + - **Secret**: Select the secret named **Password** that you created in the previous section. |
| 62 | + |
| 63 | +## Create Helm chart ## |
| 64 | +First, create a sample Helm chart with the following command |
| 65 | +```console |
| 66 | +helm create mychart |
| 67 | +``` |
| 68 | + |
| 69 | +Helm creates a new directory called mychart with the structure shown below. |
| 70 | + |
| 71 | +> [!TIP] |
| 72 | +> Follow this [charts guide](https://helm.sh/docs/chart_template_guide/getting_started/) to learn more. |
| 73 | +
|
| 74 | +``` |
| 75 | +mychart |
| 76 | +|-- Chart.yaml |
| 77 | +|-- charts |
| 78 | +|-- templates |
| 79 | +| |-- NOTES.txt |
| 80 | +| |-- _helpers.tpl |
| 81 | +| |-- deployment.yaml |
| 82 | +| |-- ingress.yaml |
| 83 | +| `-- service.yaml |
| 84 | +`-- values.yaml |
| 85 | +``` |
| 86 | + |
| 87 | +Next, update the **spec:template:spec:containers** section of the *deployment.yaml* file. The following snippet adds two environment variables to the container. You'll set their values dynamically at deployment time. |
| 88 | + |
| 89 | +```yaml |
| 90 | +env: |
| 91 | +- name: Color |
| 92 | + value: {{ .Values.settings.color }} |
| 93 | +- name: Message |
| 94 | + value: {{ .Values.settings.message }} |
| 95 | +``` |
| 96 | +
|
| 97 | +The complete *deployment.yaml* file after the update should look like below. |
| 98 | +
|
| 99 | +```yaml |
| 100 | +apiVersion: apps/v1beta2 |
| 101 | +kind: Deployment |
| 102 | +metadata: |
| 103 | + name: {{ include "mychart.fullname" . }} |
| 104 | + labels: |
| 105 | + app.kubernetes.io/name: {{ include "mychart.name" . }} |
| 106 | + helm.sh/chart: {{ include "mychart.chart" . }} |
| 107 | + app.kubernetes.io/instance: {{ .Release.Name }} |
| 108 | + app.kubernetes.io/managed-by: {{ .Release.Service }} |
| 109 | +spec: |
| 110 | + replicas: {{ .Values.replicaCount }} |
| 111 | + selector: |
| 112 | + matchLabels: |
| 113 | + app.kubernetes.io/name: {{ include "mychart.name" . }} |
| 114 | + app.kubernetes.io/instance: {{ .Release.Name }} |
| 115 | + template: |
| 116 | + metadata: |
| 117 | + labels: |
| 118 | + app.kubernetes.io/name: {{ include "mychart.name" . }} |
| 119 | + app.kubernetes.io/instance: {{ .Release.Name }} |
| 120 | + spec: |
| 121 | + containers: |
| 122 | + - name: {{ .Chart.Name }} |
| 123 | + image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}" |
| 124 | + imagePullPolicy: {{ .Values.image.pullPolicy }} |
| 125 | + env: |
| 126 | + - name: Color |
| 127 | + value: {{ .Values.settings.color }} |
| 128 | + - name: Message |
| 129 | + value: {{ .Values.settings.message }} |
| 130 | + ports: |
| 131 | + - name: http |
| 132 | + containerPort: 80 |
| 133 | + protocol: TCP |
| 134 | + livenessProbe: |
| 135 | + httpGet: |
| 136 | + path: / |
| 137 | + port: http |
| 138 | + readinessProbe: |
| 139 | + httpGet: |
| 140 | + path: / |
| 141 | + port: http |
| 142 | + resources: |
| 143 | +{{ toYaml .Values.resources | indent 12 }} |
| 144 | + {{- with .Values.nodeSelector }} |
| 145 | + nodeSelector: |
| 146 | +{{ toYaml . | indent 8 }} |
| 147 | + {{- end }} |
| 148 | + {{- with .Values.affinity }} |
| 149 | + affinity: |
| 150 | +{{ toYaml . | indent 8 }} |
| 151 | + {{- end }} |
| 152 | + {{- with .Values.tolerations }} |
| 153 | + tolerations: |
| 154 | +{{ toYaml . | indent 8 }} |
| 155 | + {{- end }} |
| 156 | +``` |
| 157 | + |
| 158 | +To store sensitive data as Kubernetes Secrets, add a *secrets.yaml* file under the templates folder. |
| 159 | + |
| 160 | +> [!TIP] |
| 161 | +> Learn more about how to use [Kubernetes Secrets](https://kubernetes.io/docs/concepts/configuration/secret/#using-secrets). |
| 162 | +
|
| 163 | +```yaml |
| 164 | +apiVersion: v1 |
| 165 | +kind: Secret |
| 166 | +metadata: |
| 167 | + name: mysecret |
| 168 | +type: Opaque |
| 169 | +data: |
| 170 | + password: {{ .Values.secrets.password }} |
| 171 | +``` |
| 172 | +
|
| 173 | +Finally, update the *values.yaml* file with the following content to optionally provide default values of the configuration settings and secrets that referenced in the *deployment.yaml* and *secrets.yaml* files. Their actual values will be overwritten by configuration pulled from App Configuration. |
| 174 | +
|
| 175 | +```yaml |
| 176 | +# settings will be overwritten by App Configuration |
| 177 | +settings: |
| 178 | + color: red |
| 179 | + message: myMessage |
| 180 | +``` |
| 181 | + |
| 182 | +## Pass configuration from App Configuration in Helm install ## |
| 183 | +First, download the configuration from App Configuration to a *myConfig.yaml* file. Use a key filter to only download those keys that start with **settings.**. If in your case the key filter is not sufficient to exclude keys of Key Vault references, you may use the argument **--skip-keyvault** to exclude them. |
| 184 | + |
| 185 | +> [!TIP] |
| 186 | +> Learn more about the [export command](https://docs.microsoft.com/cli/azure/appconfig/kv?view=azure-cli-latest#az-appconfig-kv-export). |
| 187 | +
|
| 188 | +```azurecli-interactive |
| 189 | +az appconfig kv export -n myAppConfiguration -d file --path myConfig.yaml --key "settings.*" --separator "." --format yaml |
| 190 | +``` |
| 191 | + |
| 192 | +Next, download secrets to a file called *mySecrets.yaml*. The command-line argument **--resolve-keyvault** resolves the Key Vault references by retrieving the actual values in Key Vault. You'll need to run this command with credentials that have access permissions to the corresponding Key Vault. |
| 193 | + |
| 194 | +> [!WARNING] |
| 195 | +> As this file contains sensitive information, keep the file with care and clean up when it's not needed anymore. |
| 196 | +
|
| 197 | +```azurecli-interactive |
| 198 | +az appconfig kv export -n myAppConfiguration -d file --path mySecrets.yaml --key "secrets.*" --separator "." --resolve-keyvault --format yaml |
| 199 | +``` |
| 200 | + |
| 201 | +Use helm upgrade's **-f** argument to pass in the two configuration files you've created. They'll override the configuration values defined in *values.yaml* with the values exported from App Configuration. |
| 202 | + |
| 203 | +```console |
| 204 | +helm upgrade --install -f myConfig.yaml -f mySecrets.yaml "example" ./mychart |
| 205 | +``` |
| 206 | + |
| 207 | +You can also use the **--set** argument for helm upgrade to pass literal key values. Using the **--set** argument is a good way to avoid persisting sensitive data to disk. |
| 208 | + |
| 209 | +```powershell |
| 210 | +$secrets = az appconfig kv list -n myAppConfiguration --key "secrets.*" --resolve-keyvault --query "[*].{name:key, value:value}" | ConvertFrom-Json |
| 211 | +
|
| 212 | +foreach ($secret in $secrets) { |
| 213 | + $keyvalues += $secret.name + "=" + $secret.value + "," |
| 214 | +} |
| 215 | +
|
| 216 | +if ($keyvalues){ |
| 217 | + $keyvalues = $keyvalues.TrimEnd(',') |
| 218 | + helm upgrade --install --set $keyvalues "example" ./mychart |
| 219 | +} |
| 220 | +else{ |
| 221 | + helm upgrade --install "example" ./mychart |
| 222 | +} |
| 223 | +
|
| 224 | +``` |
| 225 | + |
| 226 | +Verify that configurations and secrets were set successfully by accessing the [Kubernetes Dashboard](https://docs.microsoft.com/azure/aks/kubernetes-dashboard). You'll see that the **color** and **message** values from App Configuration were populated into the container's environment variables. |
| 227 | + |
| 228 | + |
| 229 | + |
| 230 | +One secret, **password**, stores as Key Vault reference in App Configuration was also added into Kubernetes Secrets. |
| 231 | + |
| 232 | + |
| 233 | + |
| 234 | +## Clean up resources |
| 235 | + |
| 236 | +[!INCLUDE [azure-app-configuration-cleanup](../../includes/azure-app-configuration-cleanup.md)] |
| 237 | + |
| 238 | +## Next steps |
| 239 | + |
| 240 | +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. |
| 241 | + |
| 242 | +> [!div class="nextstepaction"] |
| 243 | +> [Azure CLI](https://docs.microsoft.com/cli/azure/appconfig?view=azure-cli-latest) |
0 commit comments