you really don't need to copy the S3 files to any EC2 instance or something like that, Amazon S3 Standard has been designed for durability of 99.999999999% of objects across multiple Availability Zones, do you know what it means? Amazon by itself replicates the S3 objects in other AZ of your region to guarantee this durability.
What AWS say about S3 :
Key Features:
- Low latency and high throughput performance
- Designed for durability of 99.999999999% of objects across multiple
Availability Zones
- Resilient against events that impact an entire Availability Zone
- Designed for 99.99% availability over a given year
- Backed with the Amazon S3 Service Level Agreement for availability
- Supports SSL for data in transit and encryption of data at rest
- S3 Lifecycle management for automatic migration of objects to other
S3 Storage Classes
Besides you already have versioning enabled ( another layer of backup ), and if you want to spend more money and replicate the bucket it's up to you, if you can afford that, you will have another layer of backup, but believe me, you don't need this, with the only S3 Standard storage will be pretty enough.
If you want to prevent object deleted accidentally and you can't enable MFA, you can create a bucket policy for avoid any type of delete action :
{
"Id": "Policy1588185431596",
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Stmt1588185426140",
"Action": [
"s3:DeleteBucket",
"s3:DeleteBucketWebsite",
"s3:DeleteObject",
"s3:DeleteObjectTagging",
"s3:DeleteObjectVersion",
"s3:DeleteObjectVersionTagging"
],
"Effect": "Deny",
"Resource": [
"arn:aws:s3:::yourbucketname/*",
"arn:aws:s3:::yourbucketname"
],
"Principal": "*"
}
]
}
If you want to restrict the Delete operation to all the users except the root user you can do this :
{
"Id": "Policy1588186664547",
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Stmt1588186644754",
"Action": [
"s3:DeleteBucket",
"s3:DeleteBucketPolicy",
"s3:DeleteBucketWebsite",
"s3:DeleteObject",
"s3:DeleteObjectTagging",
"s3:DeleteObjectVersion",
"s3:DeleteObjectVersionTagging"
],
"Effect": "Deny",
"Resource": [
"arn:aws:s3:::yourbucketname/*",
"arn:aws:s3:::yourbucketname"
],
"Condition": {
"StringNotEquals": {
"aws:userid": "AWSAccountNumber"
}
},
"Principal": "*"
}
]
}
Also, you can check your policy with the policy simulator to make sure the policy is what you are expecting.
You can add this policy to your CloudFormation Template.