﻿
### Slide 1:

![Slide 1](slide_1.png)

::: Notes


#### Instructor notes

#### Student notes

**Accessibility note for screen reader users** : In an effort to make code examples in this presentation more accessible, "Start of code" and "End of code" labels have been added before and after blocks of code on slides.

:::

### Slide 2:

![Slide 2](slide_2.png)

::: Notes


#### Instructor notes

#### Student notes

:::

### Slide 3:

![Slide 3](slide_3.png)

::: Notes

This slide continues the Example Corp. scenario: having established consistent deployments in the previous module, the company now needs to automate them. Manual deployments, no matter how well-documented, introduce human error and don't scale. Automating deployments also creates a record of what was deployed and when, which is valuable for troubleshooting, compliance, and rollback.

#### Instructor notes

#### Student notes

Example Corp. is about to roll out a new customer application. In the previous module, you developed a plan for *consistent deployments*. Now, your manager is asking for a plan to automate the deployments. The plan should also include a mechanism that employees can implement to *provision company-approved resources*.

:::

### Slide 4:

![Slide 4](slide_4.png)

::: Notes


#### Instructor notes

#### Student notes

:::

### Slide 5:

![Slide 5](slide_5.png)

::: Notes

The deployment challenges listed here — consistency across regions, dependency management, rollback, and testing — are exactly the problems that infrastructure as code (IaC) is designed to address. Each question points to a limitation of manual processes: they don't scale, they're hard to reverse, and they can't be tested in isolation. Ask students which of these challenges they've encountered in practice, and what the consequences were.

#### Instructor notes

#### Student notes

The cloud opens up many possibilities, but it also presents questions about how to manage its power and flexibility, such as the following:

* How do you update servers that have already been deployed into a production environment?
* How do you consistently deploy an infrastructure to multiple Amazon Web Services (AWS) Regions in disparate geographical locations?
* How do you manage dependencies, not only on systems and technologies but on entire subsystems (for example, a website deployed atop an ecommerce infrastructure)?
* How do you roll back a deployment that didn't deploy according to plan? How do you reclaim the resources that were already created?
* How do you test and debug a deployment before rolling it out to production?

:::

### Slide 6:

![Slide 6](slide_6.png)

::: Notes

AWS offers multiple IaC tools, each suited to different use cases and team preferences. CloudFormation is the most direct mapping to AWS resources and is fully managed; the CDK lets developers use familiar programming languages but adds an abstraction layer. Choosing the right tool depends on your team's skills, your organization's operational model, and how much control you need over the underlying CloudFormation template.

#### Instructor notes

#### Student notes

CloudFormation is a service that you use to model and set up your AWS resources. That way, you can spend less time managing those resources and more time focusing on applications that run in AWS. You create a template that describes all the AWS resources that you want, such as Amazon Elastic Compute Cloud (Amazon EC2) instances or Amazon Relational Database Service (Amazon RDS) DB instances. Then, CloudFormation provisions and configures those resources for you. With CloudFormation, you can use the following tools:

* **Custom scripts and applications** : Use AWS CLI or APIs to automate deployments in a variety of languages.
* **CloudFormation** : Use a JSON or YAML script to build a template file. The template file creates and deletes a collection of resources together as a single unit (called a stack).
* **AWS Cloud Development Kit (AWS CDK)** : AWS CDK is an open source software development framework for defining cloud infrastructure as code (IaC) with modern programming languages and deploying it by using CloudFormation.
* **AWS Tools for PowerShell** : Use PowerShell to manage AWS services.
* **AWS SDK for Python (Boto3)** : Use Python to create, configure, and manage AWS services.

:::

### Slide 7:

![Slide 7](slide_7.png)

::: Notes

CloudFormation manages resources as a unit, but the real world is messier: people make changes outside of CloudFormation, and those changes create drift. Drift detection is the mechanism for identifying divergence between the template definition and the actual resource state. The challenge is that detection alone doesn't fix drift — it tells you what changed, not how to reconcile it. Resolving drift requires judgment about which state is correct: the template or the resource.

#### Instructor notes

#### Student notes

**CloudFormation** : With CloudFormation, you can create and provision AWS infrastructure deployments predictably and repeatedly. Using the service helps you use AWS service offerings to build highly reliable, highly scalable, cost-effective applications. You do not need to worry about creating and configuring the underlying AWS infrastructure. These AWS services include the following: Amazon EC2, Amazon Elastic Block Store (Amazon EBS), Amazon Simple Notification Service (Amazon SNS), Elastic Load Balancing (ELB), AWS Auto Scaling. You can use a template file to create and delete a collection of resources together as a single unit (a stack).

**Detecting drift** : Even as you manage your resources using CloudFormation, your users can change those resources outside of CloudFormation. Users can edit resources directly by using the underlying service that created the resource. For example, you can use the Amazon EC2 console to update a server instance that was created as part of a CloudFormation stack. Some changes might be made accidentally, and some might be made intentionally to respond to time-sensitive operational events. Regardless, changes made outside of CloudFormation can complicate stack update or deletion operations. You can use drift detection to identify stack resources in which configuration changes have been made outside of CloudFormation management. You can then take corrective action so that your stack resources are again in sync with their definitions in the stack template. For example, you can update the drifted resources directly so that they agree with their template definition. Resolving drift helps to ensure configuration consistency and successful stack operations.

:::

### Slide 8:

![Slide 8](slide_8.png)

::: Notes

