Lono CloudFormation Framework Introduction Part 1: EC2 Instance
This is the first part of a series of posts that provides an introduction to the Lono CloudFormation Framework. I’ve already provided an introduction to raw CloudFormation in the Simple Introduction to AWS CloudFormation Series. This series will focus on Lono.
Note: Source Code for this tutorial is available at: tongueroo/lono-cloudformation-examples
Lono CloudFormation Framework
With the Lono CloudFormation Framework, we can build CloudFormation templates with a DSL. The DSL gives us the full power of a programming language: Ruby. At the same time, the Lono DSL stays close to the declarative nature of CloudFormation. So we get the best of both worlds.
Lono has additional powerful concepts to help with AWS CloudFormation:
Concept | Description |
---|---|
Configs | Customize the blueprints to fit your needs. Customize at run-time with params or compile-time with variables. |
Layering | Use layering to build multiple environments like development, production, and more. |
DRY | Designed to allow you to reuse CloudFormation templates. The configs and templates are separated in a structured and organized way. |
Helpers | Powerful way to extend Lono and keep your code readable and maintained. |
Install
You can install lono with the gem command:
gem install lono
More info: Lono Install
Basic Lono Example
Let’s start by creating a new lono project. We’ll use the lono new command to generate a lono project quickly.
$ lono new infra
=> Creating new project called infra.
create infra
create infra/.gitignore
create infra/Gemfile
create infra/Guardfile
create infra/README.md
create infra/configs/settings.yml
$
Next we’ll generate a blueprint with the lono blueprint new command.
$ cd infra
$ lono blueprint new demo
=> Creating new blueprint called demo.
create blueprints/demo
create blueprints/demo/demo.gemspec
create blueprints/demo/.gitignore
create blueprints/demo/.meta/config.yml
create blueprints/demo/CHANGELOG.md
create blueprints/demo/Gemfile
create blueprints/demo/README.md
create blueprints/demo/Rakefile
create blueprints/demo/seed/configs.rb
exist blueprints/demo
create blueprints/demo/app/templates/demo.rb
create blueprints/demo/app/user_data/bootstrap.sh
exist blueprints/demo/app/templates
exist
create configs/demo/params/development.txt
create configs/demo/params/production.txt
create configs/demo/variables/development.rb
create configs/demo/variables/production.rb
$
Check out the generated code.
blueprints/demo/app/templates/demo.rb:
# Simple Starter Demo Example
aws_template_format_version "2010-09-09"
description "Demo stack"
parameter("InstanceType", "t3.micro")
mapping("AmiMap",
"ap-northeast-1": { ami: "ami-0f9ae750e8274075b" },
"ap-northeast-2": { ami: "ami-047f7b46bd6dd5d84" },
# ...
"us-west-2": { ami: "ami-061392db613a6357b" }
)
resource("Instance", "AWS::EC2::Instance",
instance_type: ref("InstanceType"),
image_id: find_in_map("AmiMap", ref("AWS::Region"), :ami),
security_group_ids: [get_att("SecurityGroup.GroupId")],
user_data: base64(user_data("bootstrap.sh"))
)
resource("SecurityGroup", "AWS::EC2::SecurityGroup",
group_description: "demo security group",
)
output("Instance")
output("SecurityGroup", get_att("SecurityGroup.GroupId"))
The starter blueprint creates an EC2 instance and security group associated with it. The resource method is use to create the AWS::EC2::Instance and AWS::EC2::SecurityGroup.
There are a few built-in helper methods and intrinsic functions also being used here:
Method | Description |
---|---|
ref | The intrinsic function Ref returns the value of the specified parameter or resource. |
find_in_map | The intrinsic function Fn::FindInMap returns the value corresponding to keys in a two-level map that is declared in the Mappings section. |
get_att | The Fn::GetAtt intrinsic function returns the value of an attribute from a resource in the template. |
base64 | The intrinsic function Fn::Base64 returns the Base64 representation of the input string. |
user_data | When you launch an instance in Amazon EC2, you have the option of passing user data to the instance that can be used to perform common automated configuration tasks and even run scripts after the instance starts. |
Configs
When we ran lono blueprint new demo
, it also generated some starter configs for the blueprint. Here’s the structure:
configs/
└── demo
├── params
│ ├── development.txt
│ └── production.txt
└── variables
├── development.rb
└── production.rb
Let’s look an the development examples:
configs/demo/params/development.txt:
# Starter Example
# InstanceType=t3.micro
configs/demo/varaibles/development.rb:
# Starter Example
# @variable = "value"
You can see that they are just examples to help get you started. You can change them to fit with how your template works. More info: Lono Configs
Lono Summary
Another handy way to get a summary of the blueprint template is with lono summary
$ lono summary demo
Generating CloudFormation templates for blueprint demo:
output/demo/templates/demo.yml
=> CloudFormation Template Summary for template demo:
Required Parameters:
There are no required parameters parameters
Optional Parameters:
InstanceType (String) Default: t3.micro
Resources:
1 AWS::EC2::Instance
1 AWS::EC2::SecurityGroup
2 Total
$
Deploy Example
Now that we’ve reviewed what was generated. Let’s deploy it. We’ll use the lono cfn deploy
$ lono cfn deploy demo
Deploy demo stack...
Generating CloudFormation templates for blueprint demo:
output/demo/templates/demo.yml
Uploading app/files...
Uploading CloudFormation templates...
Not modified: output/demo/templates/demo.yml to s3://lono-bucket-usp0x9l7fhr4/development/output/demo/templates/demo.yml
Templates uploaded to s3.
Generating parameter files for blueprint demo:
output/demo/params/development.json
Using template: output/demo/templates/demo.yml
Using param: configs/demo/params/development.txt
Parameters passed to cfn.create_stack:
---
stack_name: demo
parameters: []
disable_rollback: false
template_url: https://lono-bucket-usp0x9l7fhr4.s3.us-west-2.amazonaws.com/development/output/demo/templates/demo.yml
template_body: 'Hidden due to size... View at: output/demo/templates/demo.yml'
Creating demo stack.
Waiting for stack to complete
11:10:31PM CREATE_IN_PROGRESS AWS::CloudFormation::Stack demo User Initiated
11:10:33PM CREATE_IN_PROGRESS AWS::EC2::SecurityGroup SecurityGroup
11:10:38PM CREATE_IN_PROGRESS AWS::EC2::SecurityGroup SecurityGroup Resource creation Initiated
11:10:38PM CREATE_COMPLETE AWS::EC2::SecurityGroup SecurityGroup
11:10:41PM CREATE_IN_PROGRESS AWS::EC2::Instance Instance
11:10:42PM CREATE_IN_PROGRESS AWS::EC2::Instance Instance Resource creation Initiated
11:10:49PM CREATE_COMPLETE AWS::EC2::Instance Instance
11:10:51PM CREATE_COMPLETE AWS::CloudFormation::Stack demo
Stack success status: CREATE_COMPLETE
Time took for stack deployment: 20s.
$
Here’s a screenshot of the CloudFormation Events.
Here’s a screenshot of the CloudFormation Resources.
For good measure, we can also go to the EC2 Console to confirm that the EC2 Instance was created:
Cleanup
Let’s destroy the resources so we do not get charged more money than we have to. This is super simple.
$ lono cfn delete demo
Are you sure you want to want to delete the demo stack? (y/N)
y
Deleted demo stack.
Waiting for stack to complete
11:17:44PM DELETE_IN_PROGRESS AWS::CloudFormation::Stack demo User Initiated
11:17:45PM DELETE_IN_PROGRESS AWS::EC2::Instance Instance
Stack demo deleted.
Time took for stack deletion: 35s.
$
Summary
There is a lot more you can do with the Lono CloudFormation Framework. This tutorial was designed to be basic intentionally since it is meant to be a simple introduction.
In the next post, we will talk about how to add an EIP and attach it to the EC2 instance.
Lono Introduction Series
Thanks for reading this far. If you found this article useful, I'd really appreciate it if you share this article so others can find it too! Thanks 😁 Also follow me on Twitter.
Got questions? Check out BoltOps.
You might also like
More tools:
-
Kubes
Kubes: Kubernetes Deployment Tool
Kubes is a Kubernetes Deployment Tool. It builds the docker image, creates the Kubernetes YAML, and runs kubectl apply. It automates the deployment process and saves you precious finger-typing energy.
-
Jets
Jets: The Ruby Serverless Framework
Ruby on Jets allows you to create and deploy serverless services with ease, and to seamlessly glue AWS services together with the most beautiful dynamic language: Ruby. It includes everything you need to build an API and deploy it to AWS Lambda. Jets leverages the power of Ruby to make serverless joyful for everyone.
-
Lono
Lono: The CloudFormation Framework
Building infrastructure-as-code is challenging. Lono makes it much easier and fun. It includes everything you need to manage and deploy infrastructure-as-code.