Blog

Infrastructure as Code on AWS: An Introduction to CloudFormation

Picture of Ralitsa Dimitrova
Ralitsa Dimitrova
DevOps & Cloud Engineer
11.09.2025
Reading time: 10 mins.
Last Updated: 12.09.2025

Table of Contents

AWS CloudFormation is a service that enables us to provision AWS and third-party resources by treating infrastructure as code. It allows us to have consistent and version-controlled deployments. While there are other popular tools for IaC like Terraform and Pulumi, CloudFormation is designed specifically for AWS resources and services. It uses YAML or JSON-based templates, which most users are already familiar with. Since it is AWS’s service for infrastructure as code, there are more official quickstarts provided by AWS, and AWS Support will be more capable of assisting when help is needed.

One of the benefits of using CloudFormation is that there is no state file that we have to manage. The deployments are represented within the CloudFormation service as a “stack”. Stack Events show the deployment results of the resources that were created/updated/deleted based on the provided template.

In this post, we’ll cover the basics of CloudFormation, including templates, stacks, change sets, and nested stacks, and explore how these features can simplify infrastructure management while giving us greater control and visibility over our deployments.

When it comes to template files, we have a choice between using JSON and YAML formats. YAML is clearer and easier to use, which is why it is often preferred. The basic structure of a YAML template file looks like this:

---

AWSTemplateFormatVersion: version date

Description:
  String

Metadata:
  template metadata

Parameters:
  set of parameters

Rules:
  set of rules

Mappings:
  set of mappings

Conditions:
  set of conditions

Transform:
  set of transforms

Resources:
  set of resources

Outputs:
  set of outputs

Let’s walk through some of the most commonly used sections.

In the Resources section, we can declare the AWS resources that we want to have provisioned. It has the following structure:

Resources:

  LogicalResourceName1:
    Type: AWS::ServiceName::ResourceType
    Properties:
      PropertyName1: PropertyValue1

      ...

  LogicalResourceName2:
    Type: AWS::ServiceName::ResourceType
    Properties:
      PropertyName1: PropertyValue1

      ...

When creating resources, the following AWS Documentation comes in handy, as it gives information about all resource types and their properties: AWS CloudFormation Template Reference Guide

In the Parameters section, we can specify custom values for our parameters at runtime when we deploy the stack. If we are deploying it via the CloudFormation console, we will have a dropdown or an empty field in which we will be able to choose or write the value that we want. The only required attribute is Type.

Parameters:
  ParameterLogicalID:
    Description: Information about the parameter
    Type: DataType
    Default: value
    AllowedValues:
      - value1
      - value2

  

When you have multiple stacks in the same AWS account and Region, you might want to share information between them. This is useful when one stack needs to use resources created by another stack.

To share information between stacks, we have to export output values from one stack and import them into another stack. The procedure is the following:

  1. In the first stack’s template, we define certain values for export by using the Export field in the Outputs section.
Outputs:
  OutputLogicalID:
    Description: Information about the value
    Value: Value to return
    Export:
      Name: Name of resource to export
  1. Then we have to create/update that stack, so that the output value gets exported and available to other stacks. (In the CloudFormation console, we can see the output values for a given stack in the Outputs tab.)
  2. In the other stack’s template, we can then use the Fn::ImportValue function to import the exported values from the first stack.
  3. When we create/update the second stack, the exported value is automatically retrieved.

For a more thorough explanation of each of the sections, you can refer to the AWS documentation:

AWS CloudFormation template sections

The CloudFormation stacks are logical groupings of AWS resources that are going to belong to a project. When you want to add, update, or delete resources in this resource group, you can do so by modifying the stack.

Creating a stack – this involves deploying a CloudFormation template that follows the structure and the syntax that we showed above. CloudFormation then provisions and configures the resources described in the template.

Updating a stack – this involves making changes to the template or the parameters. CloudFormation compares what you submit with the current state of the stack and updates only the changed resources. There are two methods for updating stacks – with Change sets (if you want a preview of the changes before deploying them) or via a Direct update. Direct update means that CloudFormation will immediately deploy the changes.

We cover Change sets in more detail later in this post.

Deleting a stack – this deletes all the resources associated with the stack.

When working with stacks, you will have to follow the status code of your stack to know its state. It will tell you whether the change was successful, whether it failed and rolled back, whether the rollback was successful, etc.

To see more information about what was created, updated, or deleted, and if there are errors, you should choose your stack and go to the Events tab. There you will see the likely root cause of the failure, if the update wasn’t successful.