The template-and-stack model is the core of CloudFormation: a template describes desired state; a stack is the realization of that state. The key property is that stacks are managed as a unit — creating and deleting resources together. This is powerful but also means that a failed stack deletion can leave resources in an unknown state. Understanding what controls stack lifecycle — and what doesn't — is critical before using CloudFormation in production.

#### Instructor notes

#### Student notes

The two major concepts in CloudFormation are templates and stacks. A template is a JSON or YAML specification of the AWS resources to be provisioned. A stack is a collection of AWS resources that has been created from a template. You can provision (create) a stack numerous times. When a stack is provisioned, the AWS resources specified by its template are created. Any charges incurred from using these services start accruing as they are created as part of the CloudFormation stack. When a stack is deleted, the resources associated with that stack are deleted. The order of deletion is determined by CloudFormation. You do not have direct control over what gets deleted or when.

:::

### Slide 9:

![Slide 9](slide_9.png)

::: Notes

CloudFormation's default rollback behavior on failure is a safety net, but it has limits. Some resources — particularly S3 buckets with content — may not be deletable during rollback, which can leave stacks in a failed state that's hard to clean up. The `DeletionPolicy` and `DeleteOnTermination` attributes give you control, but they require upfront planning. Ask students: if a stack fails to roll back cleanly, what's your recovery procedure?

#### Instructor notes

#### Student notes

**CloudFormation** : If you encounter an error when launching a template, all resources are rolled back by default. You can change this option from the command line as follows:

* To preserve an Amazon EBS volume, set its `DeleteOnTermination` attribute to `False`.
* To preserve a resource, set its `DeletionPolicy` attribute to `Retain`.

However, some resources, such as an Amazon Simple Storage Service (Amazon S3) bucket, might not be deleted when a stack is deleted. For more information about rollback configuration, see "RollbackConfiguration" in the AWS CloudFormation API Reference at https://docs.aws.amazon.com/AWSCloudFormation/latest/APIReference/API_RollbackConfiguration.html. For more information about rolling back an update, see "Continue Rolling Back an Update" in the AWS CloudFormation User Guide at https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/using-cfn-updating-stacks-continueupdaterollback.html.

:::

### Slide 10:

![Slide 10](slide_10.png)

::: Notes


#### Instructor notes

#### Student notes

:::

### Slide 11:

![Slide 11](slide_11.png)

::: Notes

CloudFormation templates in JSON are functional but error-prone to write by hand: a missing comma or mismatched bracket will fail template validation. YAML is more human-readable and less punctuation-sensitive, making it the preferred format for most teams today. Regardless of format, using an editor with CloudFormation support — syntax checking, auto-completion — significantly reduces authoring errors before templates are deployed.

#### Instructor notes

#### Student notes

Though the JSON format has many positive attributes, one of its drawbacks is that it is easy to introduce a syntax error inadvertently. To simplify the task of editing templates, use an editor that supports editing CloudFormation templates or one that is JSON-aware. Visual Studio integrated development environment (IDE) with AWS Toolkit for Visual Studio supports editing CloudFormation templates. Support includes the following features: Parsing and formatting, Auto-completion of CloudFormation commands and keywords, Syntax checking. If you prefer to work in a text editor, such as Sublime Text or Notepad++, most popular text editors have JSON and YAML plugins that you can use to format your code. Third-party tools are also available for generating templates programmatically (such as Troposphere). For more information, see "Using the AWS CloudFormation Template Editor for Visual Studio" in the AWS Toolkit for Visual Studio User Guide at http://docs.aws.amazon.com/AWSToolkitVS/latest/UserGuide/tkv-cfn-editor.html.

:::

### Slide 12:

![Slide 12](slide_12.png)

::: Notes

Infrastructure Composer provides a visual interface for CloudFormation template authoring, lowering the barrier for teams less familiar with YAML or JSON. However, visual tools can obscure important details: a drag-and-drop operation in the canvas generates template code that should be reviewed before deployment. Consider Infrastructure Composer a starting point for template creation, not a substitute for understanding the underlying CloudFormation structure.

#### Instructor notes

#### Student notes

AWS Infrastructure Composer is a visual tool that you can use to create and modify CloudFormation templates with a drag-and-drop interface. You can add, modify, or remove resources, and the underlying JSON or YAML will be altered accordingly. If you modify a template that is associated with a running stack, you can update the stack so that it conforms to the template.

:::

### Slide 13:

![Slide 13](slide_13.png)

::: Notes

Infrastructure Composer's canvas, resource palette, and template editor work together to support different workflows — visual drag-and-drop for layout and relationships, direct template editing for precise control. The synchronization between canvas and template means changes in one view are reflected in the other, which helps students connect the visual representation to the underlying code. Ask students which view they would use to review a template before deploying it.

#### Instructor notes

#### Student notes

AWS Infrastructure Composer is a graphic tool for creating, viewing, and modifying CloudFormation templates. You can use Infrastructure Composer to visualize, build, and deploy modern applications from AWS services that are supported by AWS CloudFormation. The following are Composer components:

* **Resources palette** : The Resource types pane lists all the template resources that you can add to your template, categorized by their AWS service names. You can drag and drop these resources onto the canvas to build your architecture.
* **Canvas** : The canvas displays your template resources as a diagram. You can use it to add or remove resources, create relationships between resources, and arrange their layout.
* **Template** : In the Template editor, you can view and edit your infrastructure code in YAML or JSON.
* **Menu** : The menu provides quick access to commands for common actions. These actions include the following: Creating a new project, Opening and saving templates, Syncing with local tools such as an IDE, Viewing documentation and shortcuts, Installing the AWS IDE Toolkit.

For more information, see "Visual designer and visual canvas" in the AWS Infrastructure Composer User Guide at https://docs.aws.amazon.com/infrastructure-composer/latest/dg/reference-visual.html#reference-visual-designer.

:::

### Slide 14:

![Slide 14](slide_14.png)

::: Notes


#### Instructor notes

#### Student notes

:::

### Slide 15:

![Slide 15](slide_15.png)

::: Notes

CloudFormation templates have four major sections that serve different purposes: Resources defines what to create; Parameters allows runtime customization; Outputs exposes values for use elsewhere; Mappings provides static lookup tables. Understanding the role of each section helps students write templates that are reusable across environments. The key design tension is between hardcoded values (simpler but inflexible) and parameterized values (more flexible but harder to validate).

#### Instructor notes

#### Student notes

Let's review the major components of a template as follows:

* **Resources** : The Resources section contains the AWS objects that you will create. You can specify relationships and dependencies between resources to make sure that resources are created in the right order. You can create resources across many AWS services, including the following: Amazon EC2, Amazon S3, Amazon DynamoDB, Amazon RDS, Amazon Redshift, Amazon Route 53.
* **Parameters** : Parameters are name-value pairs whose values are supplied at runtime when the template is launched. You can then reference these parameters later in the template using special syntax. You can use them instead of literal values. Use parameters to specify variables that can change across deployments of the templates, such as names of Amazon EC2 key pairs and Availability Zones.
* **Outputs** : The Outputs section of a template returns string values created by the template that might be important to users of the associated resources. For example, if you are creating an EC2 instance that is a public web server, you might output the full public DNS name of the server in the Outputs section.
* **Mappings** : Mappings can be thought of as named static strings. They are typically used to refer to the values of the most current Amazon Machine Images (AMIs) in a Region. Mappings differ by Region. They also change over time as new AMIs are released.

:::

### Slide 16:

![Slide 16](slide_16.png)

::: Notes

The Resources section is the only required section in a CloudFormation template. Each resource has a logical ID that's used to reference it elsewhere in the template, a type that maps to an AWS resource, and properties specific to that resource type. Getting resource properties right requires consulting the documentation, because property names and allowed values vary by resource type and are not guessable from first principles.

#### Instructor notes

#### Student notes

The required Resources section declares the AWS resources that you want as part of your stack, such as an EC2 instance or an S3 bucket. You must declare each resource separately. However, you can specify multiple resources of the same type. If you declare multiple resources, separate them with commas. Each resource requires the following three fields:

* **Logical ID** : The logical ID must be alphanumeric (A–Z, a–z, 0–9) and unique within the template. Use the logical name to reference the resource in other parts of the template.
* **Resource type** : This identifies the type of resource that you are declaring. For example, `AWS::EC2::Instance` declares an EC2 instance.
* **Resource properties** : This refers to additional options that you can specify for a resource. For example, for each EC2 instance, you must specify an AMI ID for that instance.

For more information, see "Resources" in the AWS CloudFormation User Guide at http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/resources-section-structure.html. To learn more about CloudFormation template anatomy, see "AWS Resource and Property Types Reference" in the AWS CloudFormation User Guide at https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-template-resource-type-ref.html.

:::

### Slide 17:

![Slide 17](slide_17.png)

::: Notes

Intrinsic functions like `Ref` and `Fn::GetAtt` create dynamic connections between template resources, enabling templates to express relationships rather than hardcoding values. The important caveat is that `Ref` returns different identifiers for different resource types — using it incorrectly produces a valid template that creates broken infrastructure. Always verify what `Ref` returns for a specific resource type before using it in a context that requires a specific identifier format.

#### Instructor notes

#### Student notes

How do you refer to one element of a template from another element? For example, how do you associate an EC2 instance with an Elastic IP address defined within the same template? The example shows the most common intrinsic function, Ref, in a CloudFormation snippet that defines an Elastic IP address. Using the Ref function, you can reference an EC2 instance defined within the template itself. The function establishes a chain of relationships between your resources. You can use a similar pattern to associate security groups with resources, route tables with routes, and EC2 instances with subnets. Use care when using the Ref function because the value returned by Ref is dependent on the resource supplied to it. For example, using the Ref function on an S3 bucket returns the bucket's name. By contrast, using the function on an Amazon Simple Queue Service (Amazon SQS) queue returns the queue's URL. Make sure that the resource you are referencing with the Ref function is returning the correct identifier in the current context. In the example, the Ref function returns the instance ID of an EC2 instance. The return value is appropriate to assign to the InstanceId property of the `AWS::EC2::EIP` object. For a list of the values returned by various CloudFormation resources, see "Ref" in the AWS CloudFormation User Guide at http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-ref.html. To select other attributes on AWS resources defined within your CloudFormation template, see "Fn::GetAtt" in the AWS CloudFormation User Guide at http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-getatt.html. For more information about functions in general, see "Intrinsic function reference" in the AWS CloudFormation User Guide at http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference.html. To learn more about CloudFormation resource types, see "AWS Resource and Property Types Reference" in the AWS CloudFormation User Guide at https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-template-resource-type-ref.html.

:::

### Slide 18:

![Slide 18](slide_18.png)

::: Notes

The `DependsOn` attribute makes resource creation order explicit, which is necessary when CloudFormation's automatic dependency detection isn't sufficient. The underlying issue is that CloudFormation detects dependencies through `Ref` and `Fn::GetAtt`, but some dependencies are implied by application logic rather than resource references. Any time a resource must be fully configured before another resource starts, `DependsOn` should be considered even if CloudFormation wouldn't require it.

#### Instructor notes

#### Student notes

In this example, the web server has a dependency on the Amazon RDS instance. You must create the database before the web server. Although CloudFormation orders resource creation tasks automatically, these rules change as support for new resource types is rolled out through the system. To ensure consistent sequencing of resource creation tasks, use the `DependsOn` attribute. Note: Dependent stacks also have implicit dependencies. For example, if the properties of resource A use a `!Ref` function to resource B, the following rule applies: resource B is created before resource A. For more information, see "Resources" in the AWS CloudFormation User Guide at http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/resources-section-structure.html.

:::

### Slide 19:

![Slide 19](slide_19.png)

::: Notes

Parameters make templates reusable by deferring specific values to stack launch time. The trade-off is validation: parameters with AWS-specific types like KeyPair are validated before launch, while generic String parameters are only validated when the resource that uses them is created. This means a template can appear to launch successfully but fail later due to an invalid parameter value that wasn't caught upfront.

#### Instructor notes

#### Student notes

As demonstrated here, you can pass a value into your parameter using the AWS Management Console. Additionally, you can explicitly set a value for the parameter within your CloudFormation template by using the `Default:` attribute. Parameters support three data types: strings, numbers, and comma-delimited lists. CloudFormation supports numerous parameter types, including virtual private clouds (VPCs), subnets, and key pairs. If you provide a data type of String when creating a key pair parameter, CloudFormation checks whether the key pair exists when it creates the EC2 instance. It performs no validation until stack creation. If you provide a data type of KeyPair when creating a key pair parameter, CloudFormation checks whether the key pair exists before launching the stack. When the stack is launched from the console, a parameter typed as KeyPair renders a list with all key pairs in the account. For more information, see "Parameters" in the AWS CloudFormation User Guide at https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/parameters-section-structure.html.

:::

### Slide 20:

![Slide 20](slide_20.png)

::: Notes

Pseudo parameters are pre-populated by CloudFormation and provide values like the current account ID, region, and stack name without requiring manual entry. They're essential for writing region-agnostic and account-agnostic templates, but using them requires knowing which pseudo parameter provides which value. `AWS::AccountId` and `AWS::Region` are the most commonly used; `AWS::NoValue` is a special case that conditionally removes a property.

#### Instructor notes

#### Student notes

Pseudo parameters are parameters that are predefined by CloudFormation. You do not declare them in your template. For more information, see "Pseudo Parameters Reference" in the AWS CloudFormation User Guide at https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/pseudo-parameter-reference.html.

:::

### Slide 21:

![Slide 21](slide_21.png)

::: Notes

Outputs enable cross-stack referencing, which allows complex architectures to be split across multiple smaller, more manageable templates. The trade-off is coupling: if one stack exports a value that another stack imports, the exporting stack cannot be deleted while the importing stack exists. This creates dependencies between stacks that must be managed deliberately and can complicate stack lifecycle management in large environments.

#### Instructor notes

#### Student notes

You can view outputs from the console in the Outputs window of the CloudFormation page. When managing more complex infrastructures, a good practice is to use multiple smaller and more specific CloudFormation templates.

**Exporting values** : You can use outputs from each stack as inputs for other stacks through the export attribute. For example, in the following code snippet, the output named `StackVPC` returns the ID of a VPC. The operation then exports the value for cross-stack referencing with the name `VPCID` appended to the stack's name.

Other stacks that are in the same AWS account and Region can import the exported values. To import an exported value, use the `Fn::ImportValue` function in the template for the other stacks.

:::

### Slide 22:

![Slide 22](slide_22.png)

::: Notes

Mappings provide static lookup tables within a template — commonly used to map region names to region-specific AMI IDs. The challenge is maintenance: when AMI IDs change, every template that contains a Mappings section with those IDs must be updated. As your template library grows, keeping AMI IDs current across all templates becomes an operational overhead. Consider whether SSM Parameter Store references for AMI IDs might be a more maintainable alternative.

#### Instructor notes

#### Student notes

The example shows a Mappings section with a map `RegionMap`, which contains keys that map to name-value pairs containing single string values. The keys are Region names. Each name-value pair is the AMI ID in the Region represented by the key. For more information, see "Mappings" in the AWS CloudFormation User Guide at https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/mappings-section-structure.html.

:::

### Slide 23:

![Slide 23](slide_23.png)

::: Notes


#### Instructor notes

#### Student notes

:::

### Slide 24:

![Slide 24](slide_24.png)

::: Notes

Drift detection identifies when stack resources have been modified outside of CloudFormation, but it's a point-in-time check — not a continuous guard. Resources can be in a drifted state for a long time before detection runs. Integrating AWS Config's drift detection rule provides more continuous visibility, but it still requires human action to resolve findings. Consider: who in your organization should be notified when drift is detected, and what's the expected response time?

#### Instructor notes

#### Student notes

You can turn on drift detection from the CloudFormation console, or you can use AWS Config rules. To learn more about the AWS Config drift detection rule, see "cloudformation-stack-drift-detection-check" in the AWS Config Developer Guide at https://docs.aws.amazon.com/config/latest/developerguide/cloudformation-stack-drift-detection-check.html.

:::

### Slide 25:

![Slide 25](slide_25.png)

::: Notes

Embedding user data directly in CloudFormation templates using `Fn::Base64` and `!Sub` is effective for small scripts, but it creates a coupling between infrastructure definition and application bootstrapping. Long or complex scripts embedded in templates are hard to version control, test, and debug independently. Consider externalizing scripts to S3 and downloading them in a minimal bootstrap script for better maintainability.

