S3 Default server side encryption on large number of buckets using Python boto3

Question:

Hi Iam trying to turn on default s3 encryption on all my buckets in an account using python boto3 script see below.

import boto3
from botocore.exceptions import ClientError


s3 = boto3.client('s3')

response = s3.list_buckets()

for bucket in response['Buckets']:
    enc = s3.get_bucket_encryption(Bucket=bucket['Name'])
    s3.put_bucket_encryption(
        Bucket=bucket['Name'],
        ServerSideEncryptionConfiguration={
          'Rules': [
            {
                'ApplyServerSideEncryptionByDefault': {
                    'SSEAlgorithm': 'AES256'
                }
            },
          ]
        }
    )

But i am struggling with my code which is not working

gives error

  File "apply.py", line 10, in <module>
    enc = s3.get_bucket_encryption(Bucket=bucket['Name'])
  File "/Users/hhaqqani/Library/Python/2.7/lib/python/site-packages/botocore/client.py", line 272, in _api_call
    return self._make_api_call(operation_name, kwargs)
  File "/Users/hhaqqani/Library/Python/2.7/lib/python/site-packages/botocore/client.py", line 576, in _make_api_call
    raise error_class(parsed_response, operation_name)
botocore.exceptions.ClientError: An error occurred (ServerSideEncryptionConfigurationNotFoundError) when calling the GetBucketEncryption operation: The server side encryption configuration was not found

Asked By: DevopsAgentOfChaos

||

Answers:

You are passing the wrong bucket name. Change Bucket=enc to Bucket=bucket['Name'] in your call to put_bucket_encryption.

Note also that the call to get_bucket_encryption will throw an exception if the bucket does not actually have encryption configured. While that might seem odd, that’s the way it works (see boto3/issues/1899 for more details). So, to handle this potential exception:

SSECNF = 'ServerSideEncryptionConfigurationNotFoundError'

try:
    bucket = client.get_bucket_encryption(Bucket=bucket['Name'])
    # check current encryption here, if it's not what you want then update it
    # check bucket['ServerSideEncryptionConfiguration']['Rules']
except client.exceptions.ClientError as e:
    if e.response['Error']['Code'] == SSECNF:
        s3.put_bucket_encryption(...)
    else:
        print("Unexpected error: %s" % e)
Answered By: jarmod

Please see below fixed code thanks @jarmod for quick help.


import boto3
from botocore.exceptions import ClientError



s3 = boto3.client('s3')

response = s3.list_buckets()
client = boto3.client('s3')
SSECNF = 'ServerSideEncryptionConfigurationNotFoundError'
for bucket in response['Buckets']:
  try:
    bucket = client.get_bucket_encryption(Bucket=bucket['Name'])
    # check current encryption here, if it's not what you want then update it
    # check bucket['ServerSideEncryptionConfiguration']['Rules']
  except client.exceptions.ClientError as e:
    if e.response['Error']['Code'] == SSECNF:
        s3.put_bucket_encryption(Bucket=bucket['Name'],
        ServerSideEncryptionConfiguration={
          'Rules': [
            {
                'ApplyServerSideEncryptionByDefault': {
                    'SSEAlgorithm': 'AES256'
                }
            },
          ]
        })
    else:
        print("Unexpected error: %s" % e)
    ```
Answered By: DevopsAgentOfChaos