Skip to content

Commit 005acc7

Browse files
authored
Merge pull request #36 from comet-ml/CRThaze/s3proxy-azureblob-managed-identity
feat(azureblob): support Azure Managed/Workload Identity
2 parents 685ff4a + 02601b1 commit 005acc7

6 files changed

Lines changed: 92 additions & 9 deletions

File tree

‎.github/workflows/lint-render.yaml‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ jobs:
3030
- test-values/s3.yaml
3131
- test-values/azureblob.yaml
3232
- test-values/azureblob-existing-secret.yaml
33+
- test-values/azureblob-managed-identity.yaml
3334
- test-values/gcs.yaml
3435
- test-values/b2.yaml
3536
- test-values/openstack-swift.yaml

‎charts/s3proxy/Chart.yaml‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ type: application
1515
# This is the chart version. This version number should be incremented each time you make changes
1616
# to the chart and its templates, including the app version.
1717
# Versions are expected to follow Semantic Versioning (https://semver.org/)
18-
version: 0.4.2
18+
version: 0.4.3
1919

2020
# This is the version number of the application being deployed. This version number should be
2121
# incremented each time you make changes to the application. Versions are not expected to

‎charts/s3proxy/README.md.gotmpl‎

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ The chart tracks S3Proxy (`andrewgaul/s3proxy`) through `appVersion` (currently
2626
S3Proxy `3.0.0` deprecated the Apache jclouds storage backends (`s3`, `aws-s3`, `azureblob`, `filesystem`, `transient`) in favor of SDK / NIO2 providers. Upstream has announced that `3.3.0` is the last release to bundle jclouds and that future releases "will lack its Atmos and B2 storage backends" (no jclouds-free release has shipped yet; `3.3.0` remains the latest). The jclouds providers still work on 3.x, but are deprecated:
2727

2828
- `filesystem` / `transient`: already default to the non-deprecated `*-nio2` variants (`nio2: true`).
29-
- `azureblob`: **defaults to `provider: azureblob-sdk`** (the Azure SDK provider, which signs correctly against custom endpoints such as Azurite). The legacy jclouds `azureblob` provider is deprecated and mis-signs against custom endpoints; set `provider: azureblob` only if you specifically need it. On real Azure, `azureblob-sdk` may require `config.backends.azureblob.regions` for bucket creation.
29+
- `azureblob`: **defaults to `provider: azureblob-sdk`** (the Azure SDK provider, which signs correctly against custom endpoints such as Azurite). The legacy jclouds `azureblob` provider is deprecated and mis-signs against custom endpoints; set `provider: azureblob` only if you specifically need it. On real Azure, `azureblob-sdk` may require `config.backends.azureblob.regions` for bucket creation. For AKS Managed/Workload Identity (no static key), set `config.backends.azureblob.managedIdentity: true` — see "Example 3b" below.
3030
- `s3`, `googleCloudStorage`, `openstackSwift`: SDK providers exist upstream (`aws-s3-sdk`, `google-cloud-storage-sdk`, `openstack-swift-sdk`). `rackspaceCloudfiles` is OpenStack-Swift-compatible and may be served by `openstack-swift-sdk`. Migrating the chart defaults to the SDK providers is tracked separately.
3131
- `b2` (and Atmos, if ever added) are jclouds-only with **no SDK successor**. These are the backends upstream has said future releases will drop.
3232

@@ -163,6 +163,40 @@ Install:
163163
helm install s3proxy-azure ./{{ template "chart.name" . }} -f values-azure.yaml
164164
```
165165

166+
### Example 3b: Azure Blob with Managed / Workload Identity (no static key)
167+
168+
On AKS with Workload Identity, set `managedIdentity: true` instead of an account
169+
key or SAS token. The chart then renders both `jclouds.identity` and
170+
`jclouds.credential` empty, which makes the `azureblob-sdk` provider fall back to
171+
Azure's `DefaultAzureCredential` — it reads the federated token AKS injects
172+
(`AZURE_CLIENT_ID` / `AZURE_TENANT_ID` / `AZURE_FEDERATED_TOKEN_FILE`). The storage
173+
account name goes in the endpoint, never in the identity.
174+
175+
```yaml
176+
# values-azure-mi.yaml
177+
config:
178+
backends:
179+
filesystem:
180+
enabled: false
181+
azureblob:
182+
enabled: true
183+
provider: "azureblob-sdk" # required: the legacy jclouds provider can't do token auth
184+
managedIdentity: true
185+
account: "mystorageaccount" # used for the endpoint; NOT emitted as jclouds.identity
186+
# endpoint: "https://mystorageaccount.blob.core.windows.net" # or set explicitly
187+
188+
# Bind the pod to the AKS user-assigned identity:
189+
serviceAccount:
190+
create: true
191+
annotations:
192+
azure.workload.identity/client-id: "<managed-identity-client-id>"
193+
podLabels:
194+
azure.workload.identity/use: "true"
195+
196+
persistence:
197+
enabled: false
198+
```
199+
166200
### Example 4: Google Cloud Storage Backend
167201

168202
```yaml

‎charts/s3proxy/templates/configmap.yaml‎

Lines changed: 28 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,19 @@ s3proxy.large-object-mocking=true
8787
{{- end }}
8888
{{- end }}
8989
{{- end }}
90+
{{- /* Fail fast on an Azure managed-identity config that can't authenticate, since
91+
the failure otherwise surfaces only at runtime as an opaque Azure SDK error. */}}
92+
{{- if and .Values.config.backends.azureblob.enabled .Values.config.backends.azureblob.managedIdentity }}
93+
{{- if ne .Values.config.backends.azureblob.provider "azureblob-sdk" }}
94+
{{- fail "config.backends.azureblob.managedIdentity requires provider=azureblob-sdk; the legacy jclouds azureblob provider cannot use Azure token auth." }}
95+
{{- end }}
96+
{{- if or .Values.config.backends.azureblob.key.value .Values.config.backends.azureblob.key.existingSecret .Values.config.backends.azureblob.sasToken.value }}
97+
{{- fail "config.backends.azureblob.managedIdentity conflicts with a static credential; a non-empty key.*/sasToken.* disables DefaultAzureCredential. Unset them." }}
98+
{{- end }}
99+
{{- if and (not .Values.config.backends.azureblob.account) (not .Values.config.backends.azureblob.endpoint) }}
100+
{{- fail "config.backends.azureblob.managedIdentity needs the storage endpoint; set config.backends.azureblob.account (default endpoint) or endpoint." }}
101+
{{- end }}
102+
{{- end }}
90103
apiVersion: v1
91104
kind: ConfigMap
92105
metadata:
@@ -174,15 +187,23 @@ data:
174187
# (otherwise "no jclouds.regions configured" -> InvalidLocationConstraint).
175188
jclouds.regions={{ .Values.config.backends.azureblob.regions }}
176189
{{- end }}
177-
{{- if .Values.config.backends.azureblob.account }}
190+
{{- if .Values.config.backends.azureblob.managedIdentity }}
191+
# Managed/Workload Identity: azureblob-sdk falls back to Azure's
192+
# DefaultAzureCredential (reads the AKS-injected AZURE_CLIENT_ID/TENANT_ID/
193+
# FEDERATED_TOKEN_FILE) only when BOTH identity and credential are empty. The
194+
# account name lives in jclouds.endpoint above, never in the identity.
195+
jclouds.identity=
196+
jclouds.credential=
197+
{{- else }}
198+
{{- if .Values.config.backends.azureblob.account }}
178199
jclouds.identity={{ .Values.config.backends.azureblob.account }}
179-
{{- end }}
180-
{{- /* With a key (key.value or key.existingSecret) the initContainer merges
181-
jclouds.credential in from a Secret. S3Proxy requires the property in every
182-
backend file, so emit it empty when neither is set (SAS-token or Azure
183-
Workload Identity auth). */}}
184-
{{- if and (not .Values.config.backends.azureblob.key.value) (not .Values.config.backends.azureblob.key.existingSecret) }}
200+
{{- end }}
201+
{{- /* With a key (key.value or key.existingSecret) the initContainer merges
202+
jclouds.credential in from a Secret. S3Proxy requires the property in every
203+
backend file, so emit it empty when neither is set (SAS-token auth). */}}
204+
{{- if and (not .Values.config.backends.azureblob.key.value) (not .Values.config.backends.azureblob.key.existingSecret) }}
185205
jclouds.credential=
206+
{{- end }}
186207
{{- end }}
187208
{{- range $index, $bucket := .Values.config.backends.azureblob.bucketLocators }}
188209
s3proxy.bucket-locator.{{ add $index 1 }}={{ $bucket }}

‎charts/s3proxy/values.yaml‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,8 @@ config:
234234
enabled: false
235235
# -- Provider type. Defaults to `azureblob-sdk` (Azure SDK): it signs correctly against custom endpoints (Azurite, Azure Gov/China, private endpoints) and is the non-deprecated provider on S3Proxy 3.x. The legacy jclouds `azureblob` provider is deprecated upstream and mis-signs against custom endpoints; on real Azure `azureblob-sdk` may require `regions` to be set for bucket creation.
236236
provider: "azureblob-sdk"
237+
# -- Use Azure Managed/Workload Identity instead of a static account key or SAS token. Requires `provider: azureblob-sdk`; mutually exclusive with `key.*` and `sasToken.*`. When true the chart renders both `jclouds.identity` and `jclouds.credential` empty, which makes azureblob-sdk fall back to Azure's `DefaultAzureCredential` (consuming the AKS workload-identity env `AZURE_CLIENT_ID`/`AZURE_TENANT_ID`/`AZURE_FEDERATED_TOKEN_FILE`). Set `account` (or `endpoint`) for the storage endpoint, annotate the ServiceAccount with `azure.workload.identity/client-id` (`serviceAccount.annotations`) and label the pod `azure.workload.identity/use: "true"` (`podLabels`).
238+
managedIdentity: false
237239
# -- Storage account name
238240
account: ""
239241
# -- Storage account key configuration
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# Render/lint scenario: Azure Blob with Managed/Workload Identity (no static key).
2+
# Proves the chart can render both jclouds.identity and jclouds.credential EMPTY so
3+
# azureblob-sdk uses DefaultAzureCredential — the account name lives in the endpoint,
4+
# never in jclouds.identity. Also exercises the workload-identity SA/pod wiring.
5+
config:
6+
auth:
7+
type: aws-v4
8+
identity: test-access-key
9+
secret: test-secret-key
10+
backends:
11+
filesystem:
12+
enabled: false
13+
azureblob:
14+
enabled: true
15+
provider: azureblob-sdk
16+
managedIdentity: true
17+
account: teststorageaccount
18+
serviceAccount:
19+
create: true
20+
annotations:
21+
azure.workload.identity/client-id: "00000000-0000-0000-0000-000000000000"
22+
podLabels:
23+
azure.workload.identity/use: "true"
24+
persistence:
25+
enabled: false

0 commit comments

Comments
 (0)