Repository: ansible-collections/amazon.aws

Issue:
Bucket name validation is too eager and should be skippable
### Summary

With the implementation of https://github.com/ansible-collections/amazon.aws/pull/341 all bucket names must adhere to Amazon S3's naming rules. While those rules are generally followed by alternative S3 implementations, they are not a given and can sometimes be disabled (at least in the case of Ceph):

> The above constraints are relaxed if the option ‘rgw_relaxed_s3_bucket_names’ is set to true except that the bucket names must still be unique, cannot be formatted as IP address and can contain letters, numbers, periods, dashes and underscores for up to 255 characters long.

https://docs.ceph.com/en/latest/radosgw/s3/bucketops/

Furthermore, the way this works is that the bucket name is checked with every `s3_bucket` operation. So those rules don't just apply to creating new buckets, but they apply to a simple `--check --diff` run as well. At the very least, this is too eager in my estimation. If at all those rules should be applied, it should happen only when necessary.

I would like to change this in one of two ways:

1. Add an option to skip validation that is off by default (e.g. `validate_bucket_names: no (default yes)`).
2. A more fine-grained implementation that only checks the bucket name before creating a bucket, not when updating/reading it.

Those approaches could of course be combined. I'm happy to provide a pull request myself, if there are no objections to my proposal.

### Issue Type

Feature Idea

### Component Name

s3_bucket

### Additional Information

_No response_

### Code of Conduct

- [X] I agree to follow the Ansible Code of Conduct


Discussion:
Hi @href, thanks for reporting this.  If you would like to propose a PR that adds the necessary conditional handling we would definitely consider it.  We do not have a Ceph cluster (or any other non-AWS S3 implementations) available to us though for development and testing.

Resolving patch:
diff --git a/plugins/modules/aws_s3.py b/plugins/modules/aws_s3.py
--- a/plugins/modules/aws_s3.py
+++ b/plugins/modules/aws_s3.py
@@ -197,6 +197,14 @@
         type: str
         description:
         - version ID of the source object.
+  validate_bucket_name:
+    description:
+      - Whether the bucket name should be validated to conform to AWS S3 naming rules.
+      - On by default, this may be disabled for S3 backends that do not enforce these rules.
+      - See https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucketnamingrules.html
+    type: bool
+    version_added: 3.1.0
+    default: True
 author:
     - "Lester Wade (@lwade)"
     - "Sloane Hertel (@s-hertel)"
@@ -928,6 +936,7 @@ def main():
         tags=dict(type='dict'),
         purge_tags=dict(type='bool', default=True),
         copy_src=dict(type='dict', options=dict(bucket=dict(required=True), object=dict(required=True), version_id=dict())),
+        validate_bucket_name=dict(type='bool', default=True),
     )
     module = AnsibleAWSModule(
         argument_spec=argument_spec,
@@ -965,7 +974,8 @@ def main():
     object_canned_acl = ["private", "public-read", "public-read-write", "aws-exec-read", "authenticated-read", "bucket-owner-read", "bucket-owner-full-control"]
     bucket_canned_acl = ["private", "public-read", "public-read-write", "authenticated-read"]
 
-    validate_bucket_name(module, bucket)
+    if module.params.get('validate_bucket_name'):
+        validate_bucket_name(module, bucket)
 
     if overwrite not in ['always', 'never', 'different', 'latest']:
         if module.boolean(overwrite):
diff --git a/plugins/modules/s3_bucket.py b/plugins/modules/s3_bucket.py
--- a/plugins/modules/s3_bucket.py
+++ b/plugins/modules/s3_bucket.py
@@ -147,6 +147,14 @@
     choices: [ 'private', 'public-read', 'public-read-write', 'authenticated-read' ]
     type: str
     version_added: 3.1.0
+  validate_bucket_name:
+    description:
+      - Whether the bucket name should be validated to conform to AWS S3 naming rules.
+      - On by default, this may be disabled for S3 backends that do not enforce these rules.
+      - See https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucketnamingrules.html
+    type: bool
+    version_added: 3.1.0
+    default: True
 
 extends_documentation_fragment:
 - amazon.aws.aws
@@ -1011,6 +1019,7 @@ def main():
         object_ownership=dict(type='str', choices=['BucketOwnerPreferred', 'ObjectWriter']),
         delete_object_ownership=dict(type='bool', default=False),
         acl=dict(type='str', choices=['private', 'public-read', 'public-read-write', 'authenticated-read']),
+        validate_bucket_name=dict(type='bool', default=True),
     )
 
     required_by = dict(
@@ -1027,7 +1036,9 @@ def main():
     )
 
     region, ec2_url, aws_connect_kwargs = get_aws_connection_info(module, boto3=True)
-    validate_bucket_name(module, module.params["name"])
+
+    if module.params.get('validate_bucket_name'):
+        validate_bucket_name(module, module.params["name"])
 
     if region in ('us-east-1', '', None):
         # default to US Standard region


Test patch: