From a0b446918e871b104d199e83bd89e2b685166313 Mon Sep 17 00:00:00 2001 From: Adam Pippin Date: Mon, 15 Feb 2021 14:25:01 -0800 Subject: [PATCH] README contents cleaned up and migrated to wiki; remove and link there --- README.md | 320 ++---------------------------------------------------- 1 file changed, 11 insertions(+), 309 deletions(-) diff --git a/README.md b/README.md index a5bc86f..348a5f9 100644 --- a/README.md +++ b/README.md @@ -1,318 +1,20 @@ # cfnpp: cloudformation plus plus -## Goal +A tool for making it easier to write, re-use, and template CloudFormation stacks. -Make it easier to write, re-use and template CloudFormation templates +For more information, see the [wiki](wiki). -## Why did you do this? - -Writing and maintaining CloudFormation templates is tedious, but using tools that -take you _too_ far away from the CloudFormation templates gives more opportunity -for bugs to creep in and leaves you operating several months behind updates to -AWS services and CloudFormation. - -But mainly I needed something to fill up some free time. - -## What it does - -* Works with existing CloudFormation templates. (Some possible issues with the Symfony YAML parser notwithstanding.) -* Adds support for a `cfnpp:` meta block which provides some extended functionality detailed below. -* Adds several additional `!function`s detailed below. -* More planned, detailed at the end of the README. - -### Meta Block - -At the top level, a `cfnpp` block can be specified to make use of some extended functionality: - -* Includes -* Variables - -For example: - -```yaml -cfnpp: - stack: - - parent.yaml - variables: - A: 1 - B: 2 - foo: bar -``` - -#### Stack - -Any files listed will be processed in the order given _before_ the current document. If those documents specify -any documents in their stack, those will be processed before those documents in the order given and so on. - -There is nothing preventing you from including a file more than once, nor from creating a loop. It's undecided at -the time being whether this is desirable or whether we need some more complicated dependency graph or something to -process these. - -The first document is loaded, then each subsequent document is merged with it, and then any functions present processed. - -Merging follows some simple rules: - -* Maps are merged, with duplicate keys being overwritten. -* Arrays are appended. -* Scalars overwrite. -* Any type mismatch, and the value in the template being merged in simply overwrites whatever's in the original. - -For example, starting with: - -```yaml -Resources: - Resource1: - Name: My Resource Name - VpcId: vpc-1234 - AvailabilityZones: - - us-east-1a - - us-east-1b - ValidUsers: - Alice: 'aws:arn:1234:alice' - Bob: 'aws:arn:1234:bob' - AllowPorts: - - 80 - - 443 -``` - -And merging in: - -```yaml -Resources: - Resource1: - Name: New Name - AvailabilityZones: - - us-east-1c - ValidUsers: - Charlie: 'aws:arn:1234:charlie' - AllowPorts: False -``` - -Will result in: - -```yaml -Resources: - Resource1: - Name: New Name - VpcId: vpc-1234 - AvailabilityZones: - - us-east-1a - - us-east-1b - - us-east-1c - ValidUsers: - Alice: 'aws:arn:1234:alice' - Bob: 'aws:arn:1234:bob' - Charlie: 'aws:arn:1234:charlie' - AllowPorts: False -``` - -#### Variables - -Variables listed are set from all templates before the first one is processed. Variables are processed in the same -order that the documents will be compiled, and later values will overwrite earlier ones. - -That is, a base template can define some default values, and a dependent one can specify new values and they will -be visible to the base template. - -### Functions - -#### !replace - -Tells the merging process to _not_ attempt to perform any merging, but simply replace whatever's in the target document -with these values. For example, given a base template: - -```yaml -Resources; - Resource1: - AvailabilityZones: - - us-east-1a - - us-east-1b - - us-east-1c -``` - -Merging in: - -```yaml -Resources: - Resource1: - AvailabilityZones: !replace - - us-east-1c -``` - -Will result in: - -```yaml -Resources: - Resource1: - AvailabilityZones: - - us-east-1c -``` - -#### !unset - -Removes a property completely, rather than simply overriding its value or something. -The YAML parser requires that tags have a value, so simply pass '~' (null) or some -other garbage. - -Given a base template: - -```yaml -Resources: - Resource1: - Name: Test - SuperSecurityLevel: 5 -``` - -Merging in: - -```yaml -Resources: - Resource1: - SuperSecurityLevel: !unset ~ -``` - -Will result in: - -```yaml -Resources: - Resource1: - Name: Test -``` - -#### !var - -Replaced with the value of a variable. - -Given: - -```yaml -cfnpp: - variables: - A: 1 - B: - - 1 - - 2 - - 3 - -MyFavouriteNumber: !var A -SomeOtherNumbers: !var B -``` - -Will result in: - -```yaml -MyFavouriteNumber: 1 -SomeOtherNumbers: - - 1 - - 2 - - 3 -``` - -#### !if - -Conditionally include portions of the document. - -Expects to receive an array where the first element is a condition, the second is -the value if the condition is true, and the third is the value if the condition -is false (this one is optional). - -Expressions use postfix notation because this is a play project right now and -it's both fun and easy to implement and my HP calculator demanded it. Bright side, -you never have to worry about operator precedence! - -Example: - -``` -cnfpp: - variables: - LoadBalancerType: internal - -Resources: - MyLoadBalancer: - Subnet: !if - - LoadBalancerType "internal" eq - - subnet-1234 - - subnet-6789 -``` - -The true/false values can include maps/arrays/any other valid YAML. - -#### !expr - -Evaluate an expression and insert the result. - -Expects a scalar representing an expression using the same notatation as !if (and -outlined below). - -If the expression evaluates down to a single value, it will be inserted as a -scalar. If it evaluates down to multiple values, it will be inserted as an array. - -Example: - -``` -cfnpp: - variables: - A: 1 - B: 2 - C: !expr 1 2 gt - -Math: - IsALessThanB: !expr A B lt - AllMyFavouriteVariables: !expr A B - ValueOfC: !var C -``` - -Result: - -``` -Math: - IsALessThanB: True - AllMyFavouriteVariables: - - 1 - - 2 - ValueOfC: False -``` - -#### Expressions - -Expressions are composed of space separated values and operators. Valid components -are: - -* Numeric Literals: Any integer or float value. -* String Literals: Any value enclosed in double quotes (`"`). A backslash can be - used to quote/escape literal quotes within the string. -* Variables: Any non-quoted string consisting of letters and numbers (no leading - digit) is interpreted as a reference to one of the variables. -* Operator: Currently supported comparison/logical operators are: - - eq: equal - - neq: not equal - - gt: greater than - - gte: greater than or equal - - lt: less than - - lte: less than or equal - - and: boolean and - - or: boolean or -* Function: Currently supported functions are: - - concat: Concatenate as strings two values off of the stack - - concat\*: Concatenate all values currently on the stack down to a single value. - -## Usage - -### Running - -* Install dependencies with `composer install` -* Execute `cfnpp` with PHP 8, it will either complain about any missing PHP extensions or present a list of commands. -* Run `./cfnpp ` +## TODO -### Building +* Provision rendered templates directly to CloudFormation +* More flow control (e.g., foreach, etc) +* Some sort of macro system would be good. -Note: Building is not required to run. +## License -* Install dependencies with `composer install` -* Run `./cfnpp app:build`; outputs phar at builds/ +No license applied yet. No permission is granted to use, redestribute, modify, or +otherwise do anything with this software. -## TODO +## Author -* Provision rendered templates directly to CloudFormation -* Add flow control: `!if`, `!foreach`, etc -* Some sort of macro system would be good. +* Adam Pippin