Here are a few common status codes and their meaning:

  • CREATE_IN_PROGRESS – Ongoing creation of one or more stacks.
  • CREATE_COMPLETE – Successful creation of one or more stacks.
  • CREATE_FAILED – Unsuccessful creation of one or more stacks. You can see the reason for the failure in the Events tab.
  • DELETE_IN_PROGRESS – Ongoing removal of one or more stacks.
  • DELETE_COMPLETE – Successful deletion of one or more stacks. Deleted stacks are retained and viewable for 90 days.
  • DELETE_FAILED – Unsuccessful deletion of one or more stacks. Some of the resources couldn’t be deleted. You can see why in the Events tab. You will have to manually delete them. (A possible reason can be if the resource has termination protection enabled.)
  • UPDATE_IN_PROGRESS – Ongoing update of one or more stacks.
  • UPDATE_COMPLETE – Successful update of one or more stacks.
  • UPDATE_COMPLETE_CLEANUP_IN_PROGRESS – Ongoing removal of old resources for one or more stacks after a successful stack update. For stack updates that require resources to be replaced, CloudFormation creates the new resources first and then deletes the old resources to help reduce any interruptions with your stack. In this state, the stack has been updated and is usable, but CloudFormation is still deleting the old resources.
  • UPDATE_ROLLBACK_IN_PROGRESS – Ongoing return of one or more stacks to the previous working state after a failed stack update. You can’t update the stack if it is in this state.
  • UPDATE_ROLLBACK_COMPLETE_CLEANUP_IN_PROGRESS – Ongoing removal of new resources for one or more stacks after a failed stack update. In this state, the stack has been rolled back to its previous working state and is usable, but CloudFormation is still deleting any new resources it created during the stack update.
  • UPDATE_ROLLBACK_COMPLETE – Successful return of one or more stacks to a previous working state after a failed stack update.
  • UPDATE_ROLLBACK_FAILED – Unsuccessful return of one or more stacks to a previous working state after a failed stack update. You can’t update the stack while it is in this condition. Your options are to delete the stack or to continue rolling back. To continue the rollback, you have to go to your stack, click on Stack actions, and choose Continue update rollback. In the Additional information section, you will see which are the problematic resources, and you can mark them to be skipped. Then the rollback will finish successfully, and you will have to manually go and fix the failed resource. If you don’t want to perform any of these, you can contact Support to restore the stack to a usable state.

You can find information about all stack status codes in the following AWS documentation:

View CloudFormation stack events

Change sets help you see what exactly will be updated after you make a certain change. They show you the execution plan.

After you make a change to your template, you can go to the CloudFormation console, click on your stack, go to the Change sets tab, and create a change set. You will be asked to provide a template either from your local filesystem or from S3.

Infrastructure-as-code

Then, similar to when you create a stack, you will be asked to give value to the parameters and an IAM role that the stack will use to create or update the resources.

cloudformation-set-details
cloudformation-set-options

After you create the change set, you will be able to see the differences between your current template and your new one, and make sure it is exactly what you want to change before executing the change set. It also gives you information on whether the resource will be replaced or not.

cloudformation-demo-2
cloud-formation-property-level-changes

When you are ready to execute the change set, you can click on the Execute change set button, and you will be asked for the following:

  • How should the stack behave in case of failure?
    • Roll back all stack resources to the last known stable state
    • Preserve the state of successfully provisioned resources, while rolling back failed resources to the last known stable state. Resources without a last known stable state will be deleted upon the next stack operation.
  • What should the stack do with the newly created resources during a rollback?
    • Retain or delete created resources according to their attached deletion policy.
    • Delete created resources during a rollback regardless of their attached deletion policy.
change-set

If you are repeatedly creating identical resource configurations across multiple templates, you might consider using nested stacks. They are a way to separate the common configurations into dedicated templates. You can create a nested stack within a parent stack by using the AWS::CloudFormation::Stack resource.

Here is an example of a parent stack with two nested stacks – one for a security group and another for an EC2 instance.

The parent template:

AWSTemplateFormatVersion: "2010-09-09"
Description: Parent template with nested stacks for Security Group and EC2 Instance
Parameters:
  KeyName:
    Description: Name of an existing EC2 KeyPair to SSH into the instance
    Type: AWS::EC2::KeyPair::KeyName

