smt-cloudformation-parent

This project contains Java objects for building Cloudformation template components. These objects can then be serialised to a JSON or YAML template using the Jackson library.

License

License

Categories

Categories

AWS Container PaaS Providers ORM Data
GroupId

GroupId

com.github.shiver-me-timbers.aws.cloudformation
ArtifactId

ArtifactId

smt-cloudformation-parent
Last Version

Last Version

15.2.0.1
Release Date

Release Date

Type

Type

pom
Description

Description

smt-cloudformation-parent
This project contains Java objects for building Cloudformation template components. These objects can then be serialised to a JSON or YAML template using the Jackson library.
Source Code Management

Source Code Management

https://github.com/shiver-me-timbers/smt-cloudformation-parent

Download smt-cloudformation-parent

How to add to project

<!-- https://jarcasting.com/artifacts/com.github.shiver-me-timbers.aws.cloudformation/smt-cloudformation-parent/ -->
<dependency>
    <groupId>com.github.shiver-me-timbers.aws.cloudformation</groupId>
    <artifactId>smt-cloudformation-parent</artifactId>
    <version>15.2.0.1</version>
    <type>pom</type>
</dependency>
// https://jarcasting.com/artifacts/com.github.shiver-me-timbers.aws.cloudformation/smt-cloudformation-parent/
implementation 'com.github.shiver-me-timbers.aws.cloudformation:smt-cloudformation-parent:15.2.0.1'
// https://jarcasting.com/artifacts/com.github.shiver-me-timbers.aws.cloudformation/smt-cloudformation-parent/
implementation ("com.github.shiver-me-timbers.aws.cloudformation:smt-cloudformation-parent:15.2.0.1")
'com.github.shiver-me-timbers.aws.cloudformation:smt-cloudformation-parent:pom:15.2.0.1'
<dependency org="com.github.shiver-me-timbers.aws.cloudformation" name="smt-cloudformation-parent" rev="15.2.0.1">
  <artifact name="smt-cloudformation-parent" type="pom" />
</dependency>
@Grapes(
@Grab(group='com.github.shiver-me-timbers.aws.cloudformation', module='smt-cloudformation-parent', version='15.2.0.1')
)
libraryDependencies += "com.github.shiver-me-timbers.aws.cloudformation" % "smt-cloudformation-parent" % "15.2.0.1"
[com.github.shiver-me-timbers.aws.cloudformation/smt-cloudformation-parent "15.2.0.1"]

Dependencies

test (4)

Group / Artifact Type Version
org.springframework.boot : spring-boot-starter-test jar
com.github.shiver-me-timbers : smt-random jar 1.8
com.github.shiver-me-timbers : smt-matchers jar 1.2
nl.jqno.equalsverifier : equalsverifier jar 3.4.1

Project Modules

  • smt-cloudformation-generation
  • smt-cloudformation-base-json-schemas
  • smt-cloudformation-base
  • smt-cloudformation-objects-json-schemas
  • smt-cloudformation-objects

smt-cloudformation-parent

Build Status Coverage Status Maven Central

What

This library is a complete mapping of the AWS CloudFormation Resource Specification into Java objects. The objects have been generated directly from the specification so should be a direct one to one mapping.

Why

CloudFormation templates can be rather difficult to create because of the need to go back and forth from the template and the resource documentation. Also the feedback loop on small syntax errors is quite long because they will not be found until the template is actually run.

Having all the CloudFormation constructs mapped into type safe Java objects allows the resources to have a level of self documentation and much easier discovery through IDE autocompletion. It also provides realtime validation through the type safety of the Java objects.

Lastly, the objects can be used to create higher order constructs that can be shared and reused as Java libraries. This improves the maintenance of your templates as they can be simplified by encapsulating their complexity into simpler reusable components.

How

All the objects in this library can be serialised using the Jackson JSON library, including the Intrinsic Functions.

So all that is required is to create a new Template object and populate it with the details and resources you need.

Creating a Template object

A simple way to create new a template object is to extend the Template class. The following class can be serialised to JSON with the Jackson library and it will produce a valid CloudFormation template.

import shiver.me.timbers.aws.Output;
import shiver.me.timbers.aws.Parameter;
import shiver.me.timbers.aws.Template;
import shiver.me.timbers.aws.s3.Bucket;
import shiver.me.timbers.aws.s3.BucketResource;

import static shiver.me.timbers.aws.fn.Functions.fnGetAtt;
import static shiver.me.timbers.aws.s3.BucketAttributes.ARN;
import static shiver.me.timbers.aws.s3.BucketAttributes.DOMAIN_NAME;
import static shiver.me.timbers.aws.s3.BucketAttributes.WEBSITE_URL;

public class S3Template extends Template {