#### Instructor notes

#### Student notes

You can use the `UserData` property of an instance, which is created through a CloudFormation template, to start an application on a newly created instance. This example employs two inherent CloudFormation functions as follows:

* `Fn::Base64` : Ensures that the user data script is output to instances in the correct data format.
* `!Sub` : Ensures that each command is entered as a separate value.

:::

### Slide 26:

![Slide 26](slide_26.png)

::: Notes

CloudFormation helper scripts like `cfn-init` and `cfn-signal` bridge the gap between resource provisioning and application readiness. Without them, CloudFormation has no way to know whether a launched instance has successfully bootstrapped its application — it only knows that the instance started. Helper scripts require the SSM Agent or internet access to communicate back to CloudFormation, which means they're another element that can fail during bootstrapping.

#### Instructor notes

#### Student notes

The following CloudFormation helper scripts are preinstalled on Amazon Linux AMI images:

* **cfn-init** : Used to retrieve and interpret resource metadata, install packages, create files, and start services.
* **cfn-signal** : Used to signal with a `WaitCondition`, so you can synchronize stack resources for application deployment.

On the latest Amazon Linux AMI version, the scripts are installed in `/opt/aws/bin`. For more information, see "CloudFormation Helper Scripts Reference" in the AWS CloudFormation User Guide at https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/cfn-helper-scripts-reference.html.

:::

### Slide 27:

![Slide 27](slide_27.png)

::: Notes

WaitConditions solve a fundamental timing problem: CloudFormation considers an instance 'created' when it passes status checks, but the application running on it may still be installing. Without a WaitCondition, downstream resources may be created before the upstream resource is actually ready. The trade-off is complexity: if the signal is never sent due to a bootstrapping failure, the stack waits until timeout — which can be long. Always pair WaitConditions with appropriate timeout values and error handling in your bootstrap scripts.

#### Instructor notes

#### Student notes

AWS considers your instance ready when it passes its status checks. However, your user data and scripts might still be installing all the necessary software. Required software can include turning your instance into a database server, a SharePoint server, or a node in a data processing cluster. To signal CloudFormation that your instance is truly ready, use a `WaitCondition`. Think of a `WaitCondition` as a stop sign that prevents your stack from being marked as complete by CloudFormation before your code sends a signal that it has finished. The `WaitConditionHandle` is a textual representation of the `WaitCondition` that your initialization code can use to signal CloudFormation that your resource has been created. The `WaitConditionHandle` specifies the number of successful signals that must be received before the `WaitCondition` is fulfilled. The default is one. Your initialization code is responsible for calling the `cfn-signal` command on the instance to indicate that it has finished its work. The initialization code can be in user data or in a separate script downloaded to the instance using `CloudFormation::Init`. You can signal that the task was successful — CloudFormation then either creates the next resource in your stack or marks your entire stack as completed. You can also mark that the task failed — CloudFormation, by default, rolls back any resources created in your stack. You can use a wait condition for situations such as the following:

* To coordinate stack resource creation with configuration actions that are external to the stack creation
* To track the status of a configuration process

For these situations, AWS recommends that you associate a `CreationPolicy` attribute with the `WaitCondition` so that you don't need to use a `WaitConditionHandle`.

:::

### Slide 28:

![Slide 28](slide_28.png)

::: Notes

This example shows how `WaitConditionHandle` and `cfn-signal` work together: the instance's user data script explicitly signals the WaitConditionHandle when bootstrapping completes. If the signal is never sent — because of a script error, network issue, or missing permissions — the stack creation will pause until the WaitCondition times out. This design means that initialization failures manifest as stack creation delays, not immediate failures.

#### Instructor notes

#### Student notes

In this example, the snippet of code will launch an EC2 instance. In the user data script, the process signals `MyWaitHandle` so that the `WaitConditionHandle` is fulfilled.

:::

### Slide 29:

![Slide 29](slide_29.png)

::: Notes

`CreationPolicy` is the modern, preferred alternative to standalone WaitConditions for signaling that a resource is ready. It attaches the signaling requirement directly to the resource, making the template more self-contained and easier to read. The count parameter allows you to require multiple signals — useful for Auto Scaling groups where you want a minimum number of instances to successfully complete initialization before the stack proceeds.

#### Instructor notes

#### Student notes

Use the `CreationPolicy` attribute with a resource to prevent its status from reaching complete until CloudFormation receives a "success" signal for that resource. To signal a resource, you can use the `cfn-signal` helper script or `SignalResource` API. For more information, see "cfn-signal" in the AWS CloudFormation User Guide at https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/cfn-signal.html. For more information, see "SignalResource" in the AWS CloudFormation API Reference at https://docs.aws.amazon.com/AWSCloudFormation/latest/APIReference/API_SignalResource.html.

You can attach a `CreationPolicy` attribute to the following: `AWS::AppStream::Fleet`, `AWS::AutoScaling::AutoScalingGroup`, `AWS::EC2::Instance`, `AWS::CloudFormation::WaitCondition`. For more information, see "CreationPolicy Attribute" in the AWS CloudFormation User Guide at https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-attribute-creationpolicy.html.

:::

### Slide 30:

![Slide 30](slide_30.png)

::: Notes

`cfn-init` reads metadata from the `AWS::CloudFormation::Init` key to perform installation and configuration steps, separating the configuration specification (in the template) from the bootstrapping logic (in the helper script). This separation improves readability but introduces an indirect relationship that can be confusing to troubleshoot: when `cfn-init` fails, the error appears in the instance logs, not directly in CloudFormation's stack events. Always check both places when debugging bootstrapping failures.