Resources:
  SecurityGroupStack:
    Type: AWS::CloudFormation::Stack
    Properties:
      TemplateURL: <https://s3.amazonaws.com/demo-bucket/s3-nested-stack.yaml>

  EC2InstanceStack:
    Type: AWS::CloudFormation::Stack
    Properties:
      TemplateURL: <https://s3.amazonaws.com/demo-bucket/ec2-nested-stack.yaml>
      Parameters:
        KeyName: !Ref KeyName
        SecurityGroupId: !GetAtt SecurityGroupStack.Outputs.SecurityGroupId

Outputs:
  InstanceId:
    Description: The EC2 Instance ID
    Value: !GetAtt EC2InstanceStack.Outputs.InstanceId

The security group nested stack template:

AWSTemplateFormatVersion: "2010-09-09"
Description: Security Group for EC2 instance
Resources:
  InstanceSecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: Enable SSH access
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: 22
          ToPort: 22
          CidrIp: 100.200.100.200/32

Outputs:
  SecurityGroupId:
    Description: The Security Group ID
    Value: !Ref InstanceSecurityGroup

The EC2 instance nested stack template:

AWSTemplateFormatVersion: "2010-09-09"
Description: EC2 instance
Parameters:
  KeyName:
    Description: Name of an existing EC2 KeyPair
    Type: AWS::EC2::KeyPair::KeyName
  SecurityGroupId:
    Description: Security Group ID
    Type: String

Resources:
  EC2Instance:
    Type: AWS::EC2::Instance
    Properties:
      InstanceType: t3.micro
      KeyName: !Ref KeyName
      ImageId: ami-08c40ec9ead489470
      SecurityGroupIds:
        - !Ref SecurityGroupId

Outputs:
  InstanceId:
    Description: The Instance id
    Value: !Ref EC2Instance

In the CloudFormation console, the nested stacks will have a label NESTED.

aws- cloud-formation

Each nested stack can contain other nested stacks. The root stack is the top-level stack to which all nested stacks ultimately belong. If a stack is NESTED, it means it has an immediate parent stack. For the first level of nested stacks, the root stack is also the parent stack.

CloudFormation has a drift detection option that might be useful to run regularly to check whether a resource’s configuration has drifted from its intended configuration.

In the above example, I went and manually changed the inbound rule of the security group. Then I went to the nested stack that deployed it and clicked on Stack actions > Detect drift. A drift detection process started. After it finished, I went to Stack actions > View drift results. This showed me that the security group has been modified.

drift

By choosing the modified resource in the Drifts page, you can click on View drift details and see exactly which property was changed. If you then go to the AWS console, manually revert the change and run Detect drift again, the resource that was previously in MODIFIED status will now show IN_SYNC.

Another option for fixing the sync is to remove the resource from the template and run the stack update operation. After the resource is no longer managed by the stack, you should re-add it and redeploy the stack.

If you are managing multiple accounts in an AWS Organization, and you need to be able to automatically deploy the same resources to more than one account and to more than one region, you should consider using CloudFormation Stack Sets.

A stack set can be deployed as a normal CloudFormation resource with the AWS::CloudFormation::StackSet type. In this resource, you can specify targets – those are the accounts to which you want to deploy. If you set the root ID of your organization as a target, the described resources in the stack set will be applied to all accounts, and when a new account is added, you can automatically deploy them to it by redeploying the stack set. You can also specify all the regions that you want to provision the needed resources to. We will dive deeper into the specifics of the Stack sets in another post.

CloudFormation provides a powerful way to define and deploy AWS infrastructure using code. You can describe your environment in a consistent and reproducible way by writing templates. Stacks and nested stacks help you organize and manage resources efficiently, while change sets give you visibility into the changes before they are applied, minimizing the risk of errors.

Beyond the basics, CloudFormation offers features like:

  • rollback and automatic resource deletion to safeguard the environment;
  • execution plans via Change sets that give you visibility into the changes before they are applied, minimizing the risk of errors;
  • drift detection option;
  • cross-region and cross-account deployment for complex setups via Stacksets.

With CloudFormation, we can automate infrastructure management, improve reliability, and maintain a clear, auditable infrastructure lifecycle.

Explore ITGix services and learn more about our expertise.

More Posts

As organizations across Europe face increasing regulatory pressure around data residency, operational control, and digital sovereignty, cloud strategy is no longer just about scalability and performance. It is about trust,...
Reading
Introduction Cloud technology continues to reshape how businesses deliver value and scale globally. Yet as more organizations adopt multi-cloud architectures, the path to modernization often becomes more complex and costly....
Reading
Get In Touch
ITGix provides you with expert consultancy and tailored DevOps services to accelerate your business growth.
Newsletter for
Tech Experts
Join 12,000+ business leaders and engineers who receive blogs, e-Books, and case studies on emerging technology.