This is an experiment in using literate-programming to specify cloud infrastructure. Literate-programming allows us to create CloudFormation templates interleaved with explanations and diagrams. See these documents rendered in HTML here.
This README.org
file contains functions for deploying, updating, and tearing
down infrastructure. Within Emacs these functions are fully interactive.
Env Var | Value |
---|---|
AWS_PROFILE | dev |
AWS_DEFAULT_REGION | us-east-2 |
TEMPLATE_PATH | _out/s3/bucket.yaml |
OrgFilePath
is the relative path to the .org file that corresponds to the
$TEMPLATE_PATH
yaml file.
(let ((template-path (getenv "TEMPLATE_PATH")))
(f-join "org"
(f-swap-ext (f-relative template-path "_out" ) "org")))
Params
is the contents of the Params
table in the OrgFilePath
as a list
of pairs. Currently this table is required.
(with-temp-buffer
(insert-file-contents OrgFilePath)
(org-mode)
(car (read-from-string (org-sbe "Params"))))
$TemplateName
is the $TEMPLATE_PATH
using dashes and without a file
extension.
(let* ((template-path (getenv "TEMPLATE_PATH"))
(parent-dir (f-base (f-parent template-path)))
(base-name-dashes (s-replace "_" "-" (f-base template-path))))
(concat parent-dir "-" base-name-dashes))
$StackName
is $TemplateName
or $DeploymentName-$TemplateName
, depending
on whether the $Params
specify a $DeploymentName
.
(let ((deployment-name (assoc "DeploymentName" Params)))
(if deployment-name
(concat (nth 1 deployment-name) "-" TemplateName)
TemplateName))
CreateParamString
is a string of parameters suitable for use with the aws
cloudformation create-stack
command.
(let ((format-param (lambda (pair)
(s-format "ParameterKey=$0,ParameterValue=$1" 'elt pair))))
(s-join " " (mapcar format-param Params)))
DeployParamString
is a string of paramaters suitable for use with the aws
cloudformation deploy
command.
(let ((format-param (lambda (pair) (s-format "$0=$1" 'elt pair))))
(s-join " " (mapcar format-param Params)))
Only required if the template requires packaging. For a list of properties that can be filled in by packaging, see the package command.
TODO!
aws cloudformation package \
--template-file file://$TEMPLATE_PATH \
--output-template-file output.yaml \
--s3-bucket $BucketName
Create or update a stack.
aws cloudformation deploy \
--stack-name $StackName \
--template $TEMPLATE_PATH \
--capabilities CAPABILITY_AUTO_EXPAND CAPABILITY_IAM CAPABILITY_NAMED_IAM \
--parameter-overrides $ParamString
aws cloudformation create-stack \
--stack-name $StackName \
--template-body file://$TEMPLATE_PATH \
--capabilities \
CAPABILITY_AUTO_EXPAND CAPABILITY_IAM CAPABILITY_NAMED_IAM \
--parameters $ParamString
aws cloudformation update-stack \
--stack-name $StackName \
--template-body file://$TEMPLATE_PATH \
--capabilities CAPABILITY_AUTO_EXPAND CAPABILITY_IAM CAPABILITY_NAMED_IAM \
--parameters $ParamString
Create a change set:
aws cloudformation create-change-set \
--stack-name $StackName \
--template-body file://$TEMPLATE_PATH \
--change-set-name my-changes
Describe a change set:
aws cloudformation describe-change-set \
--change-set-name my-changes \
--stack-name $StackName
Apply a change set:
aws cloudformation execute-change-set \
--change-set-name my-changes \
--stack-name $StackName
Delete a change set. Does the change set get deleted automatically when it is applied?
aws cloudformation delete-change-set \
--change-set-name my-changes \
--stack-name $StackName
aws cloudformation delete-stack \
--stack-name $StackName
aws cloudformation describe-stack-events \
--stack-name $StackName
- [ ] Update sitemap to not include setup.html
- [ ] When deploying a stack with prerequisites, automatically deploy the
prerequisites
- [ ] Maybe, prereqs are a table? Make a func that checks if there is a stack with that name, and if not, create it.
- [ ] Use nested stacks? As is the best practice.