Skip to content

Commit 888fee6

Browse files
[feat]: allow adding resource policy to dynamodb tables (#154)
Issue #, if available: aws-controllers-k8s/community#2655 Description of changes: Allows to add a resource policy to a dynamodb table. By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.
1 parent 156aeb3 commit 888fee6

17 files changed

+707
-48
lines changed
Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
ack_generate_info:
2-
build_date: "2025-09-19T17:14:03Z"
2+
build_date: "2025-10-21T04:38:02Z"
33
build_hash: 6b4211163dcc34776b01da9a18217bac0f4103fd
44
go_version: go1.24.6
55
version: v0.52.0
6-
api_directory_checksum: bcdceff2d7ddf7c98141572260ef2e6cee8bf23f
6+
api_directory_checksum: d2887bf57c4e94a2687e17c41f74c875131c0beb
77
api_version: v1alpha1
88
aws_sdk_go_version: v1.32.6
99
generator_config_info:
10-
file_checksum: cc3489b53a45170d339a4de0d7d7ec0aa788955e
10+
file_checksum: 3c4832feff83bc9c29b40bc73bafc1d7e75ab1cd
1111
original_file_name: generator.yaml
1212
last_modification:
1313
reason: API generation

apis/v1alpha1/generator.yaml

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ ignore:
1111
# Replica of Spec.SSESpecification
1212
- TableDescription.SSEDescription
1313
- TableDescription.TableClassSummary
14-
- CreateTableInput.ResourcePolicy
1514
- CreateTableInput.WarmThroughput
1615
operations:
1716
UpdateGlobalTable:
@@ -29,7 +28,13 @@ resources:
2928
custom_field:
3029
list_of: CreateReplicationGroupMemberAction
3130
compare:
32-
is_ignored: true
31+
is_ignored: true
32+
ResourcePolicy:
33+
from:
34+
operation: PutResourcePolicy
35+
path: Policy
36+
compare:
37+
is_ignored: true
3338
GlobalSecondaryIndexesDescriptions:
3439
custom_field:
3540
list_of: GlobalSecondaryIndexDescription
@@ -74,7 +79,7 @@ resources:
7479
from:
7580
operation: UpdateContributorInsights
7681
path: ContributorInsightsAction
77-
compare:
82+
compare:
7883
is_ignored: true
7984
exceptions:
8085
errors:

apis/v1alpha1/table.go

Lines changed: 13 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

apis/v1alpha1/zz_generated.deepcopy.go

Lines changed: 5 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

config/crd/bases/dynamodb.services.k8s.aws_tables.yaml

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -325,6 +325,21 @@ spec:
325325
format: int64
326326
type: integer
327327
type: object
328+
resourcePolicy:
329+
description: |-
330+
An Amazon Web Services resource-based policy document in JSON format.
331+
332+
* The maximum size supported for a resource-based policy document is 20
333+
KB. DynamoDB counts whitespaces when calculating the size of a policy
334+
against this limit.
335+
336+
* Within a resource-based policy, if the action for a DynamoDB service-linked
337+
role (SLR) to replicate data for a global table is denied, adding or deleting
338+
a replica will fail with an error.
339+
340+
For a full list of all considerations that apply while attaching a resource-based
341+
policy, see Resource-based policy considerations (https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/rbac-considerations.html).
342+
type: string
328343
sseSpecification:
329344
description: Represents the settings used to enable server-side encryption.
330345
properties:

generator.yaml

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ ignore:
1111
# Replica of Spec.SSESpecification
1212
- TableDescription.SSEDescription
1313
- TableDescription.TableClassSummary
14-
- CreateTableInput.ResourcePolicy
1514
- CreateTableInput.WarmThroughput
1615
operations:
1716
UpdateGlobalTable:
@@ -29,7 +28,13 @@ resources:
2928
custom_field:
3029
list_of: CreateReplicationGroupMemberAction
3130
compare:
32-
is_ignored: true
31+
is_ignored: true
32+
ResourcePolicy:
33+
from:
34+
operation: PutResourcePolicy
35+
path: Policy
36+
compare:
37+
is_ignored: true
3338
GlobalSecondaryIndexesDescriptions:
3439
custom_field:
3540
list_of: GlobalSecondaryIndexDescription
@@ -74,7 +79,7 @@ resources:
7479
from:
7580
operation: UpdateContributorInsights
7681
path: ContributorInsightsAction
77-
compare:
82+
compare:
7883
is_ignored: true
7984
exceptions:
8085
errors:

go.mod

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ require (
1212
github.com/aws/aws-sdk-go-v2/service/dynamodb v1.39.8
1313
github.com/aws/smithy-go v1.22.2
1414
github.com/go-logr/logr v1.4.2
15+
github.com/micahhausler/aws-iam-policy v0.4.2
1516
github.com/spf13/pflag v1.0.5
1617
github.com/stretchr/testify v1.9.0
1718
k8s.io/api v0.32.1
@@ -20,6 +21,10 @@ require (
2021
sigs.k8s.io/controller-runtime v0.20.4
2122
)
2223

24+
// Temporary fix for github.com/micahhausler/aws-iam-policy. Awaiting for a-hilaly to send
25+
// a PR to micahhausler/aws-iam-policy to build Equal() method for PolicyDocument struct.
26+
replace github.com/micahhausler/aws-iam-policy => github.com/a-hilaly/aws-iam-policy v0.0.0-20231121054900-2c56e839ca53
27+
2328
require (
2429
github.com/aws/aws-sdk-go-v2/config v1.28.6 // indirect
2530
github.com/aws/aws-sdk-go-v2/credentials v1.17.47 // indirect

go.sum

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
github.com/a-hilaly/aws-iam-policy v0.0.0-20231121054900-2c56e839ca53 h1:2uNM0nR2WUDN88EYFxjEaroH+PZJ6k/h9kl+KO0dWVc=
2+
github.com/a-hilaly/aws-iam-policy v0.0.0-20231121054900-2c56e839ca53/go.mod h1:Ojgst9ZFn+VEEJpqtuw/LxVGqEf2+hwWBlkYWvF/XWM=
13
github.com/aws-controllers-k8s/kms-controller v1.0.21 h1:ar8gCdl/l7qbXzr48YN5tNq4vJbB5UqnRH7pAIkP3tI=
24
github.com/aws-controllers-k8s/kms-controller v1.0.21/go.mod h1:tHFXV8lkrzautPPvQtPUJABPlJ9MXPRj8GB1UublGHQ=
35
github.com/aws-controllers-k8s/runtime v0.52.0 h1:Q5UIAn6SSBr60t/DiU/zr6NLBlUuK2AG3yy2ma/9gDU=

helm/crds/dynamodb.services.k8s.aws_tables.yaml

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -329,6 +329,21 @@ spec:
329329
format: int64
330330
type: integer
331331
type: object
332+
resourcePolicy:
333+
description: |-
334+
An Amazon Web Services resource-based policy document in JSON format.
335+
336+
- The maximum size supported for a resource-based policy document is 20
337+
KB. DynamoDB counts whitespaces when calculating the size of a policy
338+
against this limit.
339+
340+
- Within a resource-based policy, if the action for a DynamoDB service-linked
341+
role (SLR) to replicate data for a global table is denied, adding or deleting
342+
a replica will fail with an error.
343+
344+
For a full list of all considerations that apply while attaching a resource-based
345+
policy, see Resource-based policy considerations (https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/rbac-considerations.html).
346+
type: string
332347
sseSpecification:
333348
description: Represents the settings used to enable server-side encryption.
334349
properties:

pkg/resource/table/hooks.go

Lines changed: 37 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -166,17 +166,6 @@ func (rm *resourceManager) customUpdateTable(
166166
setSyncedCondition(desired, corev1.ConditionFalse, &msg, nil)
167167
return desired, requeueWaitWhileCreating
168168
}
169-
if isTableUpdating(latest) {
170-
msg := "table is currently being updated"
171-
setSyncedCondition(desired, corev1.ConditionFalse, &msg, nil)
172-
return desired, requeueWaitWhileUpdating
173-
}
174-
if tableHasTerminalStatus(latest) {
175-
msg := "table is in '" + *latest.ko.Status.TableStatus + "' status"
176-
setTerminalCondition(desired, corev1.ConditionTrue, &msg, nil)
177-
setSyncedCondition(desired, corev1.ConditionTrue, nil, nil)
178-
return desired, nil
179-
}
180169

181170
// Merge in the information we read from the API call above to the copy of
182171
// the original Kubernetes object we passed to the function
@@ -188,10 +177,36 @@ func (rm *resourceManager) customUpdateTable(
188177
return nil, err
189178
}
190179
}
191-
if !delta.DifferentExcept("Spec.Tags") {
180+
181+
// ResourcePolicy can be updated independently of table state
182+
if delta.DifferentAt("Spec.ResourcePolicy") {
183+
if latest.ko.Status.ACKResourceMetadata == nil || latest.ko.Status.ACKResourceMetadata.ARN == nil {
184+
rlog.Debug("skipping ResourcePolicy sync - table ARN not available yet")
185+
return &resource{ko}, requeueWaitWhileCreating
186+
}
187+
188+
err = rm.syncResourcePolicy(ctx, desired, latest)
189+
if err != nil {
190+
return nil, fmt.Errorf("cannot update table resource policy %v", err)
191+
}
192+
}
193+
194+
if !delta.DifferentExcept("Spec.Tags", "Spec.ResourcePolicy") {
192195
return &resource{ko}, nil
193196
}
194197

198+
if isTableUpdating(latest) {
199+
msg := "table is currently being updated"
200+
setSyncedCondition(desired, corev1.ConditionFalse, &msg, nil)
201+
return desired, requeueWaitWhileUpdating
202+
}
203+
if tableHasTerminalStatus(latest) {
204+
msg := "table is in '" + *latest.ko.Status.TableStatus + "' status"
205+
setTerminalCondition(desired, corev1.ConditionTrue, &msg, nil)
206+
setSyncedCondition(desired, corev1.ConditionTrue, nil, nil)
207+
return desired, nil
208+
}
209+
195210
if delta.DifferentAt("Spec.TimeToLive") {
196211
if err := rm.syncTTL(ctx, desired, latest); err != nil {
197212
// Ignore "already disabled errors"
@@ -522,6 +537,15 @@ func (rm *resourceManager) setResourceAdditionalFields(
522537
} else {
523538
ko.Spec.ContinuousBackups = pitrSpec
524539
}
540+
541+
if ko.Status.ACKResourceMetadata != nil && ko.Status.ACKResourceMetadata.ARN != nil {
542+
policy, err := rm.getResourcePolicyWithContext(ctx, (*string)(ko.Status.ACKResourceMetadata.ARN))
543+
if err != nil {
544+
return err
545+
}
546+
ko.Spec.ResourcePolicy = policy
547+
}
548+
525549
return nil
526550
}
527551

@@ -670,6 +694,7 @@ func customPreCompare(
670694
delta.Add("Spec.ContributorInsights", a.ko.Spec.ContributorInsights, b.ko.Spec.ContributorInsights)
671695
}
672696
}
697+
compareResourcePolicyDocument(delta, a, b)
673698

674699
}
675700

0 commit comments

Comments
 (0)