- Published on
Science question about Cloudformation
- Author
- Name
- Roman Naumenko
Today is Nemo's first day at the DevOps school! The day starts with a stunning trip across production AWS accounts, lovely CI/CD pipelines, and other DevOps gems.
Finally, they are ready for the exciting trip to the drop-off - also known as the on-prem trench.
The teacher asks how to implement a conditional parameter for the Cloudformation template that manages SSL certs for the critical application.
Yes, Nemo, we know!
That is not a fun question. Usually, developers end up implementing something in YAML the half-Turing way. Check template below, it is not easy to grasp the logic and conditions in YAML.
cloudformation.yaml
AWSTemplateFormatVersion: "2010-09-09"
Parameters:
# This is an optional `CommaDelimitedList` parameter
CertificateSANs:
Type: CommaDelimitedList
Description: >-
A list of alternative domain names
for a certificate (e.g., "www.example.com,test.example.com")
Conditions:
# If list is empty, the join produce an empty string.
# `Fn::Not` function with `Fn::Equals` one mae a condition
# It is FALSE when CertificateSANs is empty
# TRUE when it contains at least one item.
HasCertificateSANs: !Not [!Equals [!Join ['', !Ref CertificateSANs], '']]
Resources:
Certificate:
Type: AWS::CertificateManager::Certificate
Properties:
DomainName: !Ref DomainName
# The `SubjectAlternativeNames` property expects
# a list of strings or pseudo parameter 'AWS::NoValue'.
# If parameter is not defined, the Fn::If will pass `AWS::NoValue`
# This way the SubjectAlternativeNames property set correctly.
#
# Note quoted AWS::NoValue. otherwise CloudFormation fails
# to parse the template with inline YAML array syntax
SubjectAlternativeNames:
!If [HasCertificateSANs, !Ref CertificateSANs, !Ref 'AWS::NoValue']
Ok, Nemo! Don't hurt yourself and welcome aboard of AWS CDK - where the whole class of problem like this simple does not exist.
Here is CDK app that creates same resource (source code is available in GitHub).
main.ts
import { App, Stack, StackProps } from 'aws-cdk-lib';
import { CertificateValidation, Certificate } from 'aws-cdk-lib/aws-certificatemanager';
import { HostedZone } from 'aws-cdk-lib/aws-route53';
import { Construct } from 'constructs';
export class CertValidation extends Stack {
constructor(scope: Construct, id: string, props: StackProps = {}) {
super(scope, id, props);
const myHostedZone = new HostedZone(this, 'HostedZone', {
zoneName: 'thesite.com',
});
new Certificate(this, 'Certificate', {
domainName: 'dev.thesite.com',
subjectAlternativeNames: [],
validation: CertificateValidation.fromDns(myHostedZone),
});
}
}
const app = new App();
new CertValidation(app, 'cetificate-validation');
app.synth();`subjectAlternativeNames: []` can be an empty array - no problem. The Certificate construct will handle it.
Conclusion: if you're a small Dev fish, the CDK will increase your productivity (along with curiosity). It makes writing Cloudformation a breeze with a familiar programming language.
The real adventure begins when the CDK development pattern is applied to a Cloud coral reef with a massive ecosystem of templates, applications, Dev- and other types of fishes. There might be even some security sharks coming to a party!