# CloudFormation

## Iac

* [Infrastructure as Code (IaC)](https://aws.amazon.com/what-is/iac/) enables us to provision and support your computing infrastructure using code instead of manual processes and settings.
* Manual infrastructure management is time-consuming and prone to error, especially when you manage applications at scale.
* Infrastructure as code lets you define your infrastructure's desired state without including all the steps to get to that state.
* It automates infrastructure management so developers can focus on building and improving applications instead of managing environments.
* Organizations use infrastructure as code to control costs, reduce risks, and respond with speed to new business opportunities.
* The most common use of IaC is in software development to build, test, and deploy applications.
* It lets you,
  * Reduce configuration errors and simplify infastructure management
  * Easily duplicate environments
  * Track configuration changes
  * Iterate on best practices

## Icon

![Cloud Formation](https://icon.icepanel.io/AWS/svg/Management-Governance/CloudFormation.svg)

## About

* CloudFormation is Iac service offered by AWS.
* Its declarative, meaning developer does not need to say how the resource needs to be provisioned, the developer just needs to describe the resources needed and CloudFormation will take care of provisioning them in the order required.

### Concepts

#### Stack

* When you use CloudFormation, you manage related resources as a single unit called a `stack`.
* You create, update, and delete a collection of resources by creating, updating, and deleting stacks.
* If you need to make changes to the running resources in a stack, you update the stack.
* Before making changes to your resources, you can generate a change set, which is a summary of your proposed changes.
* Change sets allow you to see how your changes might impact your running resources, especially for critical resources, before implementing them.

#### Template

* A CloudFormation template _(CFT)_ is a `JSON` or `YAML` formatted text file. You can save these files with any extension, such as `.json`, `.yaml`, `.template`, or `.txt`. CloudFormation uses these templates as blueprints for building your AWS resources.
*   Eg:

    ```json
    {
        "AWSTemplateFormatVersion": "2010-09-09", 
        "Description": "A sample template",
        "Resources": {
            "MyEC2Instance": {
                "Type": "AWS::EC2::Instance",
                "Properties": {
                    "ImageId": "ami-0ff8a91507f77f867",
                    "InstanceType": "t2.micro",
                    "KeyName": "testkey",
                    "BlockDeviceMappings": [
                        {
                            "DeviceName": "/dev/sdm",
                            "Ebs": {
                                "VolumeType": "io1",
                                "Iops": 200,
                                "DeleteOnTermination": false,
                                "VolumeSize": 20
                            }
                        }
                    ]
                }
            }
        }
    }
    ```

    ```yaml
    AWSTemplateFormatVersion: 2010-09-09 #identifies capabilities of template
    Description: A sample template
    Resources:
        MyEC2Instance:
            Type: 'AWS::EC2::Instance'
            Properties:
            ImageId: ami-0ff8a91507f77f867
            InstanceType: t2.micro
            KeyName: testkey
            BlockDeviceMappings:
                - DeviceName: /dev/sdm
                Ebs:
                    VolumeType: io1
                    Iops: 200
                    DeleteOnTermination: false
                    VolumeSize: 20
    ```

**Template Components**

**AWS Template Format Version**

* Identifies capabilities of template.

**Description**

* Comments about code

**Resources**

* Represents difference AWS components needed to configure your application or infrastructure.
* Resources can be declared and can be referenced.
*   Resource identifiers are of the form,

    ```
        service-provider:service-name:data-type-name
    ```

    * All resource types details can be found [here](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-template-resource-type-ref.html).
* Almost all AWS services are available as part of CloudFormation resources and if any resources are not available, they can be created using CloudFormation custom resources.
* `Fn:Ref` _(short-hand `!Ref`)_ in templates can be used to reference parameters and components within a template.

**Parameters**

* Allows to specify inputs to your AWS CloudFormation template.
* They allow to make reusable templates.
* Following types are allowed,
  * String
  * Number
  * CommaDelimitedList
  * List
  * AWS-Specific parameter
  * List AWS specific Parameter
  * SSM Parameter
* Can place constraints on parameters.

**Pseudo Parameters**

* These are AWS predefined parameters which can be referenced in CloudFormation script.
* List of parameters can be found [here](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/pseudo-parameter-reference.html).

**Mappings**

* These are fixed variables within your CloudFormation.
* Very handy to differentiate between different environments, regions and AMI types.
* They are great when you want configurtion based approach based on values chosen at run time.
* More about mappings can be found [here](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-findinmap.html).

**Outputs**

* The outputs declares optional output values that can be imported by using `!ImportValue` into other stacks, provided they are exported first by using `Export` section.
* Suppose a stack exports a value then other stacks that use this exported value should not reference the exported value to successfully delete the stack.
* Exported output names must be unique in the AWS region.

**Conditional**

* Allows to give conditions within templates to feature conditional resource creation.
* Conditions can be found [here](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-conditions.html).

**Intrinsic Function**

* These are functions that provide inbuilt functions to manage the stack in CloudFormation
* Full reference to all the functions are available in the [documentation](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference.html).

## Working

* `S3` is used as the CloudFormation script repository and these scripts are referenced in `CloudFormation`.
* Updation is done by reuploading the change set to `S3`.
* Stacks are identified by name.
* Deletion of a stack also deletes the artifact that was created by the `CloudFormation`.
* Working of CloudFormation can be found [here](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/cloudformation-overview.html#cfn-whatis-howdoesitwork).

## Rollback

* Following are the stack failure options available as per the scenarios possible,
  * **Stack Creation Fails:** Everything gets roll backed _(gets deleted)_ or preserve the successfully provisioned ones.
  * **Stack Updation Fails:** Everything gets roll backed \_(gets deleted) to previous working state.
  * **Rollback Failure:** If failure happens while rollback, fix the resources manually and then issue `ContinueUpdateRollback` API from Console.

## Service Role

* A service role is an AWS Identity and Access Management (IAM) role that allows AWS CloudFormation to create, update, or delete stack resources.
* If you do not provide a service role, CloudFormation uses the credentials of the IAM principal to perform the stack operations.
* If you create a service role for CloudFormation and specify the service role during stack creation, then CloudFormation uses the credentials of the service role to perform the operations, instead of the credentials of the IAM principal.
* Using this will allow to provide access based on `Least Priviledged Principle`.
* User must have `iam::PassRole` permissions to give a role to a specific service.

## Capabilities

* `CAPABILITY_NAMED_IAM` and `CAPABILITY_IAM` is necessary when creation IAM resources and use the former is the resources are named. If not specified you will receive `InsufficientCapabilitiesException`.
* `CAPABILITY_AUTO_EXPAND` is necessary when you include Macros or Nested Stacks to perform dynamic transformations.

## Deletion Policy

### Delete

* To control what happens when the CloudFormation is deleted or when the resource is removed from CloudFormation.
* It also provides safety measures to preserve and backup resources.
* Default Policy is to delete the resource. However for S3 bucket, delete policy will not delete the bucket if it is not empty. To fix this, either empty the bucket manually or make a custom resource to delete the S3 bucket.

### Retain

* This allows to preserve the resources in case of CFT deletes.

### Snapshots

* This policy enables CFT to make a snapshot before deletion of resources.

## Stack Policies

* All update actions are allowed on all resources by default.
* Stack policy is a JSON document that defines the update actions that are allowed on specific resources during stack updates.

## Termination Protection

* By default this protection is deactivated.
* Once enabled, on stack deletion the resource will not be deleted until this protection is deactivated.

## Custom Resources

* Define resources not supported by CloudFormation.
* Define custom provisioning logic for resources that can be outside CloudFormation like on-premise.
* This also allows to run custom scripts during `create`/`update`/`delete` through Lambda functions.
* Template is defined using `AWS::CloudFormation::CustomResource` or `Custom::MyCustomResourceTypeName` type.

## StackSets

* Create, Update or delete stacks across multiple accounts and regions with a single operation/template.
* When you update a stack set, all associated stack instances are updated throughout all accounts and regions.
* Most common use case are to apply this to AWS Organization _(which is a group of accounts)_. This can only be created by user who has administrative access.

## References

* [AWS CloudFormation Blog](https://dev.to/tiamatt/hands-on-aws-cloudformation-part-1-it-all-starts-here-5153)
