diff --git a/internal/aws/cfn/patch.go b/internal/aws/cfn/patch.go index 5eb0e12d..746843f9 100644 --- a/internal/aws/cfn/patch.go +++ b/internal/aws/cfn/patch.go @@ -147,3 +147,21 @@ func patchSESContactList(schema *Schema) error { dss.Enum = convertStrings(valid) return nil } + +func patchIAMRole(schema *Schema) error { + policy, found := schema.Definitions["Policy"] + if !found { + return errors.New("expected AWS::IAM::Role to have Policy") + } + policyDocument, found := policy.Properties["PolicyDocument"] + if !found { + return errors.New("expected AWS::IAM::Role to have Policy.PolicyDocument") + } + policyDocument.Type = "object" + arpd, found := schema.Properties["AssumeRolePolicyDocument"] + if !found { + return errors.New("expected AWS::IAM::Role to have AssumeRolePolicyDocument") + } + arpd.Type = "object" + return nil +} diff --git a/internal/aws/cfn/schema.go b/internal/aws/cfn/schema.go index 34034f25..d0879260 100644 --- a/internal/aws/cfn/schema.go +++ b/internal/aws/cfn/schema.go @@ -15,7 +15,7 @@ type SchemaLike interface { type Prop struct { Description string `json:"description"` Items *Prop `json:"items"` - Type string `json:"type"` + Type any `json:"type"` UniqueItems bool `json:"uniqueItems"` InsertionOrder bool `json:"insertionOrder"` Ref string `json:"$ref"` @@ -92,6 +92,8 @@ func (schema *Schema) Patch() error { return patchSESConfigurationSetEventDestination(schema) case "AWS::SES::ContactList": return patchSESContactList(schema) + case "AWS::IAM::Role": + return patchIAMRole(schema) } return nil diff --git a/internal/cmd/build/build.go b/internal/cmd/build/build.go index cce8880d..6d7cbdfc 100644 --- a/internal/cmd/build/build.go +++ b/internal/cmd/build/build.go @@ -54,6 +54,10 @@ func buildProp(n *yaml.Node, propName string, prop cfn.Prop, schema cfn.Schema, isCircular := false + if prop.Type == nil { + prop.Type = "" + } + switch prop.Type { case "string": if len(prop.Enum) > 0 { diff --git a/internal/cmd/build/pkl.go b/internal/cmd/build/pkl.go index 2f214055..957f862e 100644 --- a/internal/cmd/build/pkl.go +++ b/internal/cmd/build/pkl.go @@ -1,6 +1,7 @@ package build import ( + "errors" "fmt" "slices" "strings" @@ -28,9 +29,10 @@ type pklDefProp struct { // A class that represents a definition in a registry resource schema type pklDefClass struct { - Name string - Props []*pklDefProp - Aliases []*stringAlias + Name string + Description string + Props []*pklDefProp + Aliases []*stringAlias } func printTypeAlias(alias *stringAlias) { @@ -54,6 +56,7 @@ func printCls(cls *pklDefClass) { fmt.Println() + printDescription(cls.Description) fmt.Printf("open class %s {\n", cls.Name) for _, prop := range cls.Props { @@ -77,6 +80,9 @@ func createTypeAlias(defName string, propName string, cls *pklDefClass, enum []a func getPropType(defName string, propName string, prop *cfn.Prop, cls *pklDefClass, required bool) (string, error) { + if prop.Type == nil { + prop.Type = "" + } var retval string switch prop.Type { case "string": @@ -91,13 +97,16 @@ func getPropType(defName string, propName string, retval = "String|Mapping" } case "object": - return "", fmt.Errorf("unexpected object type: %s", propName) + retval = "Dynamic" case "array": if prop.Items != nil { if prop.Items.Ref != "" { clsName := strings.Replace(prop.Items.Ref, "#/definitions/", "", 1) retval = fmt.Sprintf("Listing<%s>", clsName) } else { + if prop.Items.Type == nil { + prop.Items.Type = "" + } switch prop.Items.Type { case "string": if len(prop.Items.Enum) > 0 { @@ -135,9 +144,7 @@ func getPropType(defName string, propName string, } if retval == "" { - //return "", errors.New("unable to determine type for " + propName) - // TODO - retval = "Todo" + return "", errors.New("unable to determine type for " + propName) } if !required { retval = fmt.Sprintf("(%s)?", retval) @@ -145,6 +152,16 @@ func getPropType(defName string, propName string, return retval, nil } +func printDescription(description string) { + descTokens := strings.Split(description, "\n") + for i, d := range descTokens { + fmt.Println("///", d) + if i == 0 && len(descTokens) > 1 { + fmt.Println("///") + } + } +} + func generatePklClass(typeName string) error { schema, err := getSchema(typeName) if err != nil { @@ -157,7 +174,6 @@ func generatePklClass(typeName string) error { fmt.Println("module", strings.ToLower(strings.Replace(typeName, "::", ".", -1))) fmt.Println() - // TODO: Needs to be on a URI somewhere public fmt.Println("import \"../../cloudformation.pkl\"") classes := make([]*pklDefClass, 0) @@ -165,9 +181,10 @@ func generatePklClass(typeName string) error { // Iterate over definitions, creating a class for each one for name, def := range schema.Definitions { cls := &pklDefClass{ - Name: name, - Props: make([]*pklDefProp, 0), - Aliases: make([]*stringAlias, 0), + Name: name, + Description: def.Description, + Props: make([]*pklDefProp, 0), + Aliases: make([]*stringAlias, 0), } classes = append(classes, cls) @@ -185,13 +202,13 @@ func generatePklClass(typeName string) error { // Print out each of the classes for _, cls := range classes { - printCls(cls) } // Create a class for the type itself shortName := strings.Split(typeName, "::")[2] fmt.Println() + printDescription(schema.Description) fmt.Printf("open class %s extends cloudformation.Resource {\n", shortName) fmt.Println() fmt.Printf(" Type = \"%s\"\n", typeName) @@ -199,9 +216,10 @@ func generatePklClass(typeName string) error { propNames := make([]string, 0) cls := &pklDefClass{ - Name: shortName, - Props: make([]*pklDefProp, 0), - Aliases: make([]*stringAlias, 0), + Name: shortName, + Description: schema.Description, + Props: make([]*pklDefProp, 0), + Aliases: make([]*stringAlias, 0), } requiredProps := schema.GetRequired() for propName, prop := range schema.Properties { @@ -215,6 +233,9 @@ func generatePklClass(typeName string) error { if err != nil { return err } + fmt.Println() + + printDescription(prop.Description) fmt.Printf(" hidden %s: %s\n", propName, propType) propNames = append(propNames, propName) } diff --git a/pkl/aws/iam/role.pkl b/pkl/aws/iam/role.pkl new file mode 100644 index 00000000..c5fbdffd --- /dev/null +++ b/pkl/aws/iam/role.pkl @@ -0,0 +1,88 @@ +/// AWS::IAM::Role +/// +/// Generated by rain build --pkl-class AWS::IAM::Role +module aws.iam.role + +import "../../cloudformation.pkl" + +/// Contains information about an attached policy. +/// +/// An attached policy is a managed policy that has been attached to a user, group, or role. +/// For more information about managed policies, refer to [Managed Policies and Inline Policies](https://docs.aws.amazon.com/IAM/latest/UserGuide/policies-managed-vs-inline.html) in the *User Guide*. +open class Policy { + PolicyName: String|Mapping + PolicyDocument: Dynamic +} + +/// A structure that represents user-provided metadata that can be associated with an IAM resource. For more information about tagging, see [Tagging IAM resources](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_tags.html) in the *IAM User Guide*. +open class Tag { + Key: String|Mapping + Value: String|Mapping +} + +/// Creates a new role for your AWS-account. +/// +/// For more information about roles, see [IAM roles](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles.html) in the *IAM User Guide*. For information about quotas for role names and the number of roles you can create, see [IAM and quotas](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_iam-quotas.html) in the *IAM User Guide*. +open class Role extends cloudformation.Resource { + + Type = "AWS::IAM::Role" + + +/// The path to the role. For more information about paths, see [IAM Identifiers](https://docs.aws.amazon.com/IAM/latest/UserGuide/Using_Identifiers.html) in the *IAM User Guide*. +/// +/// This parameter is optional. If it is not included, it defaults to a slash (/). +/// This parameter allows (through its [regex pattern](https://docs.aws.amazon.com/http://wikipedia.org/wiki/regex)) a string of characters consisting of either a forward slash (/) by itself or a string that must begin and end with forward slashes. In addition, it can contain any ASCII character from the ! (``\u0021``) through the DEL character (``\u007F``), including most punctuation characters, digits, and upper and lowercased letters. + hidden Path: (String|Mapping)? + +/// The ARN of the policy used to set the permissions boundary for the role. +/// +/// For more information about permissions boundaries, see [Permissions boundaries for IAM identities](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_boundaries.html) in the *IAM User Guide*. + hidden PermissionsBoundary: (String|Mapping)? + +/// Adds or updates an inline policy document that is embedded in the specified IAM role. +/// +/// When you embed an inline policy in a role, the inline policy is used as part of the role's access (permissions) policy. The role's trust policy is created at the same time as the role. You can update a role's trust policy later. For more information about IAM roles, go to [Using Roles to Delegate Permissions and Federate Identities](https://docs.aws.amazon.com/IAM/latest/UserGuide/roles-toplevel.html). +/// A role can also have an attached managed policy. For information about policies, see [Managed Policies and Inline Policies](https://docs.aws.amazon.com/IAM/latest/UserGuide/policies-managed-vs-inline.html) in the *User Guide*. +/// For information about limits on the number of inline policies that you can embed with a role, see [Limitations on Entities](https://docs.aws.amazon.com/IAM/latest/UserGuide/LimitationsOnEntities.html) in the *User Guide*. +/// If an external policy (such as ``AWS::IAM::Policy`` or + hidden Policies: (Listing)? + +/// A name for the IAM role, up to 64 characters in length. For valid values, see the ``RoleName`` parameter for the [CreateRole](https://docs.aws.amazon.com/IAM/latest/APIReference/API_CreateRole.html) action in the *User Guide*. +/// +/// This parameter allows (per its [regex pattern](https://docs.aws.amazon.com/http://wikipedia.org/wiki/regex)) a string of characters consisting of upper and lowercase alphanumeric characters with no spaces. You can also include any of the following characters: _+=,.@-. The role name must be unique within the account. Role names are not distinguished by case. For example, you cannot create roles named both "Role1" and "role1". +/// If you don't specify a name, CFN generates a unique physical ID and uses that ID for the role name. +/// If you specify a name, you must specify the ``CAPABILITY_NAMED_IAM`` value to acknowledge your template's capabilities. For more information, see [Acknowledging Resources in Templates](https://docs.aws.amazon.com/AWSCloudFormation/latest/Use + hidden RoleName: (String|Mapping)? + +/// The trust policy that is associated with this role. Trust policies define which entities can assume the role. You can associate only one trust policy with a role. For an example of a policy that can be used to assume a role, see [Template Examples](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-iam-role.html#aws-resource-iam-role--examples). For more information about the elements that you can use in an IAM policy, see [Policy Elements Reference](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements.html) in the *User Guide*. + hidden AssumeRolePolicyDocument: Dynamic + +/// A description of the role that you provide. + hidden Description: (String|Mapping)? + +/// A list of tags that are attached to the role. For more information about tagging, see [Tagging IAM resources](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_tags.html) in the *IAM User Guide*. + hidden Tags: (Listing)? + +/// A list of Amazon Resource Names (ARNs) of the IAM managed policies that you want to attach to the role. +/// +/// For more information about ARNs, see [Amazon Resource Names (ARNs) and Service Namespaces](https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html) in the *General Reference*. + hidden ManagedPolicyArns: (Listing)? + +/// The maximum session duration (in seconds) that you want to set for the specified role. If you do not specify a value for this setting, the default value of one hour is applied. This setting can have a value from 1 hour to 12 hours. +/// +/// Anyone who assumes the role from the CLI or API can use the ``DurationSeconds`` API parameter or the ``duration-seconds`` CLI parameter to request a longer session. The ``MaxSessionDuration`` setting determines the maximum duration that can be requested using the ``DurationSeconds`` parameter. If users don't specify a value for the ``DurationSeconds`` parameter, their security credentials are valid for one hour by default. This applies when you use the ``AssumeRole*`` API operations or the ``assume-role*`` CLI operations but does not apply when you use those operations to create a console URL. For more information, see [Using IAM roles](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_use.html) in the *IAM User Guide*. + hidden MaxSessionDuration: (Int|Mapping)? + + Properties { + ["Path"] = if (Path == null) null else Path + ["PermissionsBoundary"] = if (PermissionsBoundary == null) null else PermissionsBoundary + ["Policies"] = if (Policies == null) null else Policies + ["RoleName"] = if (RoleName == null) null else RoleName + ["AssumeRolePolicyDocument"] = if (AssumeRolePolicyDocument == null) null else AssumeRolePolicyDocument + ["Description"] = if (Description == null) null else Description + ["Tags"] = if (Tags == null) null else Tags + ["ManagedPolicyArns"] = if (ManagedPolicyArns == null) null else ManagedPolicyArns + ["MaxSessionDuration"] = if (MaxSessionDuration == null) null else MaxSessionDuration + } + +} diff --git a/pkl/aws/iam/rolepolicy.pkl b/pkl/aws/iam/rolepolicy.pkl new file mode 100644 index 00000000..04998af1 --- /dev/null +++ b/pkl/aws/iam/rolepolicy.pkl @@ -0,0 +1,43 @@ +/// AWS::IAM::RolePolicy +/// +/// Generated by rain build --pkl-class AWS::IAM::RolePolicy +module aws.iam.rolepolicy + +import "../../cloudformation.pkl" + +/// Adds or updates an inline policy document that is embedded in the specified IAM role. +/// +/// When you embed an inline policy in a role, the inline policy is used as part of the role's access (permissions) policy. The role's trust policy is created at the same time as the role, using [CreateRole](https://docs.aws.amazon.com/IAM/latest/APIReference/API_CreateRole.html). You can update a role's trust policy using [UpdateAssumeRolePolicy](https://docs.aws.amazon.com/IAM/latest/APIReference/API_UpdateAssumeRolePolicy.html). For information about roles, see [roles](https://docs.aws.amazon.com/IAM/latest/UserGuide/roles-toplevel.html) in the *IAM User Guide*. +/// A role can also have a managed policy attached to it. To attach a managed policy to a role, use [AWS::IAM::Role](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-iam-role.html). To create a new managed policy, use [AWS::IAM::ManagedPolicy](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-iam-managedpolicy.html). For information about policies, see [Managed policies and inline policies](https://docs.aws.amazon.com/IAM/latest/UserGuide/policies-managed-vs-inline.html) in the *IAM User Guide*. +/// For information about the maximum number of inline policies that you can embed with a role, see [IAM and quotas](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_iam-quotas.html) in the *IAM User Guide*. +open class RolePolicy extends cloudformation.Resource { + + Type = "AWS::IAM::RolePolicy" + + +/// The policy document. +/// +/// You must provide policies in JSON format in IAM. However, for CFN templates formatted in YAML, you can provide the policy in JSON or YAML format. CFN always converts a YAML policy to JSON format before submitting it to IAM. +/// The [regex pattern](https://docs.aws.amazon.com/http://wikipedia.org/wiki/regex) used to validate this parameter is a string of characters consisting of the following: +/// + Any printable ASCII character ranging from the space character (``\u0020``) through the end of the ASCII character range +/// + The printable characters in the Basic Latin and Latin-1 Supplement character set (through ``\u00FF``) +/// + The special characters tab (``\u0009``), line feed (``\u000A``), and carriage return (``\u000D``) + hidden PolicyDocument: (Dynamic)? + +/// The name of the policy document. +/// +/// This parameter allows (through its [regex pattern](https://docs.aws.amazon.com/http://wikipedia.org/wiki/regex)) a string of characters consisting of upper and lowercase alphanumeric characters with no spaces. You can also include any of the following characters: _+=,.@- + hidden PolicyName: String|Mapping + +/// The name of the role to associate the policy with. +/// +/// This parameter allows (through its [regex pattern](https://docs.aws.amazon.com/http://wikipedia.org/wiki/regex)) a string of characters consisting of upper and lowercase alphanumeric characters with no spaces. You can also include any of the following characters: _+=,.@- + hidden RoleName: String|Mapping + + Properties { + ["PolicyDocument"] = if (PolicyDocument == null) null else PolicyDocument + ["PolicyName"] = if (PolicyName == null) null else PolicyName + ["RoleName"] = if (RoleName == null) null else RoleName + } + +} diff --git a/pkl/aws/s3/bucket.pkl b/pkl/aws/s3/bucket.pkl index dd8290bf..8008e2c7 100644 --- a/pkl/aws/s3/bucket.pkl +++ b/pkl/aws/s3/bucket.pkl @@ -5,324 +5,434 @@ module aws.s3.bucket import "../../cloudformation.pkl" -open class EncryptionConfiguration { - ReplicaKmsKeyID: String|Mapping -} - -typealias SseKmsEncryptedObjectsStatus = "Disabled"|"Enabled" +typealias ServerSideEncryptionByDefaultSSEAlgorithm = "aws:kms"|"AES256"|"aws:kms:dsse" -open class SseKmsEncryptedObjects { - Status: SseKmsEncryptedObjectsStatus|Mapping +/// Describes the default server-side encryption to apply to new objects in the bucket. If a PUT Object request doesn't specify any server-side encryption, this default encryption will be applied. If you don't specify a customer managed key at configuration, Amazon S3 automatically creates an AWS KMS key in your AWS account the first time that you add an object encrypted with SSE-KMS to a bucket. By default, Amazon S3 uses this KMS key for SSE-KMS. For more information, see [PUT Bucket encryption](https://docs.aws.amazon.com/AmazonS3/latest/API/RESTBucketPUTencryption.html) in the *Amazon S3 API Reference*. +open class ServerSideEncryptionByDefault { + KMSMasterKeyID: (String|Mapping)? + SSEAlgorithm: ServerSideEncryptionByDefaultSSEAlgorithm|Mapping } -open class ServerSideEncryptionRule { - BucketKeyEnabled: (Boolean|Mapping)? - ServerSideEncryptionByDefault: (ServerSideEncryptionByDefault)? +/// Specifies when noncurrent object versions expire. Upon expiration, S3 permanently deletes the noncurrent object versions. You set this lifecycle configuration action on a bucket that has versioning enabled (or suspended) to request that S3 delete noncurrent object versions at a specific period in the object's lifetime. For more information about setting a lifecycle rule configuration, see [AWS::S3::Bucket Rule](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-s3-bucket-lifecycleconfig-rule.html). +open class NoncurrentVersionExpiration { + NewerNoncurrentVersions: (Int|Mapping)? + NoncurrentDays: Int|Mapping } -typealias IntelligentTieringConfigurationStatus = "Disabled"|"Enabled" +typealias NoncurrentVersionTransitionStorageClass = "DEEP_ARCHIVE"|"GLACIER"|"Glacier"|"GLACIER_IR"|"INTELLIGENT_TIERING"|"ONEZONE_IA"|"STANDARD_IA" -open class IntelligentTieringConfiguration { - Id: String|Mapping - Prefix: (String|Mapping)? - Status: IntelligentTieringConfigurationStatus|Mapping - TagFilters: (Listing)? - Tierings: Listing +/// Container for the transition rule that describes when noncurrent objects transition to the ``STANDARD_IA``, ``ONEZONE_IA``, ``INTELLIGENT_TIERING``, ``GLACIER_IR``, ``GLACIER``, or ``DEEP_ARCHIVE`` storage class. If your bucket is versioning-enabled (or versioning is suspended), you can set this action to request that Amazon S3 transition noncurrent object versions to the ``STANDARD_IA``, ``ONEZONE_IA``, ``INTELLIGENT_TIERING``, ``GLACIER_IR``, ``GLACIER``, or ``DEEP_ARCHIVE`` storage class at a specific period in the object's lifetime. If you specify this property, don't specify the ``NoncurrentVersionTransitions`` property. +open class NoncurrentVersionTransition { + StorageClass: NoncurrentVersionTransitionStorageClass|Mapping + TransitionInDays: Int|Mapping + NewerNoncurrentVersions: (Int|Mapping)? } -typealias DeleteMarkerReplicationStatus = "Disabled"|"Enabled" - -open class DeleteMarkerReplication { - Status: (DeleteMarkerReplicationStatus|Mapping)? +/// Describes where logs are stored and the prefix that Amazon S3 assigns to all log object keys for a bucket. For examples and more information, see [PUT Bucket logging](https://docs.aws.amazon.com/AmazonS3/latest/API/RESTBucketPUTlogging.html) in the *Amazon S3 API Reference*. +/// +/// To successfully complete the ``AWS::S3::Bucket LoggingConfiguration`` request, you must have ``s3:PutObject`` and ``s3:PutObjectAcl`` in your IAM permissions. +open class LoggingConfiguration { + DestinationBucketName: (String|Mapping)? + LogFilePrefix: (String|Mapping)? + TargetObjectKeyFormat: (TargetObjectKeyFormat)? } -typealias DestinationFormat = "CSV"|"ORC"|"Parquet" +/// Specifies object key name filtering rules. For information about key name filtering, see [Configuring event notifications using object key name filtering](https://docs.aws.amazon.com/AmazonS3/latest/userguide/notification-how-to-filtering.html) in the *Amazon S3 User Guide*. +open class NotificationFilter { + S3Key: S3KeyFilter +} -open class Destination { - BucketArn: String|Mapping - BucketAccountId: (String|Mapping)? - Format: DestinationFormat|Mapping - Prefix: (String|Mapping)? +/// Specifies the Object Lock rule for the specified object. Enable the this rule when you apply ``ObjectLockConfiguration`` to a bucket. +open class ObjectLockRule { + DefaultRetention: (DefaultRetention)? } -open class AnalyticsConfiguration { - TagFilters: (Listing)? - StorageClassAnalysis: StorageClassAnalysis - Id: String|Mapping +typealias ReplicationRuleStatus = "Disabled"|"Enabled" + +/// Specifies which Amazon S3 objects to replicate and where to store the replicas. +open class ReplicationRule { + Destination: ReplicationDestination + Filter: (ReplicationRuleFilter)? + Id: (String|Mapping)? Prefix: (String|Mapping)? + Priority: (Int|Mapping)? + SourceSelectionCriteria: (SourceSelectionCriteria)? + Status: ReplicationRuleStatus|Mapping + DeleteMarkerReplication: (DeleteMarkerReplication)? } -open class CorsConfiguration { - CorsRules: Listing +/// Specifies encryption-related information for an Amazon S3 bucket that is a destination for replicated objects. +open class EncryptionConfiguration { + ReplicaKmsKeyID: String|Mapping } -typealias OwnershipControlsRuleObjectOwnership = "ObjectWriter"|"BucketOwnerPreferred"|"BucketOwnerEnforced" +typealias CorsRuleAllowedMethods = "GET"|"PUT"|"HEAD"|"POST"|"DELETE" -open class OwnershipControlsRule { - ObjectOwnership: (OwnershipControlsRuleObjectOwnership|Mapping)? +/// Specifies a cross-origin access rule for an Amazon S3 bucket. +open class CorsRule { + MaxAge: (Int|Mapping)? + AllowedHeaders: (Listing)? + AllowedMethods: Listing + AllowedOrigins: Listing + ExposedHeaders: (Listing)? + Id: (String|Mapping)? } -typealias ReplicationTimeStatus = "Disabled"|"Enabled" - -open class ReplicationTime { - Time: ReplicationTimeValue - Status: ReplicationTimeStatus|Mapping +/// Specifies the container element for Object Ownership rules. +/// +/// S3 Object Ownership is an Amazon S3 bucket-level setting that you can use to disable access control lists (ACLs) and take ownership of every object in your bucket, simplifying access management for data stored in Amazon S3. For more information, see [Controlling ownership of objects and disabling ACLs](https://docs.aws.amazon.com/AmazonS3/latest/userguide/about-object-ownership.html) in the *Amazon S3 User Guide*. +open class OwnershipControls { + Rules: Listing } -open class RoutingRuleCondition { - KeyPrefixEquals: (String|Mapping)? - HttpErrorCodeReturnedEquals: (String|Mapping)? -} +typealias ReplicationDestinationStorageClass = "DEEP_ARCHIVE"|"GLACIER"|"GLACIER_IR"|"INTELLIGENT_TIERING"|"ONEZONE_IA"|"REDUCED_REDUNDANCY"|"STANDARD"|"STANDARD_IA" -open class TagFilter { - Value: String|Mapping - Key: String|Mapping +/// A container for information about the replication destination and its configurations including enabling the S3 Replication Time Control (S3 RTC). +open class ReplicationDestination { + StorageClass: (ReplicationDestinationStorageClass|Mapping)? + AccessControlTranslation: (AccessControlTranslation)? + Account: (String|Mapping)? + Bucket: String|Mapping + EncryptionConfiguration: (EncryptionConfiguration)? + Metrics: (Metrics)? + ReplicationTime: (ReplicationTime)? } -open class OwnershipControls { - Rules: Listing +/// Specifies website configuration parameters for an Amazon S3 bucket. +open class WebsiteConfiguration { + RedirectAllRequestsTo: (RedirectAllRequestsTo)? + ErrorDocument: (String|Mapping)? + IndexDocument: (String|Mapping)? + RoutingRules: (Listing)? } -open class AccessControlTranslation { - Owner: String|Mapping +/// Specifies how data related to the storage class analysis for an Amazon S3 bucket should be exported. +open class DataExport { + Destination: Destination + OutputSchemaVersion: String|Mapping } -typealias InventoryConfigurationScheduleFrequency = "Daily"|"Weekly" - typealias InventoryConfigurationIncludedObjectVersions = "All"|"Current" typealias InventoryConfigurationOptionalFields = "Size"|"LastModifiedDate"|"StorageClass"|"ETag"|"IsMultipartUploaded"|"ReplicationStatus"|"EncryptionStatus"|"ObjectLockRetainUntilDate"|"ObjectLockMode"|"ObjectLockLegalHoldStatus"|"IntelligentTieringAccessTier"|"BucketKeyStatus"|"ChecksumAlgorithm"|"ObjectAccessControlList"|"ObjectOwner" +typealias InventoryConfigurationScheduleFrequency = "Daily"|"Weekly" + +/// Specifies the inventory configuration for an Amazon S3 bucket. For more information, see [GET Bucket inventory](https://docs.aws.amazon.com/AmazonS3/latest/API/RESTBucketGETInventoryConfig.html) in the *Amazon S3 API Reference*. open class InventoryConfiguration { - ScheduleFrequency: InventoryConfigurationScheduleFrequency|Mapping - Destination: Destination Enabled: Boolean|Mapping Id: String|Mapping IncludedObjectVersions: InventoryConfigurationIncludedObjectVersions|Mapping OptionalFields: (Listing)? Prefix: (String|Mapping)? + ScheduleFrequency: InventoryConfigurationScheduleFrequency|Mapping + Destination: Destination } -typealias MetricsStatus = "Disabled"|"Enabled" +/// Describes the cross-origin access configuration for objects in an Amazon S3 bucket. For more information, see [Enabling Cross-Origin Resource Sharing](https://docs.aws.amazon.com/AmazonS3/latest/dev/cors.html) in the *Amazon S3 User Guide*. +open class CorsConfiguration { + CorsRules: Listing +} -open class Metrics { - EventThreshold: (ReplicationTimeValue)? - Status: MetricsStatus|Mapping +/// Places an Object Lock configuration on the specified bucket. The rule specified in the Object Lock configuration will be applied by default to every new object placed in the specified bucket. For more information, see [Locking Objects](https://docs.aws.amazon.com/AmazonS3/latest/dev/object-lock.html). +open class ObjectLockConfiguration { + ObjectLockEnabled: (String|Mapping)? + Rule: (ObjectLockRule)? } -open class ReplicationRuleFilter { - And: (ReplicationRuleAndOperator)? - Prefix: (String|Mapping)? - TagFilter: (TagFilter)? +typealias ReplicationTimeStatus = "Disabled"|"Enabled" + +/// A container specifying S3 Replication Time Control (S3 RTC) related information, including whether S3 RTC is enabled and the time when all objects and operations on objects must be replicated. Must be specified together with a ``Metrics`` block. +open class ReplicationTime { + Status: ReplicationTimeStatus|Mapping + Time: ReplicationTimeValue } -typealias AccelerateConfigurationAccelerationStatus = "Enabled"|"Suspended" +/// Specifies tags to use to identify a subset of objects for an Amazon S3 bucket. +open class TagFilter { + Value: String|Mapping + Key: String|Mapping +} -open class AccelerateConfiguration { - AccelerationStatus: AccelerateConfigurationAccelerationStatus|Mapping +/// Specifies the default server-side encryption configuration. +open class ServerSideEncryptionRule { + BucketKeyEnabled: (Boolean|Mapping)? + ServerSideEncryptionByDefault: (ServerSideEncryptionByDefault)? } -typealias ServerSideEncryptionByDefaultSSEAlgorithm = "aws:kms"|"AES256"|"aws:kms:dsse" +typealias IntelligentTieringConfigurationStatus = "Disabled"|"Enabled" -open class ServerSideEncryptionByDefault { - KMSMasterKeyID: (String|Mapping)? - SSEAlgorithm: ServerSideEncryptionByDefaultSSEAlgorithm|Mapping +/// Specifies the S3 Intelligent-Tiering configuration for an Amazon S3 bucket. +/// +/// For information about the S3 Intelligent-Tiering storage class, see [Storage class for automatically optimizing frequently and infrequently accessed objects](https://docs.aws.amazon.com/AmazonS3/latest/dev/storage-class-intro.html#sc-dynamic-data-access). +open class IntelligentTieringConfiguration { + Id: String|Mapping + Prefix: (String|Mapping)? + Status: IntelligentTieringConfigurationStatus|Mapping + TagFilters: (Listing)? + Tierings: Listing } typealias TieringAccessTier = "ARCHIVE_ACCESS"|"DEEP_ARCHIVE_ACCESS" +/// The S3 Intelligent-Tiering storage class is designed to optimize storage costs by automatically moving data to the most cost-effective storage access tier, without additional operational overhead. open class Tiering { AccessTier: TieringAccessTier|Mapping Days: Int|Mapping } -typealias ReplicationDestinationStorageClass = "DEEP_ARCHIVE"|"GLACIER"|"GLACIER_IR"|"INTELLIGENT_TIERING"|"ONEZONE_IA"|"REDUCED_REDUNDANCY"|"STANDARD"|"STANDARD_IA" +/// Specifies a metrics configuration for the CloudWatch request metrics (specified by the metrics configuration ID) from an Amazon S3 bucket. If you're updating an existing metrics configuration, note that this is a full replacement of the existing metrics configuration. If you don't include the elements you want to keep, they are erased. For examples, see [AWS::S3::Bucket](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-s3-bucket.html#aws-properties-s3-bucket--examples). For more information, see [PUT Bucket metrics](https://docs.aws.amazon.com/AmazonS3/latest/API/RESTBucketPUTMetricConfiguration.html) in the *Amazon S3 API Reference*. +open class MetricsConfiguration { + AccessPointArn: (String|Mapping)? + Id: String|Mapping + Prefix: (String|Mapping)? + TagFilters: (Listing)? +} -open class ReplicationDestination { - ReplicationTime: (ReplicationTime)? - StorageClass: (ReplicationDestinationStorageClass|Mapping)? - AccessControlTranslation: (AccessControlTranslation)? - Account: (String|Mapping)? - Bucket: String|Mapping - EncryptionConfiguration: (EncryptionConfiguration)? - Metrics: (Metrics)? +/// A container for describing a condition that must be met for the specified redirect to apply. For example, 1. If request is for pages in the ``/docs`` folder, redirect to the ``/documents`` folder. 2. If request results in HTTP error 4xx, redirect request to another host where you might process the error. +open class RoutingRuleCondition { + KeyPrefixEquals: (String|Mapping)? + HttpErrorCodeReturnedEquals: (String|Mapping)? } -typealias ReplicaModificationsStatus = "Enabled"|"Disabled" +typealias PartitionedPrefixPartitionDateSource = "EventTime"|"DeliveryTime" -open class ReplicaModifications { - Status: ReplicaModificationsStatus|Mapping +/// Amazon S3 keys for log objects are partitioned in the following format: +/// +/// ``[DestinationPrefix][SourceAccountId]/[SourceRegion]/[SourceBucket]/[YYYY]/[MM]/[DD]/[YYYY]-[MM]-[DD]-[hh]-[mm]-[ss]-[UniqueString]`` +/// PartitionedPrefix defaults to EventTime delivery when server access logs are delivered. +open class PartitionedPrefix { + PartitionDateSource: (PartitionedPrefixPartitionDateSource|Mapping)? } -open class BucketEncryption { - ServerSideEncryptionConfiguration: Listing +/// A container of a key value name pair. +open class Tag { + Key: String|Mapping + Value: String|Mapping } -open class TopicConfiguration { - Event: String|Mapping - Filter: (NotificationFilter)? - Topic: String|Mapping +/// Specifies the redirect behavior and when a redirect is applied. For more information about routing rules, see [Configuring advanced conditional redirects](https://docs.aws.amazon.com/AmazonS3/latest/dev/how-to-page-redirect.html#advanced-conditional-redirects) in the *Amazon S3 User Guide*. +open class RoutingRule { + RedirectRule: RedirectRule + RoutingRuleCondition: (RoutingRuleCondition)? } -open class NotificationFilter { - S3Key: S3KeyFilter +/// Describes the LAMlong functions to invoke and the events for which to invoke them. +open class LambdaConfiguration { + Filter: (NotificationFilter)? + Function: String|Mapping + Event: String|Mapping } -open class ObjectLockRule { - DefaultRetention: (DefaultRetention)? +/// Specify this only in a cross-account scenario (where source and destination bucket owners are not the same), and you want to change replica ownership to the AWS-account that owns the destination bucket. If this is not specified in the replication configuration, the replicas are owned by same AWS-account that owns the source object. +open class AccessControlTranslation { + Owner: String|Mapping } -typealias ReplicationRuleStatus = "Disabled"|"Enabled" +/// A filter that identifies the subset of objects to which the replication rule applies. A ``Filter`` must specify exactly one ``Prefix``, ``TagFilter``, or an ``And`` child element. +open class ReplicationRuleFilter { + And: (ReplicationRuleAndOperator)? + Prefix: (String|Mapping)? + TagFilter: (TagFilter)? +} -open class ReplicationRule { +/// A container for specifying rule filters. The filters determine the subset of objects to which the rule applies. This element is required only if you specify more than one filter. +/// +/// For example: +/// + If you specify both a ``Prefix`` and a ``TagFilter``, wrap these filters in an ``And`` tag. +/// + If you specify a filter based on multiple tags, wrap the ``TagFilter`` elements in an ``And`` tag +open class ReplicationRuleAndOperator { Prefix: (String|Mapping)? - Priority: (Int|Mapping)? - SourceSelectionCriteria: (SourceSelectionCriteria)? - Status: ReplicationRuleStatus|Mapping - DeleteMarkerReplication: (DeleteMarkerReplication)? - Destination: ReplicationDestination - Filter: (ReplicationRuleFilter)? - Id: (String|Mapping)? + TagFilters: (Listing)? } -typealias RedirectRuleProtocol = "http"|"https" +typealias VersioningConfigurationStatus = "Enabled"|"Suspended" -open class RedirectRule { - ReplaceKeyPrefixWith: (String|Mapping)? - ReplaceKeyWith: (String|Mapping)? - HostName: (String|Mapping)? - HttpRedirectCode: (String|Mapping)? - Protocol: (RedirectRuleProtocol|Mapping)? +/// Describes the versioning state of an Amazon S3 bucket. For more information, see [PUT Bucket versioning](https://docs.aws.amazon.com/AmazonS3/latest/API/RESTBucketPUTVersioningStatus.html) in the *Amazon S3 API Reference*. +open class VersioningConfiguration { + Status: VersioningConfigurationStatus|Mapping } -open class Arn { +typealias DestinationFormat = "CSV"|"ORC"|"Parquet" + +/// Specifies information about where to publish analysis or configuration results for an Amazon S3 bucket. +open class Destination { + Prefix: (String|Mapping)? + BucketArn: String|Mapping + BucketAccountId: (String|Mapping)? + Format: DestinationFormat|Mapping } -open class StorageClassAnalysis { - DataExport: (DataExport)? +typealias AccelerateConfigurationAccelerationStatus = "Enabled"|"Suspended" + +/// Configures the transfer acceleration state for an Amazon S3 bucket. For more information, see [Amazon S3 Transfer Acceleration](https://docs.aws.amazon.com/AmazonS3/latest/dev/transfer-acceleration.html) in the *Amazon S3 User Guide*. +open class AccelerateConfiguration { + AccelerationStatus: AccelerateConfigurationAccelerationStatus|Mapping } +/// Specifies the lifecycle configuration for objects in an Amazon S3 bucket. For more information, see [Object Lifecycle Management](https://docs.aws.amazon.com/AmazonS3/latest/dev/object-lifecycle-mgmt.html) in the *Amazon S3 User Guide*. open class LifecycleConfiguration { Rules: Listing } -open class NotificationConfiguration { - TopicConfigurations: (Listing)? - EventBridgeConfiguration: (EventBridgeConfiguration)? - LambdaConfigurations: (Listing)? - QueueConfigurations: (Listing)? +/// The date value in ISO 8601 format. The timezone is always UTC. (YYYY-MM-DDThh:mm:ssZ) +open class iso8601UTC { } -open class DataExport { - Destination: Destination - OutputSchemaVersion: String|Mapping +typealias RuleStatus = "Enabled"|"Disabled" + +/// Specifies lifecycle rules for an Amazon S3 bucket. For more information, see [Put Bucket Lifecycle Configuration](https://docs.aws.amazon.com/AmazonS3/latest/API/RESTBucketPUTlifecycle.html) in the *Amazon S3 API Reference*. +/// +/// You must specify at least one of the following properties: ``AbortIncompleteMultipartUpload``, ``ExpirationDate``, ``ExpirationInDays``, ``NoncurrentVersionExpirationInDays``, ``NoncurrentVersionTransition``, ``NoncurrentVersionTransitions``, ``Transition``, or ``Transitions``. +open class Rule { + ObjectSizeGreaterThan: (String(matches(Regex(#"[0-9]+"#)))|Mapping)? + Transition: (Transition)? + ExpirationInDays: (Int|Mapping)? + Id: (String|Mapping)? + NoncurrentVersionExpirationInDays: (Int|Mapping)? + NoncurrentVersionTransition: (NoncurrentVersionTransition)? + AbortIncompleteMultipartUpload: (AbortIncompleteMultipartUpload)? + ExpirationDate: (iso8601UTC)? + NoncurrentVersionExpiration: (NoncurrentVersionExpiration)? + NoncurrentVersionTransitions: (Listing)? + Prefix: (String|Mapping)? + Transitions: (Listing)? + ExpiredObjectDeleteMarker: (Boolean|Mapping)? + Status: RuleStatus|Mapping + TagFilters: (Listing)? + ObjectSizeLessThan: (String(matches(Regex(#"[0-9]+"#)))|Mapping)? } -open class RoutingRule { - RoutingRuleCondition: (RoutingRuleCondition)? - RedirectRule: RedirectRule +/// A container for specifying the configuration for publication of messages to an Amazon Simple Notification Service (Amazon SNS) topic when Amazon S3 detects specified events. +open class TopicConfiguration { + Event: String|Mapping + Filter: (NotificationFilter)? + Topic: String|Mapping } +typealias DefaultRetentionMode = "COMPLIANCE"|"GOVERNANCE" + +/// The container element for specifying the default Object Lock retention settings for new objects placed in the specified bucket. +/// +/// + The ``DefaultRetention`` settings require both a mode and a period. +/// + The ``DefaultRetention`` period can be either ``Days`` or ``Years`` but you must select one. You cannot specify ``Days`` and ``Years`` at the same time. +open class DefaultRetention { + Years: (Int|Mapping)? + Days: (Int|Mapping)? + Mode: (DefaultRetentionMode|Mapping)? +} + +/// A container for replication rules. You can add up to 1,000 rules. The maximum size of a replication configuration is 2 MB. The latest version of the replication configuration XML is V2. For more information about XML V2 replication configurations, see [Replication configuration](https://docs.aws.amazon.com/AmazonS3/latest/userguide/replication-add-config.html) in the *Amazon S3 User Guide*. open class ReplicationConfiguration { Role: String|Mapping Rules: Listing } -open class TargetObjectKeyFormat { -} - -open class MetricsConfiguration { - Prefix: (String|Mapping)? +/// Specifies the configuration and any analyses for the analytics filter of an Amazon S3 bucket. +open class AnalyticsConfiguration { TagFilters: (Listing)? - AccessPointArn: (String|Mapping)? + StorageClassAnalysis: StorageClassAnalysis Id: String|Mapping + Prefix: (String|Mapping)? } -open class S3KeyFilter { - Rules: Listing +/// A container specifying the time value for S3 Replication Time Control (S3 RTC) and replication metrics ``EventThreshold``. +open class ReplicationTimeValue { + Minutes: Int|Mapping } -open class LoggingConfiguration { - DestinationBucketName: (String|Mapping)? - LogFilePrefix: (String|Mapping)? - TargetObjectKeyFormat: (TargetObjectKeyFormat)? -} +typealias RedirectAllRequestsToProtocol = "http"|"https" -open class LambdaConfiguration { - Event: String|Mapping - Filter: (NotificationFilter)? - Function: String|Mapping +/// Specifies the redirect behavior of all requests to a website endpoint of an Amazon S3 bucket. +open class RedirectAllRequestsTo { + HostName: String|Mapping + Protocol: (RedirectAllRequestsToProtocol|Mapping)? } -open class SourceSelectionCriteria { - ReplicaModifications: (ReplicaModifications)? - SseKmsEncryptedObjects: (SseKmsEncryptedObjects)? +/// Describes the key format for server access log file in the target bucket. You can choose between SimplePrefix and PartitionedPrefix. +open class TargetObjectKeyFormat { } -typealias VersioningConfigurationStatus = "Enabled"|"Suspended" - -open class VersioningConfiguration { - Status: VersioningConfigurationStatus|Mapping +/// Specifies the configuration for publishing messages to an Amazon Simple Queue Service (Amazon SQS) queue when Amazon S3 detects specified events. +open class QueueConfiguration { + Filter: (NotificationFilter)? + Queue: String|Mapping + Event: String|Mapping } -typealias RedirectAllRequestsToProtocol = "http"|"https" - -open class RedirectAllRequestsTo { - HostName: String|Mapping - Protocol: (RedirectAllRequestsToProtocol|Mapping)? +/// A container for object key name prefix and suffix filtering rules. For more information about object key name filtering, see [Configuring event notifications using object key name filtering](https://docs.aws.amazon.com/AmazonS3/latest/userguide/notification-how-to-filtering.html) in the *Amazon S3 User Guide*. +/// +/// The same type of filter rule cannot be used more than once. For example, you cannot specify two prefix rules. +open class S3KeyFilter { + Rules: Listing } -typealias NoncurrentVersionTransitionStorageClass = "DEEP_ARCHIVE"|"GLACIER"|"Glacier"|"GLACIER_IR"|"INTELLIGENT_TIERING"|"ONEZONE_IA"|"STANDARD_IA" - -open class NoncurrentVersionTransition { - TransitionInDays: Int|Mapping - NewerNoncurrentVersions: (Int|Mapping)? - StorageClass: NoncurrentVersionTransitionStorageClass|Mapping +/// Specifies default encryption for a bucket using server-side encryption with Amazon S3-managed keys (SSE-S3), AWS KMS-managed keys (SSE-KMS), or dual-layer server-side encryption with KMS-managed keys (DSSE-KMS). For information about the Amazon S3 default encryption feature, see [Amazon S3 Default Encryption for S3 Buckets](https://docs.aws.amazon.com/AmazonS3/latest/dev/bucket-encryption.html) in the *Amazon S3 User Guide*. +open class BucketEncryption { + ServerSideEncryptionConfiguration: Listing } -typealias DefaultRetentionMode = "COMPLIANCE"|"GOVERNANCE" +typealias TransitionStorageClass = "DEEP_ARCHIVE"|"GLACIER"|"Glacier"|"GLACIER_IR"|"INTELLIGENT_TIERING"|"ONEZONE_IA"|"STANDARD_IA" -open class DefaultRetention { - Years: (Int|Mapping)? - Days: (Int|Mapping)? - Mode: (DefaultRetentionMode|Mapping)? +/// Specifies when an object transitions to a specified storage class. For more information about Amazon S3 lifecycle configuration rules, see [Transitioning Objects Using Amazon S3 Lifecycle](https://docs.aws.amazon.com/AmazonS3/latest/dev/lifecycle-transition-general-considerations.html) in the *Amazon S3 User Guide*. +open class Transition { + StorageClass: TransitionStorageClass|Mapping + TransitionDate: (iso8601UTC)? + TransitionInDays: (Int|Mapping)? } -open class Tag { - Key: String|Mapping +/// Specifies the Amazon S3 object key name to filter on. An object key name is the name assigned to an object in your Amazon S3 bucket. You specify whether to filter on the suffix or prefix of the object key name. A prefix is a specific string of characters at the beginning of an object key name, which you can use to organize objects. For example, you can start the key names of related objects with a prefix, such as ``2023-`` or ``engineering/``. Then, you can use ``FilterRule`` to find objects in a bucket with key names that have the same prefix. A suffix is similar to a prefix, but it is at the end of the object key name instead of at the beginning. +open class FilterRule { + Name: String|Mapping Value: String|Mapping } -open class AbortIncompleteMultipartUpload { - DaysAfterInitiation: Int|Mapping +typealias DeleteMarkerReplicationStatus = "Disabled"|"Enabled" + +/// Specifies whether Amazon S3 replicates delete markers. If you specify a ``Filter`` in your replication configuration, you must also include a ``DeleteMarkerReplication`` element. If your ``Filter`` includes a ``Tag`` element, the ``DeleteMarkerReplication`` ``Status`` must be set to Disabled, because Amazon S3 does not support replicating delete markers for tag-based rules. For an example configuration, see [Basic Rule Configuration](https://docs.aws.amazon.com/AmazonS3/latest/dev/replication-add-config.html#replication-config-min-rule-config). +/// +/// For more information about delete marker replication, see [Basic Rule Configuration](https://docs.aws.amazon.com/AmazonS3/latest/dev/delete-marker-replication.html). +/// If you are using an earlier version of the replication configuration, Amazon S3 handles replication of delete markers differently. For more information, see [Backward Compatibility](https://docs.aws.amazon.com/AmazonS3/latest/dev/replication-add-config.html#replication-backward-compat-considerations). +open class DeleteMarkerReplication { + Status: (DeleteMarkerReplicationStatus|Mapping)? } -open class QueueConfiguration { - Event: String|Mapping - Filter: (NotificationFilter)? - Queue: String|Mapping +/// A container that describes additional filters for identifying the source objects that you want to replicate. You can choose to enable or disable the replication of these objects. +open class SourceSelectionCriteria { + ReplicaModifications: (ReplicaModifications)? + SseKmsEncryptedObjects: (SseKmsEncryptedObjects)? } -open class ReplicationTimeValue { - Minutes: Int|Mapping +typealias SseKmsEncryptedObjectsStatus = "Disabled"|"Enabled" + +/// A container for filter information for the selection of S3 objects encrypted with AWS KMS. +open class SseKmsEncryptedObjects { + Status: SseKmsEncryptedObjectsStatus|Mapping } -typealias CorsRuleAllowedMethods = "GET"|"PUT"|"HEAD"|"POST"|"DELETE" +/// the Amazon Resource Name (ARN) of the specified bucket. +open class Arn { +} -open class CorsRule { - AllowedOrigins: Listing - ExposedHeaders: (Listing)? - Id: (String|Mapping)? - MaxAge: (Int|Mapping)? - AllowedHeaders: (Listing)? - AllowedMethods: Listing +/// Specifies the days since the initiation of an incomplete multipart upload that Amazon S3 will wait before permanently removing all parts of the upload. For more information, see [Stopping Incomplete Multipart Uploads Using a Bucket Lifecycle Policy](https://docs.aws.amazon.com/AmazonS3/latest/dev/mpuoverview.html#mpu-abort-incomplete-mpu-lifecycle-config) in the *Amazon S3 User Guide*. +open class AbortIncompleteMultipartUpload { + DaysAfterInitiation: Int|Mapping } -open class FilterRule { - Name: String|Mapping - Value: String|Mapping +/// Describes the notification configuration for an Amazon S3 bucket. +/// +/// If you create the target resource and related permissions in the same template, you might have a circular dependency. +/// For example, you might use the ``AWS::Lambda::Permission`` resource to grant the bucket permission to invoke an AWS Lambda function. However, AWS CloudFormation can't create the bucket until the bucket has permission to invoke the function (AWS CloudFormation checks whether the bucket can invoke the function). If you're using Refs to pass the bucket name, this leads to a circular dependency. +/// To avoid this dependency, you can create all resources without specifying the notification configuration. Then, update the stack with a notification configuration. +/// For more information on permissions, see [AWS::Lambda::Permission](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-lambda-permission.html) and [Granting Permissions to Publish Event Notification Messages to a Destination](https://docs.aws.amazon.com/AmazonS3/latest/dev/NotificationHowTo.html#grant-destinations-permissions-to-s3). +open class NotificationConfiguration { + EventBridgeConfiguration: (EventBridgeConfiguration)? + LambdaConfigurations: (Listing)? + QueueConfigurations: (Listing)? + TopicConfigurations: (Listing)? } +/// The PublicAccessBlock configuration that you want to apply to this Amazon S3 bucket. You can enable the configuration options in any combination. For more information about when Amazon S3 considers a bucket or object public, see [The Meaning of "Public"](https://docs.aws.amazon.com/AmazonS3/latest/dev/access-control-block-public-access.html#access-control-block-public-access-policy-status) in the *Amazon S3 User Guide*. open class PublicAccessBlockConfiguration { BlockPublicAcls: (Boolean|Mapping)? BlockPublicPolicy: (Boolean|Mapping)? @@ -330,116 +440,156 @@ open class PublicAccessBlockConfiguration { RestrictPublicBuckets: (Boolean|Mapping)? } -open class iso8601UTC { +/// Specifies data related to access patterns to be collected and made available to analyze the tradeoffs between different storage classes for an Amazon S3 bucket. +open class StorageClassAnalysis { + DataExport: (DataExport)? } +/// Amazon S3 can send events to Amazon EventBridge whenever certain events happen in your bucket, see [Using EventBridge](https://docs.aws.amazon.com/AmazonS3/latest/userguide/EventBridge.html) in the *Amazon S3 User Guide*. +/// +/// Unlike other destinations, delivery of events to EventBridge can be either enabled or disabled for a bucket. If enabled, all events will be sent to EventBridge and you can use EventBridge rules to route events to additional targets. For more information, see [What Is Amazon EventBridge](https://docs.aws.amazon.com/eventbridge/latest/userguide/eb-what-is.html) in the *Amazon EventBridge User Guide* open class EventBridgeConfiguration { EventBridgeEnabled: Boolean|Mapping } -typealias PartitionedPrefixPartitionDateSource = "EventTime"|"DeliveryTime" +typealias OwnershipControlsRuleObjectOwnership = "ObjectWriter"|"BucketOwnerPreferred"|"BucketOwnerEnforced" -open class PartitionedPrefix { - PartitionDateSource: (PartitionedPrefixPartitionDateSource|Mapping)? +/// Specifies an Object Ownership rule. +/// +/// S3 Object Ownership is an Amazon S3 bucket-level setting that you can use to disable access control lists (ACLs) and take ownership of every object in your bucket, simplifying access management for data stored in Amazon S3. For more information, see [Controlling ownership of objects and disabling ACLs](https://docs.aws.amazon.com/AmazonS3/latest/userguide/about-object-ownership.html) in the *Amazon S3 User Guide*. +open class OwnershipControlsRule { + ObjectOwnership: (OwnershipControlsRuleObjectOwnership|Mapping)? } -open class ReplicationRuleAndOperator { - Prefix: (String|Mapping)? - TagFilters: (Listing)? -} +typealias MetricsStatus = "Disabled"|"Enabled" -open class WebsiteConfiguration { - IndexDocument: (String|Mapping)? - RoutingRules: (Listing)? - RedirectAllRequestsTo: (RedirectAllRequestsTo)? - ErrorDocument: (String|Mapping)? +/// A container specifying replication metrics-related settings enabling replication metrics and events. +open class Metrics { + EventThreshold: (ReplicationTimeValue)? + Status: MetricsStatus|Mapping } -typealias RuleStatus = "Enabled"|"Disabled" - -open class Rule { - TagFilters: (Listing)? - NoncurrentVersionTransition: (NoncurrentVersionTransition)? - ExpiredObjectDeleteMarker: (Boolean|Mapping)? - Id: (String|Mapping)? - NoncurrentVersionExpirationInDays: (Int|Mapping)? - Status: RuleStatus|Mapping - ObjectSizeLessThan: (String(matches(Regex(#"[0-9]+"#)))|Mapping)? - Transitions: (Listing)? - ExpirationDate: (iso8601UTC)? - ObjectSizeGreaterThan: (String(matches(Regex(#"[0-9]+"#)))|Mapping)? - AbortIncompleteMultipartUpload: (AbortIncompleteMultipartUpload)? - NoncurrentVersionExpiration: (NoncurrentVersionExpiration)? - NoncurrentVersionTransitions: (Listing)? - Prefix: (String|Mapping)? - Transition: (Transition)? - ExpirationInDays: (Int|Mapping)? -} +typealias ReplicaModificationsStatus = "Enabled"|"Disabled" -open class NoncurrentVersionExpiration { - NoncurrentDays: Int|Mapping - NewerNoncurrentVersions: (Int|Mapping)? +/// A filter that you can specify for selection for modifications on replicas. +open class ReplicaModifications { + Status: ReplicaModificationsStatus|Mapping } -typealias TransitionStorageClass = "DEEP_ARCHIVE"|"GLACIER"|"Glacier"|"GLACIER_IR"|"INTELLIGENT_TIERING"|"ONEZONE_IA"|"STANDARD_IA" - -open class Transition { - StorageClass: TransitionStorageClass|Mapping - TransitionDate: (iso8601UTC)? - TransitionInDays: (Int|Mapping)? -} +typealias RedirectRuleProtocol = "http"|"https" -open class ObjectLockConfiguration { - ObjectLockEnabled: (String|Mapping)? - Rule: (ObjectLockRule)? +/// Specifies how requests are redirected. In the event of an error, you can specify a different error code to return. +open class RedirectRule { + HostName: (String|Mapping)? + HttpRedirectCode: (String|Mapping)? + Protocol: (RedirectRuleProtocol|Mapping)? + ReplaceKeyPrefixWith: (String|Mapping)? + ReplaceKeyWith: (String|Mapping)? } +/// The ``AWS::S3::Bucket`` resource creates an Amazon S3 bucket in the same AWS Region where you create the AWS CloudFormation stack. +/// +/// To control how AWS CloudFormation handles the bucket when the stack is deleted, you can set a deletion policy for your bucket. You can choose to *retain* the bucket or to *delete* the bucket. For more information, see [DeletionPolicy Attribute](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-attribute-deletionpolicy.html). +/// You can only delete empty buckets. Deletion fails for buckets that have contents. open class Bucket extends cloudformation.Resource { Type = "AWS::S3::Bucket" - hidden CorsConfiguration: (CorsConfiguration)? - hidden MetricsConfigurations: (Listing)? + +/// Indicates whether this bucket has an Object Lock configuration enabled. Enable ``ObjectLockEnabled`` when you apply ``ObjectLockConfiguration`` to a bucket. hidden ObjectLockEnabled: (Boolean|Mapping)? - hidden VersioningConfiguration: (VersioningConfiguration)? - hidden AccelerateConfiguration: (AccelerateConfiguration)? - hidden BucketEncryption: (BucketEncryption)? - hidden InventoryConfigurations: (Listing)? - hidden NotificationConfiguration: (NotificationConfiguration)? + +/// This is a legacy property, and it is not recommended for most use cases. A majority of modern use cases in Amazon S3 no longer require the use of ACLs, and we recommend that you keep ACLs disabled. For more information, see [Controlling object ownership](https://docs.aws.amazon.com//AmazonS3/latest/userguide/about-object-ownership.html) in the *Amazon S3 User Guide*. +/// +/// A canned access control list (ACL) that grants predefined permissions to the bucket. For more information about canned ACLs, see [Canned ACL](https://docs.aws.amazon.com/AmazonS3/latest/dev/acl-overview.html#canned-acl) in the *Amazon S3 User Guide*. +/// S3 buckets are created with ACLs disabled by default. Therefore, unless you explicitly set the [AWS::S3::OwnershipControls](https://docs.aws.amazon.com//AWSCloudFormation/latest/UserGuide/aws-properties-s3-bucket-ownershipcontrols.html) property to enable ACLs, your resource will fail to deploy with any value other than Private. Use cases requiring ACLs are uncommon. +/// The majority of access control configurations can be successfully and more easily achieved with bucket policies. For more information, see [AWS::S3::BucketPolicy](https://docs.aws.amazon.com//AWSCloudFormation/latest/UserGuide/aws-properties-s3-policy.html). For examples of common policy configurations, including S3 Server Access Logs buckets and more, see [Bucket policy examples](https://docs.aws.amazon.com/AmazonS3/latest/userguide/example-bucket-policies.html) in the *Amazon S3 User Guide*. + hidden AccessControl: (BucketAccessControl|Mapping)? + +/// An arbitrary set of tags (key-value pairs) for this S3 bucket. + hidden Tags: (Listing)? + +/// Describes the cross-origin access configuration for objects in an Amazon S3 bucket. For more information, see [Enabling Cross-Origin Resource Sharing](https://docs.aws.amazon.com/AmazonS3/latest/dev/cors.html) in the *Amazon S3 User Guide*. + hidden CorsConfiguration: (CorsConfiguration)? + +/// Specifies the lifecycle configuration for objects in an Amazon S3 bucket. For more information, see [Object Lifecycle Management](https://docs.aws.amazon.com/AmazonS3/latest/dev/object-lifecycle-mgmt.html) in the *Amazon S3 User Guide*. + hidden LifecycleConfiguration: (LifecycleConfiguration)? + +/// Settings that define where logs are stored. + hidden LoggingConfiguration: (LoggingConfiguration)? + +/// Configuration that defines how Amazon S3 handles Object Ownership rules. hidden OwnershipControls: (OwnershipControls)? + +/// Specifies the configuration and any analyses for the analytics filter of an Amazon S3 bucket. hidden AnalyticsConfigurations: (Listing)? - hidden IntelligentTieringConfigurations: (Listing)? - hidden ObjectLockConfiguration: (ObjectLockConfiguration)? - hidden BucketName: (String(matches(Regex(#"^[a-z0-9][a-z0-9//.//-]*[a-z0-9]$"#)))|Mapping)? - hidden LifecycleConfiguration: (LifecycleConfiguration)? + +/// Configuration that defines how Amazon S3 handles public access. hidden PublicAccessBlockConfiguration: (PublicAccessBlockConfiguration)? - hidden AccessControl: (BucketAccessControl|Mapping)? + +/// Configuration for replicating objects in an S3 bucket. To enable replication, you must also enable versioning by using the ``VersioningConfiguration`` property. +/// +/// Amazon S3 can store replicated objects in a single destination bucket or multiple destination buckets. The destination bucket or buckets must already exist. hidden ReplicationConfiguration: (ReplicationConfiguration)? + +/// Information used to configure the bucket as a static website. For more information, see [Hosting Websites on Amazon S3](https://docs.aws.amazon.com/AmazonS3/latest/dev/WebsiteHosting.html). hidden WebsiteConfiguration: (WebsiteConfiguration)? - hidden Tags: (Listing)? - hidden LoggingConfiguration: (LoggingConfiguration)? + +/// Configures the transfer acceleration state for an Amazon S3 bucket. For more information, see [Amazon S3 Transfer Acceleration](https://docs.aws.amazon.com/AmazonS3/latest/dev/transfer-acceleration.html) in the *Amazon S3 User Guide*. + hidden AccelerateConfiguration: (AccelerateConfiguration)? + +/// A name for the bucket. If you don't specify a name, AWS CloudFormation generates a unique ID and uses that ID for the bucket name. The bucket name must contain only lowercase letters, numbers, periods (.), and dashes (-) and must follow [Amazon S3 bucket restrictions and limitations](https://docs.aws.amazon.com/AmazonS3/latest/dev/BucketRestrictions.html). For more information, see [Rules for naming Amazon S3 buckets](https://docs.aws.amazon.com/AmazonS3/latest/dev/BucketRestrictions.html#bucketnamingrules) in the *Amazon S3 User Guide*. +/// +/// If you specify a name, you can't perform updates that require replacement of this resource. You can perform updates that require no or some interruption. If you need to replace the resource, specify a new name. + hidden BucketName: (String(matches(Regex(#"^[a-z0-9][a-z0-9//.//-]*[a-z0-9]$"#)))|Mapping)? + +/// Configuration that defines how Amazon S3 handles bucket notifications. + hidden NotificationConfiguration: (NotificationConfiguration)? + +/// Specifies default encryption for a bucket using server-side encryption with Amazon S3-managed keys (SSE-S3), AWS KMS-managed keys (SSE-KMS), or dual-layer server-side encryption with KMS-managed keys (DSSE-KMS). For information about the Amazon S3 default encryption feature, see [Amazon S3 Default Encryption for S3 Buckets](https://docs.aws.amazon.com/AmazonS3/latest/dev/bucket-encryption.html) in the *Amazon S3 User Guide*. + hidden BucketEncryption: (BucketEncryption)? + +/// This operation is not supported by directory buckets. +/// +/// Places an Object Lock configuration on the specified bucket. The rule specified in the Object Lock configuration will be applied by default to every new object placed in the specified bucket. For more information, see [Locking Objects](https://docs.aws.amazon.com/AmazonS3/latest/dev/object-lock.html). +/// + The ``DefaultRetention`` settings require both a mode and a period. +/// + The ``DefaultRetention`` period can be either ``Days`` or ``Years`` but you must select one. You cannot specify ``Days`` and ``Years`` at the same time. +/// + You can enable Object Lock for new or existing buckets. For more information, see [Configuring Object Lock](https://docs.aws.amazon.com/AmazonS3/latest/userguide/object-lock-configure.html). + hidden ObjectLockConfiguration: (ObjectLockConfiguration)? + +/// Specifies the inventory configuration for an Amazon S3 bucket. For more information, see [GET Bucket inventory](https://docs.aws.amazon.com/AmazonS3/latest/API/RESTBucketGETInventoryConfig.html) in the *Amazon S3 API Reference*. + hidden InventoryConfigurations: (Listing)? + +/// Specifies a metrics configuration for the CloudWatch request metrics (specified by the metrics configuration ID) from an Amazon S3 bucket. If you're updating an existing metrics configuration, note that this is a full replacement of the existing metrics configuration. If you don't include the elements you want to keep, they are erased. For more information, see [PutBucketMetricsConfiguration](https://docs.aws.amazon.com/AmazonS3/latest/API/RESTBucketPUTMetricConfiguration.html). + hidden MetricsConfigurations: (Listing)? + +/// Enables multiple versions of all objects in this bucket. You might enable versioning to prevent objects from being deleted or overwritten by mistake or to archive objects so that you can retrieve previous versions of them. + hidden VersioningConfiguration: (VersioningConfiguration)? + +/// Defines how Amazon S3 handles Intelligent-Tiering storage. + hidden IntelligentTieringConfigurations: (Listing)? Properties { - ["CorsConfiguration"] = if (CorsConfiguration == null) null else CorsConfiguration - ["MetricsConfigurations"] = if (MetricsConfigurations == null) null else MetricsConfigurations ["ObjectLockEnabled"] = if (ObjectLockEnabled == null) null else ObjectLockEnabled - ["VersioningConfiguration"] = if (VersioningConfiguration == null) null else VersioningConfiguration - ["AccelerateConfiguration"] = if (AccelerateConfiguration == null) null else AccelerateConfiguration - ["BucketEncryption"] = if (BucketEncryption == null) null else BucketEncryption - ["InventoryConfigurations"] = if (InventoryConfigurations == null) null else InventoryConfigurations - ["NotificationConfiguration"] = if (NotificationConfiguration == null) null else NotificationConfiguration + ["AccessControl"] = if (AccessControl == null) null else AccessControl + ["Tags"] = if (Tags == null) null else Tags + ["CorsConfiguration"] = if (CorsConfiguration == null) null else CorsConfiguration + ["LifecycleConfiguration"] = if (LifecycleConfiguration == null) null else LifecycleConfiguration + ["LoggingConfiguration"] = if (LoggingConfiguration == null) null else LoggingConfiguration ["OwnershipControls"] = if (OwnershipControls == null) null else OwnershipControls ["AnalyticsConfigurations"] = if (AnalyticsConfigurations == null) null else AnalyticsConfigurations - ["IntelligentTieringConfigurations"] = if (IntelligentTieringConfigurations == null) null else IntelligentTieringConfigurations - ["ObjectLockConfiguration"] = if (ObjectLockConfiguration == null) null else ObjectLockConfiguration - ["BucketName"] = if (BucketName == null) null else BucketName - ["LifecycleConfiguration"] = if (LifecycleConfiguration == null) null else LifecycleConfiguration ["PublicAccessBlockConfiguration"] = if (PublicAccessBlockConfiguration == null) null else PublicAccessBlockConfiguration - ["AccessControl"] = if (AccessControl == null) null else AccessControl ["ReplicationConfiguration"] = if (ReplicationConfiguration == null) null else ReplicationConfiguration ["WebsiteConfiguration"] = if (WebsiteConfiguration == null) null else WebsiteConfiguration - ["Tags"] = if (Tags == null) null else Tags - ["LoggingConfiguration"] = if (LoggingConfiguration == null) null else LoggingConfiguration + ["AccelerateConfiguration"] = if (AccelerateConfiguration == null) null else AccelerateConfiguration + ["BucketName"] = if (BucketName == null) null else BucketName + ["NotificationConfiguration"] = if (NotificationConfiguration == null) null else NotificationConfiguration + ["BucketEncryption"] = if (BucketEncryption == null) null else BucketEncryption + ["ObjectLockConfiguration"] = if (ObjectLockConfiguration == null) null else ObjectLockConfiguration + ["InventoryConfigurations"] = if (InventoryConfigurations == null) null else InventoryConfigurations + ["MetricsConfigurations"] = if (MetricsConfigurations == null) null else MetricsConfigurations + ["VersioningConfiguration"] = if (VersioningConfiguration == null) null else VersioningConfiguration + ["IntelligentTieringConfigurations"] = if (IntelligentTieringConfigurations == null) null else IntelligentTieringConfigurations } } diff --git a/pkl/cloudformation.pkl b/pkl/cloudformation.pkl index 773879aa..7645fcc4 100644 --- a/pkl/cloudformation.pkl +++ b/pkl/cloudformation.pkl @@ -7,9 +7,7 @@ open class Resource { Metadata: Mapping? UpdatePolicy: Mapping? UpdateReplacePolicy: String? - function Ref(to: String): Mapping = new Mapping { - ["Ref"] = to - } + } open class Parameter { @@ -19,3 +17,16 @@ open class Parameter { Description: String? } +function Ref(to: String): Mapping = new Mapping { + ["Ref"] = to +} + +function Sub(sub: String): Mapping = new Mapping { + ["Fn::Sub"] = sub +} + +function GetAtt(att: String): Mapping = new Mapping { + ["Fn::GetAtt"] = att +} + + diff --git a/pkl/patterns/bucket.pkl b/pkl/patterns/bucket.pkl index ab845210..1649202e 100644 --- a/pkl/patterns/bucket.pkl +++ b/pkl/patterns/bucket.pkl @@ -1,5 +1,7 @@ -import "../cloudformation.pkl" +import "../cloudformation.pkl" as cfn import "../aws/s3/bucket.pkl" as bucket +import "../aws/iam/rolepolicy.pkl" as rolepolicy +import "../aws/iam/role.pkl" as role open class SecureBucket extends bucket.Bucket { Metadata = new Mapping { @@ -54,15 +56,97 @@ open class SecureBucket extends bucket.Bucket { } } -// TODO: LogBucket, etc (like rain module) +// This is the only way I could think of to emit more than one resource +function resources(appName: String, logicalId: String): Mapping = new Mapping { -function resources(appName: String): Mapping = new Mapping { - ["SecureBucket"] = new SecureBucket { - BucketName = new Mapping { - ["Fn::Sub"] = "\(appName)-${AWS::Region}-${AWS::AccountId}" + [logicalId] = new SecureBucket { + BucketName = cfn.Sub("\(appName)-${AWS::Region}-${AWS::AccountId}") + ObjectLockEnabled = false + ObjectLockConfiguration = null + LoggingConfiguration { + DestinationBucketName = cfn.Ref("Log\(logicalId)") } + ReplicationConfiguration { + Role = cfn.GetAtt(logicalId + "ReplicationRole.Arn") + Rules { + new { + Destination { + Bucket = cfn.GetAtt("Replica\(logicalId).Arn") + } + Status = "Enabled" + } + } + } + VersioningConfiguration { + Status = "Enabled" + } + } + + ["Log" + logicalId] = new SecureBucket { + BucketName = cfn.Sub("\(appName)-logs-${AWS::Region}-${AWS::AccountId}") + + } + + ["Replica" + logicalId] = new SecureBucket { + BucketName = cfn.Sub("\(appName)-replicas-${AWS::Region}-${AWS::AccountId}") + ObjectLockEnabled = false + ObjectLockConfiguration = null + } + + [logicalId + "ReplicationPolicy"] = new rolepolicy.RolePolicy { + PolicyDocument { + Statement = new Listing { + new { + Action = new Listing { + "s3:GetReplicationConfiguration" + "s3:ListBucket" + } + Effect = "Allow" + Resource = cfn.Sub("arn:aws:s3:::\(appName)-${AWS::Region}-${AWS::AccountId}") + } + new { + Action { + "s3:GetObjectVersionForReplication" + "s3:GetObjectVersionAcl" + "s3:GetObjectVersionTagging" + } + Effect = "Allow" + Resource = cfn.Sub("arn:aws:s3:::\(appName)-${AWS::Region}-${AWS::AccountId}/*") + } + new { + Action { + "s3:ReplicateObject" + "s3:ReplicateDelete" + "s3:ReplicationTags" + } + Effect = "Allow" + Resource = cfn.Sub("arn:aws:s3:::\(appName)-replicas-${AWS::Region}-${AWS::AccountId}/*") + } + } + Version = "2012-10-17" + } + PolicyName = "bucket-replication-policy" + RoleName = cfn.Ref(logicalId + "ReplicationRole") } - ["OtherBucket"] = new SecureBucket {} + [logicalId + "ReplicationRole"] = new role.Role { + AssumeRolePolicyDocument { + Statement = new Listing { + new { + Action = new Listing { + "sts:AssumeRole" + } + Effect = "Allow" + Principal { + Service = new Listing { + "s3.amazonaws.com" + } + } + } + } + Version = "2012-10-17" + } + Path = "/" + } } diff --git a/scripts/pklgen.sh b/scripts/pklgen.sh index 4f96adb1..0cf2defb 100755 --- a/scripts/pklgen.sh +++ b/scripts/pklgen.sh @@ -1,5 +1,7 @@ #!/usr/local/bin/bash +set -eou pipefail + echo "Building rain..." ./scripts/build.sh @@ -8,5 +10,16 @@ echo "Building pkl classes..." echo "AWS::S3::Bucket" ./rain build --pkl-class AWS::S3::Bucket > pkl/aws/s3/bucket.pkl pkl eval pkl/aws/s3/bucket.pkl + +echo "AWS::IAM::RolePolicy" +./rain build --pkl-class AWS::IAM::RolePolicy > pkl/aws/iam/rolepolicy.pkl +pkl eval pkl/aws/iam/rolepolicy.pkl + +echo "AWS::IAM::Role" +./rain build --pkl-class AWS::IAM::Role > pkl/aws/iam/role.pkl +pkl eval pkl/aws/iam/role.pkl + +echo "Testing patterns..." pkl eval test/pkl/bucket.pkl | ./rain fmt | cfn-lint +echo "Success!" diff --git a/test/pkl/bucket.pkl b/test/pkl/bucket.pkl index e18f04b1..dd0b9b86 100644 --- a/test/pkl/bucket.pkl +++ b/test/pkl/bucket.pkl @@ -1,6 +1,7 @@ // Represents a CloudFormation template that creates buckets amends "modules/template.pkl" +import "modules/cloudformation.pkl" as cfn import "modules/aws/s3/bucket.pkl" as bucket import "modules/patterns/bucket.pkl" as pattern @@ -32,7 +33,7 @@ Resources { } ["TypedBucket2"] = new bucket.Bucket { - BucketName = Ref("Name") + BucketName = cfn.Ref("Name") } for (name in List("bucketx", "buckety", "bucketz")) { @@ -42,8 +43,8 @@ Resources { } // Import multiple resources from a pattern module - for (_key, _val in pattern.resources("my-app")) { - ["My" + _key] = _val + for (_key, _val in pattern.resources("my-app", "SecureBucket")) { + [_key] = _val } } diff --git a/test/pkl/required-any.pkl b/test/pkl/required-any.pkl new file mode 100644 index 00000000..b726ac15 --- /dev/null +++ b/test/pkl/required-any.pkl @@ -0,0 +1,21 @@ +open class Test { + hidden Foo: Dynamic + hidden Str: String + + Props { + ["Foo"] = Foo + ["Str"] = Str + } +} + +t = new Test { + Foo { + Bar = "Baz" + } + + // This works + // Foo = "" + + Str = "" +} + diff --git a/test/pkl/role.pkl b/test/pkl/role.pkl new file mode 100644 index 00000000..e692b5dd --- /dev/null +++ b/test/pkl/role.pkl @@ -0,0 +1,21 @@ +import "../../pkl/aws/iam/role.pkl" + +a = new role.Role { + AssumeRolePolicyDocument { + Statement = new Listing { + new { + Action = new Listing { + "sts:AssumeRole" + } + Effect = Allow + Principal { + Service = new Listing { + "s3.amazonaws.com" + } + } + } + } + Version = "2012-10-17" + } + Path = "/" +}