Development¶
Preparing Environment¶
- Get the source code
git clone https://github.com/CloudSnorkel/cfm-reslib.git``
- Switch to the code directory
cd cfm-reslib
- Install requirements
pip install -r requirements.txt
- Create a virtual environment with all of the requirements
poetry install
Building¶
The building process creates a CloudFormation template that can be deployed and expose cfm-reslib
to be imported by
other CloudFormation stacks. This template uses Lambda and its source code needs to be uploaded to a bucket. The build
script will create both a ZIP file and a template and will upload it to a given S3 bucket.
BUCKET=my-bucket-name
poetry run python build.py $BUCKET
And just like when deploying the released versions of cfm-reslib, you can deploy this with aws
CLI tool.
BUCKET=my-bucket-name
aws cloudformation create-stack --stack-name cfm-reslib --template-url https://s3.amazonaws.com/$BUCKET/cfm-reslib-latest.template --capabilities CAPABILITY_IAM
Or when updating:
BUCKET=my-bucket-name
aws cloudformation update-stack --stack-name cfm-reslib --template-url https://s3.amazonaws.com/$BUCKET/cfm-reslib-latest.template --capabilities CAPABILITY_IAM
Note that you won’t be able to deploy multiple stacks of cfm-reslib in the same region because the exported name has to be unique across all stacks in a certain region.
Adding Custom Resources¶
There are two methods to implement a new custom resource. You will need to create a class for your resource in both.
- If the custom resource uses just one boto3 call to create, update and delete a resource, you can inherit from
cfmreslib.boto.BotoResourceHandler
. Simply override all of the constants with the names of the methods that need to be called and you’re done. Check outElasticTranscoderPipeline
for an example. - If you need more control of the process, inherit from
cfmreslib.base.CustomResourceHandler
. You will have to implement some methods that will be called for requests coming from CloudFormation. Check outRoute53Certificate
for an example.
Once you’ve added your custom resource, make sure to add it to ALL_RESOURCES
at the end of resources.py
.
Classes¶
-
class
cfmreslib.base.
CustomResourceHandler
¶ Abstract base class for all custom resources. Implement this class for new resources. Check the documentation for each method. Not all methods are always required.
-
NAME
= '<not set>'¶ Custom resource name to be used in CloudFormation with
Custom::
prefix.
-
DESCRIPTION
= '<not set>'¶ Resource description for automatically generated documentation.
-
EXAMPLES
= []¶ Optional resource examples to be used in documentation. Each example needs “title”, “description” and “template”.
-
REPLACEMENT_REQUIRED_ATTRIBUTES
= {}¶ set of properties that require a replacement on update value changes.
-
exists
() → bool¶ Checks if the resource specified in self.physical_id exists.
- Must always be implemented
Returns: True if the resource exists, False if not
-
ready
() → bool¶ Checks if the resource specified in self.physical_id is ready.
- Must always be implemented
- Can just return True if a resource existing means it’s ready
Returns: True if the resource exists, False if not
-
data
() → Optional[Dict[str, object]]¶ Retrieves the current data that should be returned for this resource.
- Only required if
_wait_ready()
is used
Returns: resource data, can be None - Only required if
-
create
(args: Dict[str, object]) → None¶ Creates a new resource with supplied arguments.
- Must set self.physical_id
- Must call
_success()
,_fail()
or_wait_ready()
- Must always be implemented
Parameters: args – arguments as passed from CloudFormation
-
can_update
(old_args: Dict[str, object], new_args: Dict[str, object], diff: List[str]) → bool¶ Checks if a resource can safely be updated or whether a new one has to be created.
- Must always be implemented, but can just return False if needed.
Parameters: - old_args – existing arguments as passed from CloudFormation for the current resource
- new_args – requested arguments as passed from CloudFormation
- diff – a list of argument names that have changed value
Returns: True if the resource can be updated or False if it needs to be recreated
-
update
(old_args: Dict[str, object], new_args: Dict[str, object], diff: List[str]) → None¶ Updates the resource specified in self.physical_id based on the old and new arguments.
- Must call
_success()
,_fail()
or_wait_ready()
- Only required if
can_update()
ever returns True.
Parameters: - old_args – existing arguments as passed from CloudFormation for the current resource
- new_args – requested arguments as passed from CloudFormation
- diff – a list of argument names that have changed value
- Must call
-
delete
() → None¶ Deletes the resource specified in self.physical_id .
- Must call
_success()
,_fail()
or_wait_delete()
- Must always be implemented
- Must call
-
get_iam_actions
() → List[str]¶ Returns a list of required IAM permissions for all operations.
- Must always be implemented
-
-
class
cfmreslib.boto.
BotoResourceHandler
¶ -
NAME
= None¶ Custom resource name to be used in CloudFormation with
Custom::
prefix.
-
SERVICE
= None¶ boto3 service name that will be used to create the client (e.g. s3, acm, ec2).
-
CREATE_METHOD
= {}¶ Descriptor for method used to create resource. Requires “name” with the name of the method, and “physical_id_query” used to query for the physical id of the newly created resource from the method return value.
-
UPDATE_METHODS
= []¶ Optional list of descriptor for methods used to update an existing resource. Each item requires “name” with the name of the method, and “physical_id_argument” with the name of the method argument that needs to have the physical id of the updated resource.
-
EXISTS_METHOD
= {}¶ Descriptor for method used to check if resource exists. Requires “name” with the name of the method, and “physical_id_argument” with the name of the method argument that needs to have the physical id of the checked resource. This method will raise the exception set in
NOT_FOUND_EXCEPTION
when the resource does not exist.
-
EXIST_READY_QUERY
= {}¶ Optional descriptor of query to check against the result of
EXISTS_METHOD
. When set we will wait until the resource is ready before finishing with create and update operations. Requires “query” with the query to run over the exists method result, “expected_value” with the expected value (e.g. READY), and “failed_values” with values that denote failure and should stop the operation.
-
DELETE_METHOD
= {}¶ Descriptor for method used to delete an existing resource. Requires “name” with the name of the method, and “physical_id_argument” with the name of the method argument that needs to have the physical id of the resource.
-
NOT_FOUND_EXCEPTION
= ''¶ Name of exception thrown by the exists method if the resource doesn’t exist.
-
EXTRA_PERMISSIONS
= []¶ A list of extra permissions required by any operations for this resource. Most permissions will be deduced by method names, but sometimes extra IAM permissions are required.
-