At Storage Made Easy we work/partner with many Object Storage vendors.
When a project required data automation and the use of an on-premises object storage buckets, I turned to Ansible and our storage partners. However, I found that the aws_s3 module for Ansible wasn’t as friendly and well documented when working with S3 object storage that isn’t either AWS or Ceph.
The project was simple. Pull data from a number of secure locations worldwide and send to various S3-compatible object stores.
Using the documentation and examples provided for the aws_s3 ansible module, I quickly had some code running that was able to copy data to an AWS bucket.
Example from:
https://docs.ansible.com/ansible/latest/modules/aws_s3_module.html
- name: Simple PUT operation aws_s3: bucket: mybucket object: /my/desired/key.txt src: /usr/local/myfile.txt mode: put
Once that was working, I tried to copy data to some of our various partners:
Cloudian, Scality, SwiftStack, IBM Cloud Object Storage, Minio
Per the documentation, I should have had to only add the URL endpoint of these storage providers and additionally, whether to trust self-signed certificates or if the data should be encrypted with SSE-S3 (Server Side Encryption).
s3_url: "{{ s3_endpoint }}" validate_certs: true encrypt: false
However, this code was consistently throwing errors related to the endpoint (s3_url) being invalid. This was solved by adding the flag for Rados Gateway, which is the Ceph solution for using the S3 API.
rgw: true
It’s not documented, but anytime the S3 target is not AWS, the rgw flag must be set to true when specifying an endpoint via s3_url.
This code worked for some of our partners like Cloudian, but most others still failed, now with an error related to ACLs. It turns out that every time Ansible writes an object, it’s also setting the ACL of the object which is an S3 API call that many 3rd party providers don’t yet support.
Disabling the setting of ACLs took much digging (trial /error and reading the source code), since it’s not documented. The solution was to specify an empty list for the permission flag.
permission: []
The end function for the playbook to upload a set/list of files to an on-premises object storage system like Minio, Scality or SwiftStack looks like this:
- name: Upload to Non AWS S3 Storage aws_s3: bucket: "{{ backup_bucket }}" object: "{{ item.path }}" src: "{{ item.path }}" mode: put aws_access_key: "{{ access_key }}" aws_secret_key: "{{ secret_key }}" validate_certs: (true/false) encrypt: (true/false) rgw: true permission: [] s3_url: "{{ s3_endpoint }}" loop: "{{ files_to_backup.files }}" loop_control: label: "{{ item.path }}"
I hope this article saves you hours of research (trial and error) and enables devops to use AWS S3 alternatives.







Douglas Soltesz
Latest posts by Douglas Soltesz (see all)
- LucidLink Technology Preview Setup Guide - September 6, 2021
- The features and benefits of using LucidLink with the Enterprise File Fabric - September 2, 2021