Disabling AWS CloudFront distribution using Python and Boto3

AWS CloudFront is a widely-used content delivery network service and as most of Amazon Web Services elements can be configured programmatically in many ways. For beginners, the easiest way leads through the web AWS console, in which you can simply point and click to adjust a particular parameter. It works fine if you are taking care of a few services only.

For larger installations, it is better to use AWS CLI and batch scripts to handle the creation, configuration, and removal of services. In some cases, I prefer to use Python, for the sake of simplicity when talking of changes to the variables and integrations with other elements of our infrastructure.

It is especially useful during such a crazy time as we have now – Black Friday, Cyber Monday, and other marketing-heavy periods when a lot of changes need to be provided in particular moments. Hence the script below.

Preparation

In order to work with AWS using Python, you should install the Boto3 library. The installation is rather straightforward, but you should also remember to configure the AWS console – provide access and secret key and set the default region to work with.

These values can be adjusted when connecting to AWS through Boto3, but for sake of simplicity, I will assume that this is configured and you don’t have to overwrite them.

Steps to perform

There is no single command that disables CloudFront distribution. This is considered a configuration change, so you have to execute the Update Distribution command. You can build configuration from scratch, but this is way easier to pull the current configuration from CloudFront and adjust it a little.

Let’s start with the obvious things:

import boto3

distribution_id = 'E2QVVVY9A06'

cf = boto3.client('cloudfront')
distribution = cf.get_distribution(Id=distribution_id)

Once the Boto3 is imported and the distribution ID declared, we are creating AWS CloudFront Client which will take care of the next steps. The first one (still visible above) is pulling information about the distribution we want to adjust.

Now comes the housekeeping and adjustments:

ETag = distribution['ETag']
distribution_config = distribution['Distribution']['DistributionConfig']
distribution_config['Enabled'] = False

From the distribution info, we are pulling two important elements: the ETag and distribution config itself.

The ETag is the entity-tag – it is the hash value that represents the state of the object. It is required when updating distribution since we want to make sure that we are updating the distribution that is in the same state as we expect. If a different script will adjust this distribution in the meantime, the ETag of the distribution will change and your changes will not be applied.

The distribution config is useful because we will use the same config to send it back. The only change we will make is the switch in the “Enabled” variable. We will set it from True to False. This will switch the distribution to the disabled state.

Now it is time for the final command:

cf.update_distribution(DistributionConfig=distribution_config, Id=distribution_id, IfMatch=ETag)

The above is sending the request to update distribution using adjusted distribution config. We are requesting the change to the particular distribution id and its particular state described by ETag value.

The distribution update takes typically a few minutes. It is important if you want to remove such distribution – it can not be deleted programmatically as long as it is not disabled first. So, you should disable it, wait for the distribution to return to the ready state, and then remove it.

Whole script

Below you will find the whole script in one piece:

import boto3

distribution_id = 'E2QVVVY9A06'

cf = boto3.client('cloudfront')
distribution = cf.get_distribution(Id=distribution_id)

ETag = distribution['ETag']
distribution_config = distribution['Distribution']['DistributionConfig']
distribution_config['Enabled'] = False

cf.update_distribution(DistributionConfig=distribution_config, Id=distribution_id, IfMatch=ETag)