    public S3Template() {
        final Parameter name = new Parameter("Name");
        final BucketResource bucket = new BucketResource("S3Bucket");
        withParameters(name);
        withResources(bucket.withProperties(
            new Bucket().withBucketName(name.ref())
        ));
        withOutputs(
            new Output("BucketName").withValue(bucket.ref()),
            new Output("BucketDomainName").withValue(fnGetAtt(bucket, DOMAIN_NAME)),
            new Output("BucketWebsiteUrl").withValue(fnGetAtt(bucket, WEBSITE_URL)),
            new Output("BucketArn").withValue(fnGetAtt(bucket, ARN))
        );
    }
} 

Intrinsic Functions

All of the CloudFormation Intrinsic Functions have also been mapped, except for Transform. Transform has been excluded because the functionality it provides can now be solved through Java and this library instead. If at any time new functions are added and you find that they are not supported by this library please raise an issue.

Fn::Base64

shiver.me.timbers.aws.fn.Functions.fnBase64("some string")

Fn::Cidr

shiver.me.timbers.aws.fn.Functions.fnCidr("192.168.0.0/24", "6", "5")

Condition Functions

import shiver.me.timbers.aws.Condition;
import shiver.me.timbers.aws.Parameter;
import shiver.me.timbers.aws.Template;
import shiver.me.timbers.aws.s3.Bucket;
import shiver.me.timbers.aws.s3.BucketResource;

import static shiver.me.timbers.aws.fn.Functions.fnEquals;
import static shiver.me.timbers.aws.fn.Functions.fnIf;

public class S3Template extends Template {

    public S3Template() {
        final Parameter name = new Parameter("Name");
        final Condition notNamed = new Condition("NotNamed", fnEquals(name.ref(), ""));
        final BucketResource bucket = new BucketResource("S3Bucket");
        withParameters(name);
        withConditions(notNamed);
        withResources(bucket.withProperties(
            new Bucket().withBucketName(
                fnIf(notNamed, "DefaultName", name.ref())
            )
        ));
    }
}

Fn::FindInMap

import shiver.me.timbers.aws.Parameter;
import shiver.me.timbers.aws.Template;
import shiver.me.timbers.aws.s3.Bucket;
import shiver.me.timbers.aws.s3.BucketResource;

import java.util.HashMap;
import java.util.Map;

import static shiver.me.timbers.aws.fn.Functions.fnFindInMap;
import static shiver.me.timbers.aws.fn.Functions.ref;
import static java.util.Collections.singletonMap;

public class S3Template extends Template {

    public S3Template() {
        final Parameter name = new Parameter("Name");
        final BucketResource bucket = new BucketResource("S3Bucket");
        withParameters(name);
        withMappings(new HashMap<String, Map<String, Map<String, String>>>() {{
            put("BucketNames", new HashMap<String, Map<String, String>>() {{
                put("ap-southeast-2", singletonMap("Name", "AuBucket"));
                put("us-east-1", singletonMap("Name", "UsBucket"));
            }});
        }});
        withResources(bucket.withProperties(
            new Bucket().withBucketName(fnFindInMap("BucketNames", ref("AWS::Region"), "Name"))
        ));
    }
}

Fn::GetAtt

shiver.me.timbers.aws.fn.Functions.fnGetAtt(new BucketResource("S3Bucket"), BucketAttributes.ARN)

Fn::GetAZs

shiver.me.timbers.aws.fn.Functions.fnGetAZs(shiver.me.timbers.aws.fn.Functions.ref("AWS::Region"))

Fn::ImportValue

shiver.me.timbers.aws.fn.Functions.fnImportValue("ExportedValue")

Fn::Join

shiver.me.timbers.aws.fn.Functions.fnJoin(":", "a", "b", "c")

Fn::Select

shiver.me.timbers.aws.fn.Functions.fnSelect(1, "apples", "grapes", "oranges", "mangoes")

Fn::Split

shiver.me.timbers.aws.fn.Functions.fnSplit("|", "a|b|c")

Fn::Sub

shiver.me.timbers.aws.fn.Functions.fnSub("www.${Domain}", singletonMap("Domain", ref("RootDomainName")))

Ref

shiver.me.timbers.aws.fn.Functions.ref("AWS::Region")

Idiosyncrasies

The primitive property types have been mapped in a way that you may not expect, they are as follows:

String -> java.lang.CharSequence
Integer, Double -> java.lang.Number
Boolean -> java.lang.CharSequence

This mapping is to allow the use of Intrinsic Functions in the values of primitive properties. Unfortunately the java.lang.Boolean type is final so cannot be extended, this means Boolean values must be set with strings.

Versions

Version
15.2.0.1
15.2.0.0
6.0.0.0
1.1
1.0