AWS CloudFormation Basics
Published: 2021-11-16 10:45:00

AWS CloudFormation is a service that provisions and manages resources on AWS. CloudFormation can be used to create, update and manage infrastructures on AWS. 
To provision infrastructure or services on AWS, you will require a template to define the AWS resources you want to provision.

A TEMPLATE is a formatted YAML or JSON file. The YAML file is used most of the time for configurations.
These templates can be created in any text editor of your choice, I prefer to use vs-code. 
The template describes all of the AWS resources. When you use cloudFormation
to create a template automatically you are creating a JSON script.
To create a template you can also use the cloudFormation designer, you will put all your resources needed and you will also specify all of its dependencies needed and finally save this design as a template.

                creating a template that provisions an s3 bucket using a designer
![designer pic.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1637055038636/kTmwtlMJC.png)

When we deploy a template, what we are creating is a STACK in aws. The Stack provisions the 
resources defined within the template into the aws account.
Note that a template can be reused multiple times. Imagine a scenario where we want to deploy our apps in multiple regions for backup purposes. You won't be creating each resource in every region.
what you can do is to create a template in cloudFormation and deploy the template to multiple regions.

Note that the creation of a stack requires a template. Also, the template will be created into a stack and the 
the stack will have the AWS resources.
Also, templates can be stored in an AWS S3 bucket or uploaded from your local machine.

         Some of the Benefits of using CloudFormation
1. CloudFormation is an easy way to create and manage a collection of AWS resources.
2. CloudFormation templates can be reusable.
3. It allows you to version control your aws infrastructure. 
4. You only pay for resources that you create. i.e cloudFormation is a service without charge.

CloudFormation supports over 500 resources types including aws resources and third-party resources.

         AWS Template and it's components
1. Version: the AWS format version
2. Description: the description of the template
3. Parameters: values you want to the template
4. Mappings: These are key-value collections that can be used to lookup value within our template.
5. MetaData: it's an arbitrary YAML code that is passed into the resource when there are created.
6. Resources: includes all the aws resources you want to include in your infrastructure. (Required) 
7. Outputs: used to emit values from your template once a stack has been created or updated which can be called cross-referencing template. Outputs should be the last element defined in your template.

Example of a simple template that creates a LAMP stack using an EC2 instance with vs-code below:

AWSTemplateFormatVersion: 2010-09-09
Description: >-
  Create a Wordpress installation on the LAMP stack using an EC2 instance
Parameters:
  KeyName:
    Description: Name of an existing EC2 KeyPair to enable SSH access to the instances
    Type: 'AWS::EC2::KeyPair::KeyName'
    ConstraintDescription: must be the name of an existing EC2 KeyPair.
  InstanceType:
    Description: WebServer EC2 instance type
    Type: String
    Default: t2.small
    AllowedValues:
      - t1.micro
      - t2.nano
      - t2.micro
      - t2.small
      - t2.medium
      - t2.large
    ConstraintDescription: must be a valid EC2 instance type.
  SSHLocation:
    Description: The IP address range that can be used to SSH to the EC2 instances
    Type: String
    MinLength: '9'
    MaxLength: '18'
    Default: 0.0.0.0/0
    AllowedPattern: '(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})/(\d{1,2})'
    ConstraintDescription: must be a valid IP CIDR range of the form x.x.x.x/x.
  DBName:
    Default: wordpressdb
    Description: The WordPress database name
    Type: String
    MinLength: '1'
    MaxLength: '64'
    AllowedPattern: '[a-zA-Z][a-zA-Z0-9]*'
    ConstraintDescription: must begin with a letter and contain only alphanumeric characters.
  DBUser:
    NoEcho: 'true'
    Description: The WordPress database admin account username
    Type: String
    MinLength: '1'
    MaxLength: '16'
    AllowedPattern: '[a-zA-Z][a-zA-Z0-9]*'
    ConstraintDescription: must begin with a letter and contain only alphanumeric characters.
  DBPassword:
    NoEcho: 'true'
    Description: The WordPress database admin account password
    Type: String
    MinLength: '8'
    MaxLength: '41'
    AllowedPattern: '[a-zA-Z0-9]*'
    ConstraintDescription: must contain only alphanumeric characters.
  DBRootPassword:
    NoEcho: 'true'
    Description: MySQL root password
    Type: String
    MinLength: '8'
    MaxLength: '41'
    AllowedPattern: '[a-zA-Z0-9]*'
    ConstraintDescription: must contain only alphanumeric characters.
