Architecture
An architecture overview to help with developing new plugins.
High level
At a high level the codify loads plugins from the registry which contains resources. Resources do 2 main functions, they get the current status of the system and they apply changes.
Refresh
Plugins are required to implement the async refresh(parameters: Partial<T>): Promise<Partial<T> | null>
method of the plugin library. Within this method, plugins are expected to pull the current config of the
system based on the desired parameters of the user that are passed in. The refresh method returns a config
of the current status of the system, that is to say if the returned config were to be applied no changes
would result. Codify will then calculate a change set that is needed to turn the current config generated
by refresh()
to the desired config supplied by the user.
Plan
A collection of change sets across multiple resources is called a plan. A plan consists of change sets which are
in turn composed by one resource operation and a list of parameter operations. A resource operation can be one
of: create, destroy, re-create, modify or no-op
. This controls tells the resource to create, destroy, re-create or
modify the resource. The resource level operation is calculated using a couple of factors:
- Does the current config exist? If null is returned by the refresh then the
create
operation is returned. - Based on resource parameters. If the resource exists then Codify will use the parameter operations to determine the resource operation. By default, any parameter changes will cause the resource to be re-created. However, resources can explicitly enable parameter level modifications in their configs.
- If the desired and current config matches perfectly, then
no-op
or no operation is returned
Parameter operations can be one of add, modify, remove, or no-op
. A parameter change is add
if it exists in the desired
config but not the current. modify
is returned when the parameter exists in both but the value has changed.
remove
is returned when a parameter exists in current but not desired. no-op
is returned if the parameter
stays the same between the desired and current configs.
Apply
Applies make the changes in the plan on the user’s operating system. The operations undertaken by an apply is entirely described by a plan. Plugins are required to implement:
async applyCreate(plan: CreatePlan<TerraformConfig>): Promise<void>
async applyDestroy(plan:DestroyPlan<AliasConfig>): Promise<void>
- Optionally:
applyModify(pc: ParameterChange<AliasConfig>, plan: ModifyPlan<AliasConfig>): Promise<void>
In applyCreate
a resource is expected to install packages on the operating system. In applyDestroy
the resource is expected to uninstall packages. Optionally resources to override applyModify
to apply
parameter level changes like for example in the aws-profile
resource, modify was overridden to allow the
modification of the awsAccessKeyId
and awsAccessKeySecret
without re-creating a profile.
Example: aws-cli resource
Let’s go over an example to make the overall architecture more clear.
Refresh
In the refresh method of the aws-cli
resource. The resource will check if aws cli is already installed on the
system. If it’s not then return null
, if it is then it returns an empty config {}
because the aws-cli
resource
has no parameters.
Plan
Codify will use this information to generate a change set and a plan. Based on if the current config is null or not
Codify will determine if the resource operation is apply
or no-op
.
Apply
During the Apply, Codify will choose to either call applyCreate
or not call anything at all depends on the plan.
If applyCreate
is called, the aws-cli
resource will install aws-cli
on the system using the method
recommended by AWS. For arm based macs, this means installing aws-cli
using homebrew.