#### Instructor notes

#### Student notes

**`AWS::CloudFormation::Init`** : Use the `AWS::CloudFormation::Init` type to include metadata on an EC2 instance for the `cfn-init` helper script. CloudFormation provides Python helper scripts, such as `cfn-init`, that you can use to install software and start services on an EC2 instance in your stack.

**`cfn-init`** : If your template calls the `cfn-init` script, the script looks for resource metadata rooted in the `AWS::CloudFormation::Init` metadata key. For more information, see "cfn-init" in the AWS CloudFormation User Guide at https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/cfn-init.html. The `cfn-init` helper script supports all metadata types for Linux systems. It supports metadata types for Windows with conditions. For more examples, see the following topics in the AWS CloudFormation User Guide: "Deploying Applications on Amazon EC2 with AWS CloudFormation" at https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/deploying.applications.html and "Bootstrapping AWS CloudFormation Windows Stacks" at https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/cfn-windows-stacks-bootstrapping.html.

:::

### Slide 31:

![Slide 31](slide_31.png)

::: Notes


#### Instructor notes

#### Student notes

:::

### Slide 32:

![Slide 32](slide_32.png)

::: Notes

Troubleshooting CloudFormation issues requires checking multiple places: stack events in the console for high-level status, and system logs on the instance for bootstrapping failures. The most common mistake is looking only at CloudFormation's stack events and missing errors that happened inside the instance. Configuring CloudFormation to publish logs to CloudWatch solves the log access problem, but it requires that the template be set up correctly before the failure occurs.

#### Instructor notes

#### Student notes

If CloudFormation fails to create, update, or delete your stack, view the error messages or logs to help you learn more about the issue. The following tasks describe general methods for troubleshooting a CloudFormation issue.

**Status of stack and error messages** : Use the CloudFormation console to view the status of your stack. In the console, you can view a list of stack events while your stack is being created, updated, or deleted. From this list, find the failure event and then view the status reason for that event. The status reason might contain an error message from CloudFormation or from a particular service, which helps you troubleshoot your problem.

**Amazon EC2 issues** : For Amazon EC2 issues, view the cloud-init and cfn logs. These logs are published on the EC2 instance in the `/var/log/` directory. These logs capture processes and command outputs while CloudFormation is setting up your instance. For Windows, view the EC2Configure service and cfn logs in `%ProgramFiles%\Amazon\EC2ConfigService` and `C:\cfn\log`. You can also configure your CloudFormation template so the logs are published to Amazon CloudWatch. CloudWatch displays logs in the AWS Management Console so you don't need to connect to your EC2 instance. For more information, see "Troubleshooting CloudFormation" in the AWS CloudFormation User Guide at https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/troubleshooting.html.

:::

### Slide 33:

![Slide 33](slide_33.png)

::: Notes

The `--on-failure` option gives you control over what happens when stack creation fails: preserve resources for debugging (`DO_NOTHING`), roll back created resources (`ROLLBACK`), or delete everything (`DELETE`). The right choice depends on the context: in development, `DO_NOTHING` is useful for debugging; in automated pipelines, `DELETE` avoids accumulating failed stacks. The `--stack-policy` option adds a layer of protection against accidental changes to critical resources.

#### Instructor notes

#### Student notes

There are additional command options that help you manage stack creations. Some key options are the following:

* `--on-failure` : This determines which action will be taken if stack creation fails. It must be one of the following: `DO_NOTHING`, `ROLLBACK`, `DELETE`. You can specify either `--on-failure` or `--disable-rollback`, but not both.
* `--stack-policy` : Set a stack policy to control stack updates.
* `--parameters` : This is a list of parameter structures that specifies input parameters for the stack.

For more information, see "create-stack" in the AWS CLI Command Reference at https://docs.aws.amazon.com/cli/latest/reference/cloudformation/create-stack.html.

:::

### Slide 34:

![Slide 34](slide_34.png)

::: Notes

Failed rollbacks are one of the most frustrating CloudFormation states: the stack is stuck, you can't easily update or delete it, and the cause is often that a resource was changed outside of CloudFormation. The key lesson is that changes made outside of CloudFormation are a primary cause of operational problems. Prevention — managing all stack resources through CloudFormation and using permissions to prevent out-of-band changes — is more effective than recovery.

#### Instructor notes

#### Student notes

You can instruct CloudFormation to continue rolling back an update to your stack even after the rollback has failed. A stack goes into the `UPDATE_ROLLBACK_FAILED` state when CloudFormation cannot roll back all changes during an update. For example, you might have a stack that is rolling back to an earlier database instance that was deleted outside of CloudFormation.

Common causes of a failed rollback include the following:

* Changing a resource in your stack outside of CloudFormation
* Granting insufficient permissions
* Receiving limitation errors
* Encountering resources that have not stabilized

After you have remedied the cause of the failed rollback, you can instruct CloudFormation to continue rolling back the update. You can do this by using the CloudFormation console or the AWS CLI. If the stack still does not successfully roll back, contact AWS Support. For more information, see "continue-update-rollback" in the AWS CLI Command Reference at http://docs.aws.amazon.com/cli/latest/reference/cloudformation/continue-update-rollback.html and "Continue Rolling Back an Update" in the AWS CloudFormation User Guide at http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/using-cfn-updating-stacks-continueupdaterollback.html.

:::

### Slide 35:

![Slide 35](slide_35.png)

::: Notes


#### Instructor notes

#### Student notes

:::

### Slide 36:

![Slide 36](slide_36.png)

::: Notes

CloudFormation best practices address both the technical and operational dimensions of IaC: how to structure templates for reuse, how to protect against accidental changes, and how to maintain an audit trail. These practices are not optional refinements — they address real failure modes. Templates without stack policies can have critical resources accidentally replaced; stacks without CloudTrail logging make it hard to understand who changed what when something goes wrong.

#### Instructor notes

#### Student notes

Best practices are recommendations that help you use CloudFormation more effectively and securely throughout its entire workflow. Recommendations are centered around the following:

* Learning how to plan and organize your stacks
* Creating templates that describe your resources and the software applications that run on them
* Managing your stacks and their resources

These best practices are based on real-world experience from current CloudFormation customers. For more information, see each of the following resources in the AWS CloudFormation User Guide: "AWS CloudFormation Best Practices" at http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/best-practices.html, "Exporting Stack Output Values" at https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/using-cfn-stack-exports.html, "Working with AWS CloudFormation StackSets" at https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/what-is-cfnstacksets.html.

:::

### Slide 37:

![Slide 37](slide_37.png)

::: Notes


#### Instructor notes

#### Student notes

For more information, see "AWS CloudFormation Best Practices" in the AWS CloudFormation User Guide at http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/best-practices.html.

:::

### Slide 38:

![Slide 38](slide_38.png)

::: Notes

These best practices address a common CloudFormation anti-pattern: using CloudFormation for initial deployment but then managing resources directly. Once a resource drifts from its template, the benefits of IaC — repeatability, auditability, version control — are undermined. Change sets are particularly important: they let you preview what CloudFormation will do before it does it, which is essential for avoiding unintended resource replacement.

#### Instructor notes

#### Student notes

**Manage all stack resources through CloudFormation:** After you launch a stack, use the CloudFormation console, API, or AWS Command Line Interface (CLI) to update resources in your stack. Do not make changes to stack resources outside of CloudFormation. Doing so can create a mismatch between your stack's template and the current state of your stack resources. For more information, see "Walkthrough: Updating a Stack" in the AWS CloudFormation User Guide at https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/updating.stacks.walkthrough.html.

**Create change sets before updating your stacks:** Use change sets to determine how proposed changes to a stack might impact your running resources before you implement them. CloudFormation doesn't make any changes to your stack until you implement the change set. You can decide whether to proceed with your proposed changes or create another change set. For more information, see "Updating Stacks Using Change Sets" in the AWS CloudFormation User Guide at https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/using-cfn-updating-stacks-changesets.html.

**Use stack policies:** Stack policies help protect critical stack resources from unintentional updates that might cause resources to be interrupted or even replaced. A stack policy is a JSON document that describes which update actions can be performed on designated resources. For more information, see "Prevent Updates to Stack Resources" in the AWS CloudFormation User Guide at https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/protect-stack-resources.html.

**Use CloudTrail to log CloudFormation API calls:** CloudTrail tracks anyone making CloudFormation API calls in your AWS account. CloudTrail logs API calls whenever anyone uses the CloudFormation API, the CloudFormation console, a backend console, or CloudFormation CLI commands. For more information, see "Logging AWS CloudFormation API Calls with AWS CloudTrail" in the AWS CloudFormation User Guide at https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/cfn-api-logging-cloudtrail.html.

**Use code reviews and revision controls to manage your templates:** Your stack templates describe the configuration of your AWS resources, such as their property values. To review changes and to keep an accurate history of your resources, use code reviews and revision controls. For more information, see "AWS CloudFormation Best Practices" in the AWS CloudFormation User Guide at http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/best-practices.html.

:::

### Slide 39:

![Slide 39](slide_39.png)

::: Notes


#### Instructor notes

#### Student notes

:::

### Slide 40:

![Slide 40](slide_40.png)

::: Notes

AWS Service Catalog provides a governed self-service portal where end users can launch approved resources without needing direct IAM permissions on the underlying services. The key design principle is separation of concerns: catalog administrators define what's available and how it can be configured; end users choose from a curated menu. This model enables autonomy while maintaining guardrails, but it requires ongoing catalog maintenance as approved configurations change.

#### Instructor notes

#### Student notes

With Service Catalog, IT administrators can create, manage, and distribute catalogs of approved products to end users. These users can then access the products they need in a personalized portal. To enforce compliance with company business policies, administrators can control which users have access to each product.

**Users** : Service Catalog supports the following types of users:

* **Catalog administrators (administrators)** : Catalog administrators manage a catalog of products (applications and services), organizing them into portfolios and granting access to end users. To provide advanced resource management, Service Catalog administrators prepare CloudFormation templates, configure constraints, and manage AWS Identity and Access Management (IAM) roles that are assigned to products.
* **End users** : End users receive AWS credentials from their IT department or manager. They use the AWS Management Console to launch products to which they have been granted access.

**Products** : A product is an IT service that you want to make available for deployment on AWS. A product consists of one or more AWS resources. A product can be a single compute instance running Amazon Linux, a fully configured multi-tier web application running in its own environment, or anything in between. You create a product by importing a CloudFormation template.

**Portfolios** : A portfolio is a collection of products together with configuration information. Portfolios help manage who can use specific products and how they can use them. With Service Catalog, you can create a customized portfolio for each type of user in your company and selectively grant access to the appropriate portfolio. You also can share your portfolios with other AWS accounts. You can then make it possible for the administrator of those accounts to distribute your portfolios with additional constraints, such as limiting which EC2 instances a user can create. For more information, see "What Is AWS Service Catalog?" in the AWS Service Catalog Administrator Guide at https://docs.aws.amazon.com/servicecatalog/latest/adminguide/introduction.html.

:::

### Slide 41:

![Slide 41](slide_41.png)

::: Notes

The Service Catalog administrator workflow involves creating products from CloudFormation templates, organizing them into portfolios, and configuring constraints and permissions. The constraint system is powerful: launch constraints assign a specific role for provisioning (enabling least-privilege for end users); template constraints limit configuration options. Constraints add governance but also add complexity — poorly configured constraints can prevent end users from deploying what they need.

#### Instructor notes

#### Student notes

This diagram shows the initial workflow for an administrator when creating a catalog.

**Versioning** : Use Service Catalog to manage multiple versions of the products in your catalog. You can add new versions of templates and associated resources based on software updates or configuration changes.

**Permissions** : By granting a user permissions, that user can browse the portfolio and launch the products in it. To control who can view and modify your catalog, apply IAM permissions. You can assign IAM permissions to IAM users, groups, and roles.

**Constraints** : Constraints control the ways that specific AWS resources can be deployed for a product. You can use them to apply limits to products for governance or cost control. Types of Service Catalog constraints include the following: Launch constraints -- Specify a role for a product in a portfolio. This role is used to provision the resources at launch. Notification constraints -- Get notifications about stack events using an Amazon SNS topic. Template constraints -- Restrict the configuration parameters that are available for the user when launching the product.

**Tags** : Tags are useful for identifying and categorizing AWS resources that users provision. Types of tags include the following: AutoTags -- These tags identify information about the origin of a provisioned resource in Service Catalog. Service Catalog applies these tags to provisioned resources automatically. TagOptions -- These tags are key-value pairs managed in Service Catalog that serve as templates for creating AWS tags. For more information, see "Managing Tags in AWS Service Catalog" in the AWS Service Catalog Administrator Guide at https://docs.aws.amazon.com/servicecatalog/latest/adminguide/managing-tags.html.

:::

### Slide 42:

![Slide 42](slide_42.png)

::: Notes

The end-user workflow in Service Catalog is intentionally simple: browse the portfolio, select a product, configure allowed parameters, and launch. The complexity is hidden behind the catalog interface. The key question for instructors to raise is: what happens when the available products don't meet a user's needs? Service Catalog works well for well-understood, standardized use cases but can become a bottleneck when requirements are unique or rapidly changing.

#### Instructor notes

#### Student notes

This diagram shows the initial workflow

for a user.

:::

### Slide 43:

![Slide 43](slide_43.png)

::: Notes


#### Instructor notes

#### Student notes

:::

### Slide 44:

![Slide 44](slide_44.png)

::: Notes


#### Instructor notes

#### Student notes

:::

### Slide 45:

![Slide 45](slide_45.png)

::: Notes


#### Instructor notes

#### Student notes

:::

### Slide 46:

![Slide 46](slide_46.png)

::: Notes

CloudFormation error messages are sometimes clear and sometimes cryptic — the stack events view gives you the high-level sequence, but the actual error may be buried in service-specific logs or deep in cfn log files on the instance. Having a systematic approach to troubleshooting — check stack events first, then instance logs, then service-specific logs — saves significant time. Ask students: where would they look first if a stack failed during an EC2 instance bootstrapping step?

#### Instructor notes

#### Student notes

If CloudFormation fails to create, update, or delete your stack, you can view error messages or logs to help you learn more about the issue. For more information, see "Troubleshooting CloudFormation" in the AWS CloudFormation User Guide at http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/troubleshooting.html.

:::

### Slide 47:

![Slide 47](slide_47.png)

::: Notes

This specific error — `TemplateURL must reference a valid Amazon S3 bucket` — appears when a CloudFormation template is referenced via URL but the S3 bucket doesn't exist, is in the wrong region, or isn't accessible. It's a common misconfiguration that produces a confusing error message because the problem is with the template location, not the template content. When troubleshooting this error, verify bucket existence, region, and the caller's S3 permissions.

#### Instructor notes

#### Student notes

The error, "TemplateURL must reference a valid Amazon S3 bucket," is generated when using an Amazon S3 reference in a CloudFormation template.

:::

### Slide 48:

![Slide 48](slide_48.png)

::: Notes


#### Instructor notes

#### Student notes

:::

### Slide 49:

![Slide 49](slide_49.png)

::: Notes


#### Instructor notes

#### Student notes

:::

### Slide 50:

![Slide 50](slide_50.png)

::: Notes


#### Instructor notes

#### Student notes

:::

### Slide 51:

![Slide 51](slide_51.png)

::: Notes


#### Instructor notes

#### Student notes

:::

### Slide 52:

![Slide 52](slide_52.png)

::: Notes

This lab gives hands-on experience with the CloudFormation workflow: launching a stack, modifying the template visually, updating the stack with changes, and detecting drift. The progression from launch to drift detection mirrors a real operational workflow. Encourage students to think about what governance mechanisms they would put in place to detect and respond to drift in a production environment where multiple teams have access.

#### Instructor notes

#### Student notes

This lab will take you through the following process:

* Launching a CloudFormation stack from an existing CloudFormation template
* Modifying a CloudFormation template with AWS CloudFormation Designer
* Updating an existing stack with changes
* Tagging resources and grouping them into resource groups
* Detecting drift in a stack
* Adding tags values to a CloudFormation template

:::

### Slide 53:

![Slide 53](slide_53.png)

::: Notes


#### Instructor notes

#### Student notes

:::
