:bangbang: | Litany is deprecated and is no longer being maintained.  
:---: | :---

# Litany

A ruby-based DSL to implement and utilize CloudFormation templates.

## Table of Contents

- [Getting Started](https://git-aws.internal.justin.tv/pages/CPE-Ops/litany/file.GettingStarted.html)
- [Example Projects](https://git-aws.internal.justin.tv/CPE-Ops/litany-examples)

## Design Goals

* Using Litany it should be easy to scale from a simple one server configuration to a multi-region multi-account setup.
* Always have sane and reasonable defaults.
* Make it easy for people without infrastructure expertise to 'do the right thing'.
* The DSL should be completely ruby compatible, allowing for developers to utilize powerful native language constructs.
* Allow low level tuning of most settings for when the 'easy way' just isn't flexible enough.

## Concepts

### Project

A Litany project is defined as a folder, it's files, and it's sub folders and files, which contain one or more `.lit` files.  Currently the only requirement is the presence of a file named `project.lit` at the root of the project folder.

#### Scoping

Projects are intended to be to be tied back to a given 'product' or 'service', but those terms themselves are somewhat fuzzy.

To illustrate, currently the most robust usage of Litany is in the `twilight-lit` repository.  It is nominally meant to provide infrastructure for `twilight` but that encompasses many many services and supporting resources.

Ultimately, I'd encourage you to think of a project as a collection of services which should share a VPC or at least a collection of VPCs inside of the same AWS account.

Hosting multiple Litany projects inside of the same account is not a well explored activity.  If you have a solid use case on doing this please report any issues with doing so.

#### Where does a project live?

This is really a matter of preference for the users.

The only limitation right now is that a specific project can only live in a single folder tree.  This can be in a stand alone repository, a folder in a multi-litany-project repository, or even as a sub folder inside of a service repository.

#### Project Structure

Here are a list of things that can be inside of your project.

##### Litany Files

These are the primary files in your project.  They use `.lit` or `.litany` as the file extension and you will always have at least one named `project`. Inside of these files you have access to the full Litany DSL and will define your Resources in these files.

##### Settings Files

These are a specialized version of Litany files.  Like them they end in `.lit` or `.litany`, but you are not required to have one present.  If you use a single settings file you must name it `settings`.  If you wish to use multiple create a subfolder named `settings` and create files inside of named what you wish as long as they end with the standard file extensions.

You will not normally define resources inside of these files but instead use the Settings DSL to configure your project based on target environment and stage.  These files are also guaranteed to load and execute before any other Litany files.

##### Assets

There are currently magic folders you can use to provide userdata or lambda scripts.  These assets can be referenced by names in certain Resources to embed them inside of the resulting Cloud Formation templates.  These assets generally support being implemented as ERB templates with which you can inject knowledge from inside the main files.

This system, while functional, is very much a v1 and will be evolved over time.

### Resource DSL


### Stacks

Certain resources inside of Litany

* Stacks

    Stacks are a CloudFormation concept.  Ultimately many top level resources you define inside of your Litany configuration result in Stacks which are then uploaded to CloudFormation.

    Litany, in practice, implements Stack Layering.
* Resources
* MetaResources
* Resource Flavors
* Resource DSL
* Litany DSL
* Plugins
* Modules

## Implemented Primitives
These CFN primitives have been implemented to a degree at which they function.

Not every 'flavor' of a given resource may be present, and some attributes may not be implemented.

* AWS::AutoScaling::AutoScalingGroup
* AWS::AutoScaling::LaunchConfiguration
* AWS::CertificateManager::Certificate
* AWS::CloudFront::Distribution
* AWS::CloudWatch::Alarm
* AWS::ElasticLoadBalancingV2::Listener
* AWS::ElasticLoadBalancingV2::ListenerRule
* AWS::ElasticLoadBalancingV2::LoadBalancer
* AWS::ElasticLoadBalancingV2::TargetGroup
* AWS::EC2::EIP
* AWS::EC2::Instance
* AWS::EC2::InternetGateway
* AWS::EC2::Route
* AWS::EC2::RouteTable
* AWS::EC2::SecurityGroup
* AWS::EC2::SecurityGroupIngress
* AWS::EC2::Subnet
* AWS::EC2::SubnetRouteTableAssociation
* AWS::EC2::Volume
* AWS::EC2::VPC
* AWS::EC2::VPCGatewayAttachment
* AWS::EC2::VPCPeeringConnection
* AWS::ECR::Repository
* AWS::ECS::Cluster
* AWS::ECS::Service
* AWS::ECS::TaskDefinition
* AWS::ElastiCache::ReplicationGroup
* AWS::ElastiCache::SubnetGroup
* AWS::ElasticBeanstalk::Application
* AWS::ElasticBeanstalk::Environment
* AWS::Elasticsearch::Domain
* AWS::Events::Rule
* AWS::IAM::InstanceProfile
* AWS::IAM::Role
* AWS::Kinesis::Stream
* AWS::KMS::Alias
* AWS::KMS::Key
* AWS::Lambda::Function
* AWS::Lambda::Permission
* AWS::Logs::LogGroup
* AWS::RDS::DBCluster
* AWS::RDS::DBClusterParameterGroup
* AWS::RDS::DBInstance
* AWS::RDS::OptionGroup
* AWS::RDS::DBParameterGroup
* AWS::RDS::DBSubnetGroup
* AWS::Route53::HostedZone
* AWS::Route53::RecordSet
* AWS::Route53::HealthCheck
* AWS::S3::Bucket
* AWS::S3::BucketPolicy
* AWS::SNS::Subscription
* AWS::SNS::Topic
* AWS::SQS::Queue
* AWS::SQS::QueuePolicy

## Pending Primitives
These primitives are queued to be investigated or implemented soon as business need is evident.
* AWS::AutoScaling::LifecycleHook
* AWS::AutoScaling::ScalingPolicy
* AWS::AutoScaling::ScheduledAction
* AWS::DynamoDB::Table
* AWS::EC2::DHCPOptions
* AWS::EC2::EIPAssociation
* AWS::EC2::NetworkInterface
* AWS::EC2::NetworkInterfaceAttachment
* AWS::EC2::SecurityGroupEgress
* AWS::EFS::FileSystem
* AWS::EFS::MountTarget
* AWS::IAM::AccessKey
* AWS::IAM::Group
* AWS::IAM::ManagedPolicy
* AWS::IAM::Policy
* AWS::IAM::User
* AWS::IAM::UserToGroupAddition
* AWS::KinesisFirehose::DeliveryStream
* AWS::Lambda::EventSourceMapping
* AWS::Lambda::Alias
* AWS::Lambda::Version
* AWS::Logs::Destination
* AWS::Logs::LogStream
* AWS::Logs::MetricFilter
* AWS::Logs::SubscriptionFilter
* AWS::OpsWorks::App
* AWS::OpsWorks::ElasticLoadBalancerAttachment
* AWS::OpsWorks::Instance
* AWS::OpsWorks::Layer
* AWS::OpsWorks::Stack
* AWS::OpsWorks::UserProfile
* AWS::OpsWorks::Volume
* AWS::Redshift::Cluster
* AWS::Redshift::ClusterParameterGroup
* AWS::Redshift::ClusterSecurityGroup
* AWS::Redshift::ClusterSecurityGroupIngress
* AWS::Redshift::ClusterSubnetGroup
* AWS::RDS::EventSubscription
* AWS::Route53::RecordSetGroup
* AWS::SNS::TopicPolicy
* AWS::WAF::ByteMatchSet
* AWS::WAF::IPSet
* AWS::WAF::Rule
* AWS::WAF::SizeConstraintSet
* AWS::WAF::SqlInjectionMatchSet
* AWS::WAF::WebACL
* AWS::WAF::XssMatchSet

## Not Implemented Primitives
Some primitives are set to not be implemented now or in the future.  Common reason for this is that the functionality was better implemented in an alternative way.
* AWS::RDS::DBSecurityGroup
* AWS::RDS::DBSecurityGroupIngress

## Ice-boxed Primitives
These primitives are not going to be implemented immediately, but will be moved to pending based on business needs.

* AWS::ApiGateway::Account
* AWS::ApiGateway::ApiKey
* AWS::ApiGateway::Authorizer
* AWS::ApiGateway::BasePathMapping
* AWS::ApiGateway::ClientCertificate
* AWS::ApiGateway::Deployment
* AWS::ApiGateway::Method
* AWS::ApiGateway::Model
* AWS::ApiGateway::Resource
* AWS::ApiGateway::RestApi
* AWS::ApiGateway::Stage
* AWS::ApiGateway::UsagePlan
* AWS::ApiGateway::UsagePlanKey
* AWS::ApplicationAutoScaling::ScalableTarget
* AWS::ApplicationAutoScaling::ScalingPolicy
* AWS::CloudFormation::Authentication
* AWS::CloudFormation::CustomResource
* AWS::CloudFormation::Init
* AWS::CloudFormation::Interface
* AWS::CloudFormation::Stack
* AWS::CloudFormation::WaitCondition
* AWS::CloudFormation::WaitConditionHandle
* AWS::CloudTrail::Trail
* AWS::CodeBuild::Project
* AWS::CodeCommit::Repository
* AWS::CodeDeploy::Application
* AWS::CodeDeploy::DeploymentConfig
* AWS::CodeDeploy::DeploymentGroup
* AWS::CodePipeline::CustomActionType
* AWS::CodePipeline::Pipeline
* AWS::Cognito::IdentityPool
* AWS::Cognito::IdentityPoolRoleAttachment
* AWS::Cognito::UserPool
* AWS::Cognito::UserPoolClient
* AWS::Cognito::UserPoolGroup
* AWS::Cognito::UserPoolUser
* AWS::Cognito::UserPoolUserToGroupAttachment
* AWS::Config::ConfigRule
* AWS::Config::ConfigurationRecorder
* AWS::Config::DeliveryChannel
* AWS::DataPipeline::Pipeline
* AWS::DirectoryService::MicrosoftAD
* AWS::DirectoryService::SimpleAD
* AWS::EC2::CustomerGateway
* AWS::EC2::FlowLog
* AWS::EC2::Host
* AWS::EC2::NatGateway
* AWS::EC2::NetworkAcl
* AWS::EC2::NetworkAclEntry
* AWS::EC2::PlacementGroup
* AWS::EC2::SpotFleet
* AWS::EC2::SubnetCidrBlock
* AWS::EC2::SubnetNetworkAclAssociation
* AWS::EC2::VolumeAttachment
* AWS::EC2::VPCCidrBlock
* AWS::EC2::VPCDHCPOptionsAssociation
* AWS::EC2::VPCEndpoint
* AWS::EC2::VPNConnection
* AWS::EC2::VPNConnectionRoute
* AWS::EC2::VPNGateway
* AWS::EC2::VPNGatewayRoutePropagation
* AWS::ElastiCache::CacheCluster
* AWS::ElastiCache::ParameterGroup
* AWS::ElastiCache::SecurityGroup
* AWS::ElastiCache::SecurityGroupIngress
* AWS::ElasticBeanstalk::ApplicationVersion
* AWS::ElasticBeanstalk::ConfigurationTemplate
* AWS::ElasticLoadBalancing::LoadBalancer
* AWS::EMR::Cluster
* AWS::EMR::InstanceGroupConfig
* AWS::EMR::Step
* AWS::GameLift::Alias
* AWS::GameLift::Build
* AWS::GameLift::Fleet
* AWS::IoT::Certificate
* AWS::IoT::Policy
* AWS::IoT::PolicyPrincipalAttachment
* AWS::IoT::Thing
* AWS::IoT::ThingPrincipalAttachment
* AWS::IoT::TopicRule
* AWS::SDB::Domain
* AWS::SSM::Association
* AWS::SSM::Document
* AWS::SSM::Parameter
* AWS::StepFunctions::Activity
* AWS::StepFunctions::StateMachine
* AWS::WorkSpaces::Workspace
