{"id":13620635,"url":"https://github.com/UnquietCode/Cloud-Temple","last_synced_at":"2025-04-14T22:32:04.299Z","repository":{"id":22558497,"uuid":"25899659","full_name":"UnquietCode/Cloud-Temple","owner":"UnquietCode","description":"A collection of rituals and incantations which assist in the creation of modular (reusable, extensible) CloudFormation templates in JavaScript.","archived":false,"fork":false,"pushed_at":"2021-01-25T00:43:24.000Z","size":60,"stargazers_count":7,"open_issues_count":0,"forks_count":2,"subscribers_count":4,"default_branch":"master","last_synced_at":"2024-04-24T12:24:38.139Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"CoffeeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/UnquietCode.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2014-10-29T02:02:29.000Z","updated_at":"2021-01-25T00:35:52.000Z","dependencies_parsed_at":"2022-08-05T18:15:13.986Z","dependency_job_id":null,"html_url":"https://github.com/UnquietCode/Cloud-Temple","commit_stats":null,"previous_names":[],"tags_count":5,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/UnquietCode%2FCloud-Temple","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/UnquietCode%2FCloud-Temple/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/UnquietCode%2FCloud-Temple/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/UnquietCode%2FCloud-Temple/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/UnquietCode","download_url":"https://codeload.github.com/UnquietCode/Cloud-Temple/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248971920,"owners_count":21191688,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-01T21:00:57.970Z","updated_at":"2025-04-14T22:32:03.994Z","avatar_url":"https://github.com/UnquietCode.png","language":"CoffeeScript","funding_links":[],"categories":["CoffeeScript"],"sub_categories":[],"readme":"# Cloud Temple (v1.0.2)\n\n##### `npm install cloud-temple`\n\nA collection of rituals and incantations which assist in the creation of modular (reusable, extensible) AWS [CloudFormation](http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/Welcome.html) templates in JavaScript.\n\nThe examples below are written in [CoffeeScript](http://coffeescript.org) and assume you are using **Node.js**, but these are not hard requirements.\n\n\n### Stop repeating yourself!\nThere's no reason to repeat the same parameters and resources in all of your templates. When it comes time for you change something, you end up editing all of your templates instead of a few small declarations. This limitation arises primarily through the lack of composibility of JSON documents, which is simply not a problem when using a richer language like CoffeeScript.\n\n```coffee\n# DataVolume.coffee\nResource = require('cloud-temple').Resource\n\nmodule.exports = Resource(\"DataVolume\", \"AWS::EC2::Volume\"\n  Size : \"100\"\n  Encrypted: true\n  AvailabilityZone : \"us-east-1a\"\n)\n```\n\n### Write once, use many.\nWrite a component, use it once, then use it again and again. You shouldn't have to repeat the definition of a component simply to change its ID or a couple of measly properties. Cloud Temple lets you specify a component's identifier spearately, so that you can reuse the same basic component across your templates.\n\n```coffee\n# create a new Resource constructor\nVolume = Resource(\"AWS::EC2::Volume\"\n  Size : \"100\"\n  Encrypted: true\n  AvailabilityZone : \"us-east-1a\"\n)\n\n# use the constructor to make a new instance\nDatabaseVolume = Volume(\"DataVolume\")\n\n# make another instance, with some properties overridden\nScratchDisk = Volume(\"TempVolume\"\n  Size: \"50\"\n)\n\n# properties can also be replaced after construction\nScratchDisk.Encrypted = false\n```\n\n\n## Table of Contents\n1. [Templates](#templates)\n1. [Parameters](#parameters)\n1. [Resources](#resources)\n1. [Outputs](#outputs)\n1. [Mappings](#mappings)\n1. [Intrinsic Functions](#functions)\n1. [Referencing Components](#referencing)\n1. [Pseudo Parameters](#pseudos)\n1. [Helper Functions](#helpers)\n\n\n\u003ca name=\"templates\"\u003e\u003c/a\u003e\n## Templates ([docs](http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/template-anatomy.html))\nA `Template` is a collection of components, divided into the three main categories of \"Parameters\", \"Resources\", and \"Outputs\".\n\n### To create a new Template:\n```coffee\nTemplate = require('cloud-temple').Template\n\ntemplate1 = Template()\ntemplate2 = Template(\"a description can also be provided\")\n```\n\n### To add a Parameter to a Template:\n```coffee\nA = Parameter(...)\nB = Parameter(...)\n\n# singular\ntemplate.addParameter(A).addParameter(B)\n\n# plural\ntemplate.addParameters(A, B)\n```\n\n### To add a Resource to a Template:\n```coffee\nA = Resource(...)\nB = Resource(...)\n\n# singular\ntemplate.addResource(A).addResource(B)\n\n# plural\ntemplate.addResources(A, B)\n```\n\n### To add an Output to a Template:\n```coffee\nA = Output(...)\nB = Output(...)\n\n# singular\ntemplate.addOutput(A).addOutput(B)\n\n# plural\ntemplate.addOutputs(A, B)\n```\n\n### To add any component to a Template:\nSometimes you may not readily know the type of a component. You can add any `Parameter`, `Resource` or `Output` by using the `add(...)` function.\n\n```coffee\ntemplate.add(component)\n```\n\n### To copy a Template:\nYou can create a copy of a template and all of its components, optionally changing its description in the process.\n\n```coffee\nnewTemplate = oldTemplate.copy(\"Optional New Description\")\n```\n\n### To render a Template as JSON:\n```coffee\nconsole.log template.toJson()\n```\n\n\n\u003ca name=\"parameters\"\u003e\u003c/a\u003e\n## Parameters ([docs](http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/parameters-section-structure.html))\n`Parameter` components are used for accepting inputs to your template.\n\n### To create a new Parameter with an ID:\nThe `Parameter` constructor function accepts two parameters, where the first is the ID and the second is an object containing the various properties.\n\n```coffee\nParameter = require('cloud-temple').Parameter\n\nDBPortParameter = Parameter(\"DBPort\"\n  Type: \"Number\"\n  Default: \"3306\"\n  Description: \"TCP/IP port for the database\"\n  MinValue: \"1150\"\n  MaxValue: \"65535\"\n)\n```\n\n### To create a new reusable Parameter:\nYou can create multiple parameters from a single definition by using the overloaded `Parameter` constructor, which defers creation and allows the ID to be provided later.\n\n```coffee\nParameter = require('cloud-temple').Parameter\n\nPortParameter = Parameter(\n  Type: \"Number\"\n  Default: \"3306\"\n  Description: \"TCP/IP port for the database\"\n  MinValue: \"1150\"\n  MaxValue: \"65535\"\n)\n\nDBPort = PortParameter(\"DBPort\")\n```\n\n### To reference a Parameter:\nParameters can be referenced in your resources and outputs by using the `Ref` function. As a shortcut to calling `Functions.Ref` and passing a parameter, you can call `.Ref()` directly on a parameter instance. (See the information on [referencing](#referencing) below.)\n\n```coffee\n# { \"Ref\" : \"ParameterID\" }\nparameter.Ref()\n```\n\n### To copy a Parameter and change some of its properties:\nSometimes it is desirable to create a copy of an existing `Parameter` in order to change some values, such as the default value, which may change between templates.\n\n```coffee\nClusterNameParameter = Parameter('ClusterName'\n  Type: \"String\"\n  Description: \"A unique name for the cluster.\"\n  AllowedPattern: \"[a-z]+[a-z0-9]*\"\n  DefaultValue: \"Balthazar\"\n)\n\nClusterName = ClusterNameParameter.copy(\n  DefaultValue: \"Melchior\"\n)\n```\n\n### To render a Parameter as JSON:\n```coffee\nconsole.log parameter.toJson()\n```\n\n\n\u003ca name=\"mappings\"\u003e\u003c/a\u003e\n## Mappings ([docs](http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/mappings-section-structure.html))\n\n### To add a mapping to a Template:\n```coffee\n# add a single map\ntemplate.addMapping(\"RegionMap\",\n  \"us-east-1\" : { \"AMI\" : \"ami-bad\" }\n\n# add multiple maps\ntemplate.addMappings(\n  RegionMap:\n    \"us-east-1\" : { \"AMI\" : \"ami-bad\" }\n)\n```\n\n\u003ca name=\"resources\"\u003e\u003c/a\u003e\n## Resources ([docs](http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/resources-section-structure.html))\nA `Resource` is an AWS component which is created as part of your stack. Like parameters, they can be referenced in other resources and outputs by ID (see the section on [referencing](#referencing) below).\n\n### To create a new Resource with an ID:\nThe `Resource` function accepts three parameters, where the first is the ID, the second is the resource type, and the third is an object containing the various properties.\n\n```coffee\nResource = require('cloud-temple').Resource\n\nDataVolume = Resource(\"DataVolume\", \"AWS::EC2::Volume\"\n  Size : \"100\"\n  Encrypted: true\n  AvailabilityZone : \"us-east-1a\"\n)\n```\n\n### To create a new reusable Resource:\nLike parameters, each resource in a template has a [unique] ID. However, to facillitate reuse it is often desirable to have the consuming templates assign their own ID. The `Resource` constructor function is overloaded to defer creation and allow the ID to be provided later.\n\n```coffee\nResource = require('cloud-temple').Resource\n\n# create a new Resource constructor\nVolume = Resource(\"AWS::EC2::Volume\"\n  Size : \"100\"\n  Encrypted: true\n  AvailabilityZone : \"us-east-1a\"\n)\n\n# create named instances using the constructor\nDatabaseVolume = Volume(\"DataVolume\")\nScratchDisk = Volume(\"TempVolume\")\n```\n\n### To access a Resource attribute:\nAs a shortcut to calling `Functions.GetAtt` and passing in a resource, you can call `.GetAtt(..)` directly on a resource instance.\n\n```coffee\n# { \"Fn::GetAtt\" : [\"ResourceID\", \"AttributeName\"] }\nresource.GetAtt(\"AttributeName\")\n```\n\n### To reference a Resource:\nResources can be referenced in other resources and outputs by using the `Ref` function. As a shortcut to calling `Functions.Ref` and passing a resource, you can call `.Ref()` directly on a parameter instance. (See the section on [referencing](#referencing) below.)\n\n```coffee\n# { \"Ref\" : \"ResourceID\" }\nresource.Ref()\n```\n\n### To add a dependency to a Resource ([docs](#where)):\nResources can have dependencies to other resources. This is sometimes necessary to ensure that resources are created in a certain order.\n\n```coffee\nServer1 = Resource(...)\nServer2 = Resource(...)\nS3Bucket = Resource(...)\n\nServer2.dependsOn(Server1, S3Bucket)\n```\n\n### To set the metadata for a Resource:\n```coffee\noldMetadata = resource.setMetadata({...})\n```\n\n### To retrieve the metadata for a Resource:\n```coffee\nmetadata = resource.getMetadata()\n```\n\n### To copy a Resource and change some of its properties:\nYou can create a copy of an existing `Resource` in order to change some of its property values or add an additional one.\n\n```coffee\nDefaultVolume = Resource(\"Volume\", \"AWS::EC2::Volume\"\n  Size : \"100\"\n  AvailabilityZone : \"us-east-1a\"\n)\n\nEncryptedVolume = DefaultVolume.copy(\n  Encrypted: true\n)\n```\n\n### To render a Resource as JSON:\n```coffee\nconsole.log resource.toJson()\n```\n\n\n\u003ca name=\"outputs\"\u003e\u003c/a\u003e\n## Outputs ([docs](http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/outputs-section-structure.html))\nYou can define outputs for your template, which can reference a `Parameter`, `Resource`, or any hard-coded or derived value. In this way you can expose values which may be unique to each template, such as input parameters or values generated during the creation of your stack.\n\n### To create a new Output:\n```coffee\nOutput = require('cloud-temple').Output\nDnsName = Output(\"DnsName\", \"a.b.com\")\n```\n\n### To create a new Output with a description:\n```coffee\nOutput = require('cloud-temple').Output\nDnsName = Output(\"DnsName\", \"main DNS entry for the stack\", \"a.b.com\")\n```\n\n### To reference a component in an Output:\nThe value of an `Output` may be a literal value, function value, pseudo parameter, or a reference to an existing `Parameter` or `Resource`. As in other places, you can simply pass in the component and this will be be interpreted as an implicit call to `.Ref()`.\n\n```coffee\nOutput = require('cloud-temple').Output\n\nVolumeMount = require('./EC2VolumeMountPoint').GetAtt('Device')\nDeviceAddress = Output(\"DeviceAddress\", VolumeMount)  # /dev/sdg\n```\n\n### To copy an Output and change its description or value:\nYou can create a copy of an existing `Output` and replace its description, value, or both.\n\n```coffee\nEnvironment = Output(\"Environment\", \"environment type of the stack\", \"production\")\n\n# replace the value\nThisEnvironment = Environment.copy(\"development\")\n\n# replace the description and the value\nThisEnvironment = Environment.copy(\"the development environment\", \"QA-2\")\n```\n\n\n\u003ca name=\"functions\"\u003e\u003c/a\u003e\n## Intrinsic Functions ([docs](http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference.html))\n\nFunctions which are available in CloudFormation templates are also available in your CoffeeScript templates under the `Functions` helper object.\n\n```coffee\nResource = require('cloud-temple').Resource\nFunctions = require('cloud-temple').Functions\n\nDataVolume = Resource(\"DataVolume\", \"AWS::EC2::Volume\"\n  Size : \"100\"\n  AvailabilityZone : Functions.Select(0, Functions.GetAZs())\n)\n```\n\n### Complete List of Functions\n\n* `Ref(id)` \u0026rarr; `{ \"Ref\" : id }`\n* `GetAtt(id, attribute)` \u0026rarr; `{ \"Fn::GetAtt\" : [id, attribute] }`\n* `Base64(string)` \u0026rarr; `{ \"Fn::Base64\" : string }`\n* `GetAZs(region=PseudoParams.Region)` \u0026rarr; `{ \"Fn::GetAZs\" : region }`\n* `Join(delimeter, values)` \u0026rarr; `{ \"Fn::Join\" : [ delimeter, values ]}`\n* `Select(index, values)` \u0026rarr; `{ \"Fn::Select\" : [ index, values ]}`\n\n\n\u003ca name=\"referencing\"\u003e\u003c/a\u003e\n## Referencing Components ([docs](http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-ref.html))\n\nTwo of the intrinsic functions, `Ref` and `GetAtt`, take the ID of an existing `Parameter` or `Resource` as input. As a convenience, these can be called directly on `Parameter` and `Resource` objects, which will make use of the component's ID.\n\n```coffee\nFunctions = require('cloud-temple').Functions\nResource = require('cloud-temple').Resource\n\nEC2Instance = require('./Server')\n\nDnsRecord = Resource(\"DnsRecord\", \"AWS::Route53::RecordSet\"\n  HostedZoneId: \"1ZHH423DMZ\"\n  Name : \"a.b.com\"\n  Type : \"A\"\n  ResourceRecords : [ EC2Instance.GetAtt(\"PublicIp\") ]\n)\n```\n\nEven more convenient, you can use a `Parameter` or `Resource` directly in another Resource's definition, or as a template output, and this will be interpreted as an implicit call to `.Ref()`.\n\n```coffee\nDataVolume = Resource(\"DataVolume\", \"AWS::EC2::Volume\"\n  Size : \"100\"\n  Encrypted: true\n  AvailabilityZone : \"us-east-1a\"\n)\n\nDataVolumeMount = Resource(\"MountPoint\", \"AWS::EC2::VolumeAttachment\"\n  InstanceId : \"i-1284g\"\n  VolumeId  : DataVolume\n  Device : \"/dev/sdg\"\n)\n```\n\n\n\u003ca name=\"pseudos\"\u003e\u003c/a\u003e\n## Pseudo Parameters ([docs](http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/pseudo-parameter-reference.html))\nIntrinsic CloudFormation parameters which are exposed to all templates are available under the `PseudoParameters` helper (also aliased to `Pseudo`). Under the hood, pseudo parameters are just `Ref` objects and can be used anywhere references are allowed.\n\n```coffee\nPseudo = require('cloud-temple').PseudoParameters\n\n# \"Outputs\": {\n#   \"MyStackRegion\": { \"Value\": { \"Ref\": \"AWS::Region\" } }\n# }\ntemplate.addOutput(\"MyStackRegion\", Pseudo.Region)\n```\n\n### Complete List of Pseudo Parameters\n* AccountId \u0026rarr; `{ \"Ref\" : \"AWS::AccountId\" }`\n* NotificationARNs \u0026rarr; `{ \"Ref\" : \"AWS::NotificationARNs\" }`\n* NoValue \u0026rarr; `{ \"Ref\" : \"AWS::NoValue\" }`\n* Region \u0026rarr; `{ \"Ref\" : \"AWS::Region\" }`\n* StackId \u0026rarr; `{ \"Ref\" : \"AWS::StackId\" }`\n* StackName \u0026rarr; `{ \"Ref\" : \"AWS::StackName\" }`\n\n\n\u003ca name=\"helpers\"\u003e\u003c/a\u003e\n## Helpers\nThere are a few functions which are included as helpers, being little more than some syntactical sugar to make creating components en masse a bit easier.\n\n### To create a series of Parameters from a regular object:\nYou can expedite the creation of parameters by using the `Parameterize` helper. This function takes as input a normal map of identifiers to property objects, and returns a map of identifiers to `Parameter` objects, where the parameter ID's are taken from the keys.\n\n```coffee\n# Parameters.coffee\nParameterize = require('cloud-temple').Parameterize\n\nmodule.exports = Parameterize\n\n  DataInstanceType:\n    Type: \"String\"\n    Description: \"instance type for database server\"\n    Default: \"m3.large\"\n\n  AppInstanceType:\n    Type: \"String\"\n    Description: \"instance type for application server\"\n    Default: \"m3.medium\"\n    \n  ....\n  \n```\n\n### To create a series of components from a regular object:\nUsing the `Componentize` helper, you can create a map of components where the ID's for Parameters and Resources are taken from the object keys, which avoids having to specify the ID twice. This is also a nice way to make use of reusable components. Where the ID has already been set (which is always true for Outputs), it is left unchanged.\n\n```coffee\n# ServerComponents.coffee\nComponentize = require('cloud-temple').Componentize\n\nmodule.exports = Componentize\n  \n  # using Parameters\n  VolumeName: Parameter({...})\n  \n  # using Resources\n  Volume: Resource(\"AWS::EC2::Volume\", {...})\n  \n  # if the component already has an ID it is left unchanged\n  Instance: Resource(\"AWS::EC2::Instance\", \"WebServerInstance\", {...})\n  \n  # setting the ID on a reusable Resource\n  DNS: require('./DnsRecord')\n  \n  # you could also include Outputs here\n  StackRegion: Output(\"StackRegion\", Pseudo.Region)\n```\n\n### To create a template from a regular object:\nYou can piece together an object containing any number Parameters, Resources, Outputs, or their deferred constructors, and automatically turn it into a full template by using the `Templatize` function. A description for the template can optionally be provided.\n\n```coffee\n# MyTemplate.coffee\n\nmodule.exports = Templatize(\"optional description\"\n\n  ParamA: Parameter({...})\n\n  ResourceB: Resource(\"resource\", \"Type\", {...})\n\n  OutC: Output(\"OutputC\", \"...\")\n\n)\n```\n\n### To create a template from an array of components:\nGiven an array of already constructed components (Parameters, Resources, and Outputs), you can automatically turn it into a template by using the overloaded `Templatize` function. A description for the template can optionally be provided.\n\n```coffee\n# MyTemplate.coffee\n\nmodule.exports = Templatize(\"optional description\", [\n  \n  Parameter(\"ParamA\", {...})\n  \n  Resource(\"ResourceB\", \"Type\", {...})\n  \n  Output(\"OutputC\", \"...\")\n\n])\n```\n\n\n\u003ca name=\"license\"\u003e\u003c/a\u003e\n## License\nCloud Temple is free and open software. Anyone is free to copy, modify, publish, use, compile, sell, or distribute this software, either in source code form or as a compiled binary, for any purpose, commercial or non-commercial, and by any means.\n\nInformation wants to be free. This software is free. Make it, break it. Use it.\n\n\n## Thanks!\nYou know, for being *you*.\n\n\n## To Do\nA few things which need to be completed for full support.\n\n* [Conditions](http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/conditions-section-structure.html) / [Condition Functions](http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-conditions.html)\n* [Custom Resources](http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/crpg-ref.html)\n* [resource attributes](http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-product-attribute-reference.html)\n  * `Metadata`\n  * `DeletionPolicy`\n  * `UpdatePolicy` \n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FUnquietCode%2FCloud-Temple","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FUnquietCode%2FCloud-Temple","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FUnquietCode%2FCloud-Temple/lists"}