Site icon Check Point Blog

Introducing Cloud Formation Simulator Tool

AWS CloudFormation Templates (CFT) are designed to simplify deployment and management on AWS. CFTs have come a long way from being a declarative infrastructure blueprint. Power users of AWS CloudFormation now create CFTs which act like a software program that accepts parameters, processes them according to logic and generates output.

While working with CFTs, the Dome9 team faced a couple of needs that we had to address:

To meet these needs, we built a tool called CFT-Simulator that allows you to run an offline (=not executing the stack in AWS environment) simulation of the CFT according to various input parameters.

With the CFT-Simulator, you can debug complex CFTs and transform a generic template into a concrete plan with all parameters and conditions being evaluated right on your laptop.

Let’s see it in action:

The tool is open sourced and hosted on github : https://github.com/Dome9/cft-simulator
It is installed according to the provided instructions.

Assuming this is our original CFT:

{
    "AWSTemplateFormatVersion": "2010-09-09",
    "Mappings": {
      "RegionMap": {
        "us-east-1": {
          "AMI": "ami-use1"
        },
        "us-west-1": {
          "AMI": "ami-usw1"
        },
        "us-west-2": {
          "AMI": "ami-usw2"
        }
      }
    },
    "Parameters": {
      "EnvType": {
        "Default": "test",
        "Type": "String",
        "AllowedValues": [
          "prod",
          "dev",
          "test"
        ]
      },
      "NameIndex": {
        "Default": 0,
        "Type": "Number"
      }
    },
    "Conditions": {
      "CreateProdResources": {
        "Fn::Equals": [
          {
            "Ref": "EnvType"
          },
          "prod"
        ]
      },
      "CreateDevResources": {
        "Fn::Equals": [
          {
            "Ref": "EnvType"
          },
          "dev"
        ]
      },
      "OrTest": {
        "Fn::Or": [
          {
            "Condition": "CreateProdResources"
          },
          {
            "Condition": "CreateDevResources"
          }
        ]
      },
      "NonProd": {
        "Fn::Not": [
          {
            "Condition": "CreateProdResources"
          }
        ]
      }
    },
    "Resources": {
      "EC2Instance": {
        "Type": "AWS::EC2::Instance",
        "Properties": {
          "FindInMapTest": {
            "Fn::FindInMap": [
              "RegionMap",
              {
                "Ref": "AWS::Region"
              },
              "AMI"
            ]
          },
          "NestedIfTest": {
            "Fn::If": [
              "CreateProdResources",
              "c1.forprod",
              {
                "Fn::If": [
                  "CreateDevResources",
                  "m1.forDevstuff",
                  "m1.forOtherEnvs"
                ]
              }
            ]
          },
          "SelectTest": {
            "Fn::Select": [
              {
                "Ref": "NameIndex"
              },
              [
                "apples",
                "grapes",
                "oranges",
                "mangoes"
              ]
            ]
          },
          "JoinTest": {
            "Fn::Join": [
              ":",
              [
                "a",
                "b",
                "c"
              ]
            ]
          },
          "PseudoParam": {
            "Ref": "AWS::Region"
          }
        }
      },
      "ProdInstance": {
        "Type": "AWS::EC2::Instance",
        "Properties": {
          "Name": "ProdOnly"
        },
        "Condition": "CreateProdResources"
      },
      "NonProdInstance": {
        "Type": "AWS::EC2::Instance",
        "Properties": {
          "Name": "aNonProdInstance"
        },
        "Condition": "NonProd"
      }
    }
  }

 

We wish to simulate how it will look in ‘prod’ environment (and with parameter ‘NameIndex’=1)

So we run:

$ node cft-simulator.js -p ‘{“EnvType”:”prod”,”NameIndex”:1}’ test/test1.json

and it outputs:

{
   "AWSTemplateFormatVersion": "2010-09-09",
   "Conditions": {
     "CreateProdResources": true,
     "CreateDevResources": false,
     "OrTest": true,
     "NonProd": false
   },
   "Resources": {
     "EC2Instance": {
       "Type": "AWS::EC2::Instance",
       "Properties": {
         "FindInMapTest": "ami-use1",
         "NestedIfTest": "c1.forprod",
         "SelectTest": "grapes",
         "JoinTest": "a:b:c",
         "PseudoParam": "us-east-1"
       }
     },
     "ProdInstance": {
       "Type": "AWS::EC2::Instance",
       "Properties": {
         "Name": "ProdOnly"
       },
       "Condition": true
     }
   }
 }

 

Look ma! All of my conditions are now properly evaluated, including parameters and AWS intrinsic functions – so only ‘prod’ configurations are now in place!  I have validated that my logic works.

Now, this output is not abstract anymore, hence is more suitable to be used for static compliance tests (we’ll discuss that in a future blog) or to be uploaded into Dome9 Clarity to generate something like:

Though we created it for our own needs, we’ll be happy to know if this tool helps you too. If you wish to contribute – that’s even better!

You can check out some of our other open-source tools and software on our github site: https://github.com/Dome9.

Exit mobile version