While creating a nested stack in CloudFormation, you may see a failure with this cryptic message:
Value of property Parameters must be an object
The full event will look something like this:
{"StackId":"arn:aws:cloudformation:us-west-2:760937633930:stack/my_nested_stack1/32499563-d49c-21e3-a914-302bfc8340a6","EventId":"MyNestedStack-CREATE_FAILED-1399325327000","ResourceStatus":"CREATE_FAILED","ResourceType":"AWS::CloudFormation::Stack","Timestamp":"2014-05-05T21:28:47Z","ResourceStatusReason":"Value of property Parameters must be an object","StackName":"my_nested_stack1","PhysicalResourceId":null,"LogicalResourceId":"MyNestedStack"}
Not very helpful. And a Google search turned up nothing.
Chances are, you're trying to pass a list as a parameter for a child stack. Parameter objects can only accept Strings and Numbers, not lists.
You may be passing a list inadvertently with a CommaDelimitedList parameter in the parent:
{"AWSTemplateFormatVersion":"2010-09-09","Description":"Launches a nested stack","Parameters":{"TemplateUrl":{"Description":"URL for S3-hosted CloudFormation template","Type":"String"},"FooList":{"Description":"List of Foos (subnets, availability zones, whatever)","Type":"CommaDelimitedList"}}"Resources":{"MyNestedStack":{"Type":"AWS::CloudFormation::Stack","Properties":{"TemplateURL":{"Ref":"TemplateUrl"},"Parameters":{"FooList":{"Ref":"FooList"}}}}}}
The problem here is that CloudFormation has already converted FooList from a string to a list.
In this case, you can simply defer parsing by treating FooList as a String in the parent:
{"AWSTemplateFormatVersion":"2010-09-09","Description":"Launches a nested stack","Parameters":{"TemplateUrl":{"Description":"URL for S3-hosted CloudFormation template","Type":"String"},"FooList":{"Description":"List of Foos (subnets, availability zones, whatever)","Type":"String"}}"Resources":{"MyNestedStack":{"Type":"AWS::CloudFormation::Stack","Properties":{"TemplateURL":{"Ref":"TemplateUrl"},"Parameters":{"FooList":{"Ref":"FooList"}}}}}}
A more general solution is to assemble the list into a string with Fn::Join and pass that through instead:
{"AWSTemplateFormatVersion":"2010-09-09","Description":"Launches a nested stack","Parameters":{"TemplateUrl":{"Description":"URL for S3-hosted CloudFormation template","Type":"String"},"FooList":{"Description":"List of Foos (subnets, availability zones, whatever)","Type":"CommaDelimitedList"}}"Resources":{"MyNestedStack":{"Type":"AWS::CloudFormation::Stack","Properties":{"TemplateURL":{"Ref":"TemplateUrl"},"Parameters":{"FooList":{"Fn::Join":[",",{"Ref":"FooList"}]}}}}}}
Docker allows you to create lightweight and portable containers that encapsulate any application. Your app and its runtime environment are packaged together. Starting your app requires only Docker and your container.
Docker installation is simple, but takes a non-trivial amount of time to complete. Baking Docker into your machine image has the desired effect of minimizing provisioning time, but image creation is typically a hassle.
Enter Packer. Packer simplifies the creation of machine images for EC2, Digital Ocean, Vagrant, and many other virtual environments. By defining a basic Packer template, creating Docker-capable images can be done with a single command.
Here is our Packer template:
We take a base Ubuntu 12.04 LTS image and install Docker on it (as per the official guide) using the script defined in provisioners. Other provisioners are supported: you could swap the shell script out for (or append) Chef, Ansible, or another supported provisioner.
This template will create an EC2 AMI. To create other images, simply replace/append the builder with one for another provider.
Note we specify the Docker version in a variable. Variables can be used throughout the template with {{user `var_name`}}.
Before we build our image on EC2, we'll need to export our AWS credentials as environment variables:
To kick off the build, we invoke packer build:
For EC2, you can copy the AMI to other regions using the AWS Console or awscli:
Typical build times are ~5-15min, but this could be improved by using a newer release of Ubuntu. (Docker requires a newer kernel than is shipped with Ubuntu 12.04). Cross-region copy times are quick, typically under a minute.
With your new AMI, you should now be able to provision Docker hosts in just a minute or two.
It's not in the current Elastic Beanstalk documentation, but you can't create a new application version from an S3 file hosted in a different region. Attempts to do so will return this error:
If you want to create an application version in multiple regions, you'll need a location-constrained bucket for each region. It's a good pattern to include the region in the bucket name:
Now, just use the regional bucket for each create-application-version call:
I needed a way to handle delayed processing of messages in a distributed system. Since I already had Redis running (but no message queue other than Kafka), I used a sorted set as a simple delay queue.
The basic approach is to insert each message into the sorted set with a score equal to the [unix] time the message should become available for processing ("ready").
Get all "ready" messages with a range query from (time) zero to now, then delete the messages. To avoid multiple processing and lost messages, run this in a transaction: