AWS Cloudformation - Template learning

In Cloudformation, the entire architecture is defined in the template, and then the corresponding Stack is generated through the template

AWS officially provides a reference manual, https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/cfn-whatis-howdoesitwork.html

It's very detailed and useful. It's boring at first, but it's interesting to savor it carefully. Here are the study notes of Douzi.

In the template, there are nine section s that can be defined, but only the resource module must exist, and the other eight modules are optional. The nine modules are Format Version, MetaData, parameters, mappings, conditions, transform, Resources and Outputs.

The basic format is as follows: JSON version

{
  "AWSTemplateFormatVersion" : "version date",

  "Description" : "JSON string",

  "Metadata" : {
    template metadata
  },

  "Parameters" : {
    set of parameters
  },

  "Mappings" : {
    set of mappings
  },

  "Conditions" : {
    set of conditions
  },

  "Transform" : {
    set of transforms
  },

  "Resources" : {
    set of resources
  },

  "Outputs" : {
    set of outputs
  }
}

Let's see what each module can do.

Format Version (optional)

He defines what template s can do. The latest version is a 2010-09-09

For example:

"AWSTemplateFormatVersion" : "2010-09-09"

Description (optional)
This is also easy to understand, that is to add a description of the template. For YAML, you can add comments in template at any time, but for JSON, this is the only place where you can add comments.

For example:

"Description" : "Here are some details about the template."

Metadata (optional)

You can add any object to the template for additional explanation.

"Metadata" : {
  "Instances" : {"Description" : "Information about the instances"},
  "Databases" : {"Description" : "Information about the databases"}
}

Parameters (optional)
Compared with the first three sections, this section is more complex. It is used to provide users with customized parameters.

Refer to the link for specific parameters that can be defined
https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/parameters-section-structure.html

A basic requirement is

  1. Up to 60 parameters in a template
  2. Name required for each parameter
  3. Type needs to be defined for each parameter
  4. Each parameter needs to pass in a value when executing the template. We can define the range of this value, default value, etc
  5. We can call our parameters through the internal function Ref, which is usually used in the two section s of Resource or Output.

For example:

"Parameters" : {
  "DBPort" : {
    "Default" : "3306",
    "Description" : "TCP/IP port for the database",
    "Type" : "Number",
    "MinValue" : "1150",
    "MaxValue" : "65535"
  },
  "DBPwd" : {
    "NoEcho" : "true",
    "Description" : "The database admin account password",
    "Type" : "String",
    "MinLength" : "1",
    "MaxLength" : "41",
    "AllowedPattern" : "^[a-zA-Z0-9]*$"
  }
}

Mapping (optional)

This is to get different value s by matching different key s. A common use is that the scene automatically selects the corresponding AMI image file through different region s.

For example:

The following is a complete cf file, in which we only use three section s, namely Format Version, mappings and Resources. Mappings defines nested second level JSON objects

The Mapping structure is so large, how to get the corresponding information? We can get it through a built-in function Fn::FindInMap. Fn::FindInMap needs to specify the name of Mapping RegionalMap, the name of the first layer's Key region, and the name of the second layer's key schema to obtain the corresponding AMI id. This operation is implemented in the Resource section. A global variable, Presto parameter AWS:: Region, is also called to automatically obtain the name of the Region where the user is located

{
  "AWSTemplateFormatVersion" : "2010-09-09",

  "Mappings" : {
    "RegionMap" : {
      "us-east-1"        : {"HVM64" : "ami-0ff8a91507f77f867", "HVMG2" : "ami-0a584ac55a7631c0c"},
      "us-west-1"        : {"HVM64" : "ami-0bdb828fd58c52235", "HVMG2" : "ami-066ee5fd4a9ef77f1"},
      "eu-west-1"        : {"HVM64" : "ami-047bb4163c506cd98", "HVMG2" : "ami-0a7c483d527806435"},
      "ap-northeast-1"   : {"HVM64" : "ami-06cd52961ce9f0d85", "HVMG2" : "ami-053cdd503598e4a9d"},
      "ap-southeast-1"   : {"HVM64" : "ami-08569b978cc4dfa10", "HVMG2" : "ami-0be9df32ae9f92309"}
    }
  },

  "Resources" : {
    "myEC2Instance" : {
      "Type" : "AWS::EC2::Instance",
      "Properties" : {
        "ImageId" : { "Fn::FindInMap" : [ "RegionMap", { "Ref" : "AWS::Region" }, "HVM64"]},
        "InstanceType" : "m1.small"
      }
    }
  }
}

Let's actually run it to see the results. After creating the Stack, let's see the automatically generated EC2 instance. My area is North Virginia, which is us-east-1. He will

Look at the AMI ID of EC2, which is consistent with what we defined in Mapping

Condition (optional)
Next, take a look at the Condition module. The function of this module is similar to the if..else statement. If one Condition is true, perform the operation. Otherwise, perform another operation.

