README
@sjmeverett/cloudformation-types
Basically, CloudFormation in typescript instead of JSON/YAML.
Why?
CloudFormation is overwhelming at first, so I thought I'd make it a little easier. Because there are types, you get editor completion, and there are links to the AWS documentation in the JSDocs.
Since it's just Typescript, you also get expressions, conditionals, etc. You can also create NPM modules with reusable patterns, e.g. a Lambda function with API Gateway in front, and a record in Route 53.
How?
import { createLambdaFunction } from "@sjmeverett/cloudformation-types";
const fn = createLambdaFunction("MyLambdaFunction", {
FunctionName: "...",
// ... etc
});
const myStack = {
AWSTemplateFormatVersion: "2010-09-09",
Resources: getResources([fn]),
};
console.log(JSON.stringify(myStack));
The library defines a function for every CloudFormation resource type, generated by trimming the AWS::
off the front and removing other ::
in the name. E.g., AWS::Lambda::Function
becomes createLambdaFunction
.
The create
functions accept two parameters: the resource name, and an appropriately-typed Properties
definition. They simply return the CloudFormation object which can be serialised to JSON. The name is stored on a non-enumerable key referenced by a symbol exported as nameSymbol
.
Example:
fn ===
{
Type: "AWS::Lambda::Function",
Properties: {
FunctionName: "...",
// ... etc
},
[nameSymbol]: "MyLambdaFunction",
};
There are a few helper methods as well:
getName(resource)
— helper to get the name, i.e.,resource[nameSymbol]
dependsOn(resource, ...dependencies)
— adds resources to theDependsOn
field of the specified resourcegetRef(resource)
— just returns{ Ref: getName(resource) }
getAttribute(resource, attributeName)
— gets an attribute (output) from the specified resource, in a typesafe mannergetResources(resources)
— builds up the map of resource name to resource definition from an array of resourcesfnSub(str: string, vars?: Record<string, string>)
— helper forFn::Sub
intrinsic function
Note that the types returned from getRef
and getAttribute
are "faked". getRef
claims to return a string, even though it returns an object like {Ref: 'foo'}
, and getAttribute
claims to return whatever the type of the attribute you asked for, even though it actually returns {'Fn::GetAtt': 'foo'}
. I figured this was more useful, as it means you can supply an attribute value to a Property with the matching type.
How does it work?
The build process downloads a JSON file from AWS that describes all the AWS CloudFormation types, generates a Typescript file from a handlebars template, and then compiles that Typescript.