Resources:
  WebServerSecurityGroup:
    Type: 'AWS::EC2::SecurityGroup'
    Properties:
      GroupDescription: >-
        Enable HTTP access via port 80  + SSH access
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: '80'
          ToPort: '80'
          CidrIp: 0.0.0.0/0
        - IpProtocol: tcp
          FromPort: '22'
          ToPort: '22'
          CidrIp: !Ref SSHLocation
  WebServer:
    Type: 'AWS::EC2::Instance'
    Properties:
        ImageId: 'ami-01419b804382064e4'
        InstanceType: !Ref InstanceType
        SecurityGroups: !Ref WebServerSecurityGroup
        KeyName: !Ref KeyName
    Metadata:
      Instance:
        Description: "This server hosts the WiredBrain Coffee Blog"
  IPAddress:
    Type: 'AWS::EC2::EIP'
  IPAssoc:
    Type: 'AWS::EC2::EIPAssociation'
    Properties:
      InstanceId: !Ref WebServer
      EIP: !Ref IPAddress
Outputs:
  WebsiteURL:
    Value: !Join 
      - ''
      - - 'http://'
        - !GetAtt 
          - WebServer
          - PublicDnsName
        - /wordpress
    Description: WordPress Website 

Note: If you need info about how to write a template for different aws resources, check the documentation area on aws cloudFormation documentation  via https://docs.aws.amazon.com/cloudformation/ 
 
MetaData is used to run arbitrary code against a resource when there are deployed. For example, each linux AMI image comes pre-installed with a range of prebuilt scripts that can be used to set up and configure EC2 instances. 
examples of such scripts are: 
1. cfn-init: used to retrieve and interpret metadata, install packages, create files and start services.
2. cfn-signal: used to synchronize your actions.
3. cfn-hup: deals with change detection within metadata. 

How CloudFormation works: You have your YAML formatted file that has defined resources you would like to create on aws and configurations you might wish to execute. The template will be executed by the cloudFormation framework which
handles stack creation, stack updates, error detection, and stack deletion. As the engine operates on the template, 
it will create the AWS services for you.

      Diff steps in creating a stack in aws portal
step 1: Specify the template
step 2: specify stack details
step 3: configure stack options
step 4: Review and create

          How CloudFormation handles dependencies
A better way of working with dependencies is that you don't need to create dependencies in a particular order, cloud formation
can resolve dependencies automatically by using PARAMETERS. Parameters are a way of injecting values into a cloudFormation template that is used to create and update a stack i.e at runtime the required dependencies will be injected into the appropriate places in the template.

You can extend a cloudFormation template by using parameters and mappings which will enable us to create reusable templates that can be deployed into multiple scenarios. One of the major reasons for using parameters is that it allows us to reuse a 
template to perform multiple deployments of resources. For example, you can have three diff stacks with diff parameters like database credentials, keyname, and InstanceType for dev, stage, and prod env but all are built using the same template.

Note that when creating your stack on AWS, you will be required to input 7 parameters which are dbname, db-user, db-password, 
db-root password, instance-type, key name, ssh location.

In summary, cloudFormation is an infrastructure as code service that is used to manage our aws services. Other configuration management
tools that can be used to provision aws resources are Ansible, Jenkins, and22 terraform.