His typical usage is as follows:

Parameter setaction: define the input parameters you want to compare

Condition section: use internal functions to judge. Internal functions include five operations: FN:: and, FN:: equals, FN:: if, FN:: not, FN:: not. Basic syntax:

"Conditions" : {

  "Logical ID" : {Intrinsic function}
}

Resource and Outputs section: these two modules are associated with condition s. Only when the association is true will the return be created.

Let's see an example to illustrate. These two examples are: if the user creates a test environment, an instance will be created. If it is a prod environment, then a volume will be added based on the instance

First, the Mapping module. The above example has been tested.
Next is the Parameters module, which provides two supported values for users to choose from
Next is the Condition module. According to our syntax, we give a name of CreateProdResource, followed by a nested built-in function. First, get the value of the EnvType parameter, and then compare it with the keyword prod. if it is the same, return the true, or return the false
Next, in resources Module, three resources are created. The first one is to create EC2 through Mappnig, which has been tested in the previous example. The second one is to create a mount point, in which one uses the keyword condition to obtain the corresponding conditions. The third one is similar to that of the previous one. In addition, the value of AZ is obtained through the built-in function Fn::GetAtt
Finally, the Outputs module specifies that the condition is true before returning the result

{
  "AWSTemplateFormatVersion" : "2010-09-09",

  "Mappings" : {
    "RegionMap" : {
      "us-east-1"      : { "AMI" : "ami-0ff8a91507f77f867", "TestAz" : "us-east-1a" },
      "us-west-1"      : { "AMI" : "ami-0bdb828fd58c52235", "TestAz" : "us-west-1a" },
      "us-west-2"      : { "AMI" : "ami-a0cfeed8", "TestAz" : "us-west-2a" },
      "eu-west-1"      : { "AMI" : "ami-047bb4163c506cd98", "TestAz" : "eu-west-1a" },
      "sa-east-1"      : { "AMI" : "ami-07b14488da8ea02a0", "TestAz" : "sa-east-1a" },
      "ap-southeast-1" : { "AMI" : "ami-08569b978cc4dfa10", "TestAz" : "ap-southeast-1a" },
      "ap-southeast-2" : { "AMI" : "ami-09b42976632b27e9b", "TestAz" : "ap-southeast-2a" },
      "ap-northeast-1" : { "AMI" : "ami-06cd52961ce9f0d85", "TestAz" : "ap-northeast-1a" }
    }
  },

  "Parameters" : {
    "EnvType" : {
      "Description" : "Environment type.",
      "Default" : "test",
      "Type" : "String",
      "AllowedValues" : ["prod", "test"],
      "ConstraintDescription" : "must specify prod or test."
    }
  },

  "Conditions" : {
    "CreateProdResources" : {"Fn::Equals" : [{"Ref" : "EnvType"}, "prod"]}
  },

  "Resources" : {
    "EC2Instance" : {
      "Type" : "AWS::EC2::Instance",
      "Properties" : {
        "ImageId" : { "Fn::FindInMap" : [ "RegionMap", { "Ref" : "AWS::Region" }, "AMI" ]}
      }
    },

    "MountPoint" : {
      "Type" : "AWS::EC2::VolumeAttachment",
      "Condition" : "CreateProdResources",
      "Properties" : {
        "InstanceId" : { "Ref" : "EC2Instance" },
        "VolumeId"  : { "Ref" : "NewVolume" },
        "Device" : "/dev/sdh"
      }
    },

    "NewVolume" : {
      "Type" : "AWS::EC2::Volume",
      "Condition" : "CreateProdResources",
      "Properties" : {
        "Size" : "100",
        "AvailabilityZone" : { "Fn::GetAtt" : [ "EC2Instance", "AvailabilityZone" ]}
      }
    }
  },

  "Outputs" : {
    "VolumeId" : {
      "Value" : { "Ref" : "NewVolume" }, 
      "Condition" : "CreateProdResources"
    }
  }  
}

Let's actually run

Here you can allow the user to choose prod or test. I chose prod

Take a look at the order in which his stack creates resource s. First, EC2 and New Volume are created, and then mount point is created

Take a look at the created volume

And corresponding Outputs

Tranform (optional)
This is mainly to call Lambda, which will be explained with specific examples later

Resources (required)

Here we create corresponding resources. Each AWS service has its own attribute value that needs to be defined. Please refer to this link for specific use
https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-template-resource-type-ref.html

Outputs (optional)
The output results here can be called in other stack s or displayed in console.

The syntax is as follows

"Outputs" : {
  "Logical ID" : {
    "Description" : "Information about the value",
    "Value" : "Value to return",
    "Export" : {
      "Name" : "Value to export"
    }
  }
}

So far, the nine basic section s are simply over. Next, let's look at the internal function in the Template

Tags: AWS JSON Database Lambda

Posted on Tue, 07 Apr 2020 12:12:07 -0400 by tdors