@@ -23,6 +23,10 @@ import (
2323
2424const (
2525 BucketACLSeparator = "/"
26+
27+ // AWS predefined group URIs for bucket ACL grants
28+ AuthenticatedUsersURI = "http://acs.amazonaws.com/groups/global/AuthenticatedUsers"
29+ AllUsersURI = "http://acs.amazonaws.com/groups/global/AllUsers"
2630)
2731
2832func ResourceBucketACL () * schema.Resource {
@@ -60,17 +64,26 @@ func ResourceBucketACL() *schema.Resource {
6064 Type : schema .TypeString ,
6165 Computed : true ,
6266 },
67+ "uri" : {
68+ Type : schema .TypeString ,
69+ Optional : true ,
70+ Description : "The uri of the grantee if you are granting permissions to a predefined group." ,
71+ ValidateFunc : validation .StringInSlice ([]string {
72+ AuthenticatedUsersURI ,
73+ AllUsersURI ,
74+ }, false ),
75+ },
6376 "id" : {
6477 Type : schema .TypeString ,
65- Required : true ,
78+ Optional : true ,
6679 Description : "The project ID owner of the grantee." ,
6780 ValidateDiagFunc : verify .IsUUID (),
6881 },
6982 "type" : {
7083 Type : schema .TypeString ,
71- Required : true ,
72- Description : "Type of grantee. Valid values: `CanonicalUser`" ,
73- ValidateFunc : validation .StringInSlice ([]string {string (s3Types .TypeCanonicalUser )}, false ),
84+ Optional : true ,
85+ Description : "Type of grantee. Valid values: `CanonicalUser`, `Group` " ,
86+ ValidateFunc : validation .StringInSlice ([]string {string (s3Types .TypeCanonicalUser ), string ( s3Types . TypeGroup ) }, false ),
7487 },
7588 },
7689 },
@@ -183,7 +196,12 @@ func resourceBucketACLCreate(ctx context.Context, d *schema.ResourceData, m any)
183196 }
184197
185198 if v , ok := d .GetOk ("access_control_policy" ); ok && len (v .([]any )) > 0 && v .([]any )[0 ] != nil {
186- input .AccessControlPolicy = expandBucketACLAccessControlPolicy (v .([]any ))
199+ accessControlPolicy , err := expandAndValidateBucketACLAccessControlPolicy (v .([]any ))
200+ if err != nil {
201+ return diag .FromErr (err )
202+ }
203+
204+ input .AccessControlPolicy = accessControlPolicy
187205 }
188206
189207 out , err := conn .PutBucketAcl (ctx , input )
@@ -198,30 +216,35 @@ func resourceBucketACLCreate(ctx context.Context, d *schema.ResourceData, m any)
198216 return resourceBucketACLRead (ctx , d , m )
199217}
200218
201- func expandBucketACLAccessControlPolicy (l []any ) * s3Types.AccessControlPolicy {
219+ func expandAndValidateBucketACLAccessControlPolicy (l []any ) ( * s3Types.AccessControlPolicy , error ) {
202220 if len (l ) == 0 || l [0 ] == nil {
203- return nil
221+ return nil , nil
204222 }
205223
206224 tfMap , ok := l [0 ].(map [string ]any )
207225 if ! ok {
208- return nil
226+ return nil , nil
209227 }
210228
211229 result := & s3Types.AccessControlPolicy {}
212230
213231 if v , ok := tfMap ["grant" ].(* schema.Set ); ok && v .Len () > 0 {
214- result .Grants = expandBucketACLAccessControlPolicyGrants (v .List ())
232+ grants , err := expandAndValidateBucketACLAccessControlPolicyGrants (v .List ())
233+ if err != nil {
234+ return nil , err
235+ }
236+
237+ result .Grants = grants
215238 }
216239
217240 if v , ok := tfMap ["owner" ].([]any ); ok && len (v ) > 0 && v [0 ] != nil {
218241 result .Owner = expandBucketACLAccessControlPolicyOwner (v )
219242 }
220243
221- return result
244+ return result , nil
222245}
223246
224- func expandBucketACLAccessControlPolicyGrants (l []any ) []s3Types.Grant {
247+ func expandAndValidateBucketACLAccessControlPolicyGrants (l []any ) ( []s3Types.Grant , error ) {
225248 grants := make ([]s3Types.Grant , 0 , len (l ))
226249
227250 for _ , tfMapRaw := range l {
@@ -233,7 +256,12 @@ func expandBucketACLAccessControlPolicyGrants(l []any) []s3Types.Grant {
233256 grant := s3Types.Grant {}
234257
235258 if v , ok := tfMap ["grantee" ].([]any ); ok && len (v ) > 0 && v [0 ] != nil {
236- grant .Grantee = expandBucketACLAccessControlPolicyGrantsGrantee (v )
259+ grantee , err := expandAndValidateBucketACLAccessControlPolicyGrantsGrantee (v )
260+ if err != nil {
261+ return nil , err
262+ }
263+
264+ grant .Grantee = grantee
237265 }
238266
239267 if v , ok := tfMap ["permission" ].(string ); ok && v != "" {
@@ -243,17 +271,17 @@ func expandBucketACLAccessControlPolicyGrants(l []any) []s3Types.Grant {
243271 grants = append (grants , grant )
244272 }
245273
246- return grants
274+ return grants , nil
247275}
248276
249- func expandBucketACLAccessControlPolicyGrantsGrantee (l []any ) * s3Types.Grantee {
277+ func expandAndValidateBucketACLAccessControlPolicyGrantsGrantee (l []any ) ( * s3Types.Grantee , error ) {
250278 if len (l ) == 0 || l [0 ] == nil {
251- return nil
279+ return nil , nil
252280 }
253281
254282 tfMap , ok := l [0 ].(map [string ]any )
255283 if ! ok {
256- return nil
284+ return nil , nil
257285 }
258286
259287 result := & s3Types.Grantee {}
@@ -262,11 +290,23 @@ func expandBucketACLAccessControlPolicyGrantsGrantee(l []any) *s3Types.Grantee {
262290 result .ID = buildBucketOwnerID (aws .String (v ))
263291 }
264292
293+ if v , ok := tfMap ["uri" ].(string ); ok && v != "" {
294+ result .URI = aws .String (v )
295+ }
296+
265297 if v , ok := tfMap ["type" ].(string ); ok && v != "" {
266298 result .Type = s3Types .Type (v )
267299 }
268300
269- return result
301+ if result .Type == s3Types .TypeCanonicalUser && result .ID == nil {
302+ return nil , errors .New ("id is required when grantee type is CanonicalUser" )
303+ }
304+
305+ if result .Type == s3Types .TypeGroup && result .URI == nil {
306+ return nil , errors .New ("uri is required when grantee type is Group" )
307+ }
308+
309+ return result , nil
270310}
271311
272312func expandBucketACLAccessControlPolicyOwner (l []any ) * s3Types.Owner {
@@ -345,6 +385,10 @@ func flattenBucketACLAccessControlPolicyGrantsGrantee(grantee *s3Types.Grantee)
345385 m ["display_name" ] = NormalizeOwnerID (grantee .DisplayName )
346386 }
347387
388+ if grantee .URI != nil {
389+ m ["uri" ] = * grantee .URI
390+ }
391+
348392 if grantee .ID != nil {
349393 m ["id" ] = NormalizeOwnerID (grantee .ID )
350394 }
@@ -451,7 +495,12 @@ func resourceBucketACLUpdate(ctx context.Context, d *schema.ResourceData, m any)
451495 }
452496
453497 if d .HasChange ("access_control_policy" ) {
454- input .AccessControlPolicy = expandBucketACLAccessControlPolicy (d .Get ("access_control_policy" ).([]any ))
498+ accessControlPolicy , err := expandAndValidateBucketACLAccessControlPolicy (d .Get ("access_control_policy" ).([]any ))
499+ if err != nil {
500+ return diag .FromErr (err )
501+ }
502+
503+ input .AccessControlPolicy = accessControlPolicy
455504 }
456505
457506 _ , err = conn .PutBucketAcl (ctx , input )
0 commit comments