> ## Documentation Index
> Fetch the complete documentation index at: https://notes.kodekloud.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Demo Creating a pipeline for continuous delivery

> Guide to build a CodePipeline that deploys a CloudFormation template from S3 to provision an EC2 instance.

This walkthrough shows how to build a simple continuous-delivery pipeline that deploys a CloudFormation template stored in S3. The pipeline uses CodePipeline as the orchestrator and CloudFormation as the deploy provider. End result: CodePipeline pulls a ZIP artifact from S3, CloudFormation extracts the template inside the ZIP, and CloudFormation creates the resources (an EC2 instance in this demo).

What you'll do in this demo:

* Create an S3 bucket (with versioning enabled) to store CloudFormation artifacts.
* Upload a zipped CloudFormation template to S3.
* Create an IAM role CloudFormation can assume to provision resources.
* Create a CodePipeline that uses the S3 artifact as Source and CloudFormation as Deploy.
* Verify the resulting CloudFormation stack and EC2 instance.

Step-by-step details follow.

## 1 — Create an S3 bucket for pipeline artifacts

Create a dedicated bucket to hold CloudFormation templates/artifacts. CodePipeline benefits from object versioning so it can reference specific object versions for each release.

<Frame>
  <img src="https://mintcdn.com/kodekloud-c4ac6d9a/PAkNjEHEmrNfcejz/images/AWS-CloudFormation/Automation-and-Integration/Demo-Creating-a-pipeline-for-continuous-delivery/aws-s3-create-bucket-eden-kodekloud.jpg?fit=max&auto=format&n=PAkNjEHEmrNfcejz&q=85&s=6b41a1e3c4daf5eaedb615988ce6310b" alt="A screenshot of the AWS S3 &#x22;Create bucket&#x22; console showing the &#x22;General purpose&#x22; bucket type selected and a bucket name field filled with &#x22;eden-kodekloud-kjhl-templa&#x22;. The page also shows an option to copy settings from an existing bucket and a &#x22;Choose bucket&#x22; button." width="1920" height="1080" data-path="images/AWS-CloudFormation/Automation-and-Integration/Demo-Creating-a-pipeline-for-continuous-delivery/aws-s3-create-bucket-eden-kodekloud.jpg" />
</Frame>

Enable versioning on the bucket before using it as a pipeline source.

<Frame>
  <img src="https://mintcdn.com/kodekloud-c4ac6d9a/PAkNjEHEmrNfcejz/images/AWS-CloudFormation/Automation-and-Integration/Demo-Creating-a-pipeline-for-continuous-delivery/s3-create-bucket-versioning-enabled-screenshot.jpg?fit=max&auto=format&n=PAkNjEHEmrNfcejz&q=85&s=4a7d975936e3194c2fa7b0e75064975a" alt="A screenshot of the Amazon S3 &#x22;Create bucket&#x22; console showing the Bucket Versioning section with the &#x22;Enable&#x22; option selected. The Tags (optional) section is visible below along with the console header and navigation." width="1920" height="1080" data-path="images/AWS-CloudFormation/Automation-and-Integration/Demo-Creating-a-pipeline-for-continuous-delivery/s3-create-bucket-versioning-enabled-screenshot.jpg" />
</Frame>

After creating the bucket, open it and confirm it is empty (ready for upload).

<Frame>
  <img src="https://mintcdn.com/kodekloud-c4ac6d9a/PAkNjEHEmrNfcejz/images/AWS-CloudFormation/Automation-and-Integration/Demo-Creating-a-pipeline-for-continuous-delivery/s3-console-empty-bucket-eden-templates.jpg?fit=max&auto=format&n=PAkNjEHEmrNfcejz&q=85&s=c4162fa49d76d6e13e0363a52ae4032b" alt="A screenshot of the Amazon S3 console for the bucket &#x22;eden-kodekloud-kjhl-templates,&#x22; showing the Objects tab with a message saying there are no objects. The UI displays controls like Upload, Create folder, Actions, Copy S3 URI, and a search/filter field." width="1920" height="1080" data-path="images/AWS-CloudFormation/Automation-and-Integration/Demo-Creating-a-pipeline-for-continuous-delivery/s3-console-empty-bucket-eden-templates.jpg" />
</Frame>

## 2 — Prepare and upload the CloudFormation artifact

For this demo we use a minimal CloudFormation template that creates a single EC2 instance. Save this content as simple-ec2.yaml:

```yaml theme={null}
Resources:
  MyInstance:
    Type: AWS::EC2::Instance
    Properties:
      InstanceType: t3.small
      ImageId: ami-0eb9d6fc9fab44d24
```

Zip the template (for example: simple-ec2.zip). The pipeline Source artifact will be the ZIP file uploaded to S3.

<Frame>
  <img src="https://mintcdn.com/kodekloud-c4ac6d9a/PAkNjEHEmrNfcejz/images/AWS-CloudFormation/Automation-and-Integration/Demo-Creating-a-pipeline-for-continuous-delivery/cf-project-cloudformation-templates-explorer.jpg?fit=max&auto=format&n=PAkNjEHEmrNfcejz&q=85&s=43a292e89b951ddd34efae4a75dbac8a" alt="A Windows File Explorer window in dark mode showing the &#x22;cf-project&#x22; folder. The right pane lists CloudFormation-related YAML/JSON files (e.g., simple-ec2, s3-bucket, cfn-init) while the left pane shows common folders and navigation." width="1920" height="1080" data-path="images/AWS-CloudFormation/Automation-and-Integration/Demo-Creating-a-pipeline-for-continuous-delivery/cf-project-cloudformation-templates-explorer.jpg" />
</Frame>

Upload the ZIP to your S3 bucket. After upload you should see the file listed, e.g. simple-ec2.zip.

<Frame>
  <img src="https://mintcdn.com/kodekloud-c4ac6d9a/PAkNjEHEmrNfcejz/images/AWS-CloudFormation/Automation-and-Integration/Demo-Creating-a-pipeline-for-continuous-delivery/aws-s3-upload-succeeded-simple-ec2.jpg?fit=max&auto=format&n=PAkNjEHEmrNfcejz&q=85&s=aae343e0ab31a93396d74bb37d4f8695" alt="A screenshot of the AWS S3 console showing a successful upload to the bucket s3://eden-kodekloud-kjhl-templates. The file &#x22;simple-ec2.zip&#x22; (304.0 B) is listed in the Files and folders pane with status &#x22;Succeeded.&#x22;" width="1920" height="1080" data-path="images/AWS-CloudFormation/Automation-and-Integration/Demo-Creating-a-pipeline-for-continuous-delivery/aws-s3-upload-succeeded-simple-ec2.jpg" />
</Frame>

## 3 — Create an IAM role CloudFormation can assume

CloudFormation needs an execution role to create resources on your behalf. Create an IAM role with a trust policy allowing CloudFormation to assume the role, and attach the required policies (for this demo we attach CloudFormation and EC2 full access).

Open IAM and create a new role:

* Trusted entity: AWS service
* Use case: CloudFormation

<Frame>
  <img src="https://mintcdn.com/kodekloud-c4ac6d9a/PAkNjEHEmrNfcejz/images/AWS-CloudFormation/Automation-and-Integration/Demo-Creating-a-pipeline-for-continuous-delivery/aws-iam-create-role-aws-service.jpg?fit=max&auto=format&n=PAkNjEHEmrNfcejz&q=85&s=ac67767b75b6f3e48d3bdd861b1dacdb" alt="A screenshot of the AWS IAM &#x22;Create role&#x22; page showing the Trusted entity type options with &#x22;AWS service&#x22; selected. The browser tabs and Windows taskbar are also visible." width="1920" height="1080" data-path="images/AWS-CloudFormation/Automation-and-Integration/Demo-Creating-a-pipeline-for-continuous-delivery/aws-iam-create-role-aws-service.jpg" />
</Frame>

Proceed to Add permissions and attach the managed policies needed for CloudFormation to create EC2 instances (example policies: AWSCloudFormationFullAccess, AmazonEC2FullAccess).

<Frame>
  <img src="https://mintcdn.com/kodekloud-c4ac6d9a/PAkNjEHEmrNfcejz/images/AWS-CloudFormation/Automation-and-Integration/Demo-Creating-a-pipeline-for-continuous-delivery/aws-iam-create-role-cloudformation.jpg?fit=max&auto=format&n=PAkNjEHEmrNfcejz&q=85&s=3526a124993bb66b1d4948bb9079d0e2" alt="A screenshot of the AWS IAM &#x22;Create role&#x22; console showing the &#x22;Use case&#x22; section with CloudFormation selected as the service/use case. The page shows the CloudFormation radio option, a dropdown for Service or use case, and Cancel/Next buttons." width="1920" height="1080" data-path="images/AWS-CloudFormation/Automation-and-Integration/Demo-Creating-a-pipeline-for-continuous-delivery/aws-iam-create-role-cloudformation.jpg" />
</Frame>

Search and select the appropriate managed policies.

<Frame>
  <img src="https://mintcdn.com/kodekloud-c4ac6d9a/PAkNjEHEmrNfcejz/images/AWS-CloudFormation/Automation-and-Integration/Demo-Creating-a-pipeline-for-continuous-delivery/aws-iam-create-role-cloudformation-search.jpg?fit=max&auto=format&n=PAkNjEHEmrNfcejz&q=85&s=d4a6e32304e7ba3731e12d0be6b85f45" alt="A screenshot of the AWS IAM console on the &#x22;Create role&#x22; -> &#x22;Add permissions&#x22; step, showing the &#x22;Permissions policies&#x22; list with a search for &#x22;CloudFo&#x22; and several AWS-managed policies (like AWSCloudFormation) listed. The browser window and taskbar are visible at the top and bottom of the screen." data-og-width="1920" width="1920" data-og-height="1080" height="1080" data-path="images/AWS-CloudFormation/Automation-and-Integration/Demo-Creating-a-pipeline-for-continuous-delivery/aws-iam-create-role-cloudformation-search.jpg" data-optimize="true" data-opv="3" srcset="https://mintcdn.com/kodekloud-c4ac6d9a/PAkNjEHEmrNfcejz/images/AWS-CloudFormation/Automation-and-Integration/Demo-Creating-a-pipeline-for-continuous-delivery/aws-iam-create-role-cloudformation-search.jpg?w=280&fit=max&auto=format&n=PAkNjEHEmrNfcejz&q=85&s=48f2792e778072148caa2dfc9d90baff 280w, https://mintcdn.com/kodekloud-c4ac6d9a/PAkNjEHEmrNfcejz/images/AWS-CloudFormation/Automation-and-Integration/Demo-Creating-a-pipeline-for-continuous-delivery/aws-iam-create-role-cloudformation-search.jpg?w=560&fit=max&auto=format&n=PAkNjEHEmrNfcejz&q=85&s=e9fb44167b26b84d4eacbf206b3b95bd 560w, https://mintcdn.com/kodekloud-c4ac6d9a/PAkNjEHEmrNfcejz/images/AWS-CloudFormation/Automation-and-Integration/Demo-Creating-a-pipeline-for-continuous-delivery/aws-iam-create-role-cloudformation-search.jpg?w=840&fit=max&auto=format&n=PAkNjEHEmrNfcejz&q=85&s=24b9773c499bff3ce626ede59bae6d9e 840w, https://mintcdn.com/kodekloud-c4ac6d9a/PAkNjEHEmrNfcejz/images/AWS-CloudFormation/Automation-and-Integration/Demo-Creating-a-pipeline-for-continuous-delivery/aws-iam-create-role-cloudformation-search.jpg?w=1100&fit=max&auto=format&n=PAkNjEHEmrNfcejz&q=85&s=b0627de23346abeb732be2f265022211 1100w, https://mintcdn.com/kodekloud-c4ac6d9a/PAkNjEHEmrNfcejz/images/AWS-CloudFormation/Automation-and-Integration/Demo-Creating-a-pipeline-for-continuous-delivery/aws-iam-create-role-cloudformation-search.jpg?w=1650&fit=max&auto=format&n=PAkNjEHEmrNfcejz&q=85&s=726dbbba9f9ad2910583b358dc55d49d 1650w, https://mintcdn.com/kodekloud-c4ac6d9a/PAkNjEHEmrNfcejz/images/AWS-CloudFormation/Automation-and-Integration/Demo-Creating-a-pipeline-for-continuous-delivery/aws-iam-create-role-cloudformation-search.jpg?w=2500&fit=max&auto=format&n=PAkNjEHEmrNfcejz&q=85&s=a842a0ac776aa1294351e308374e08a3 2500w" />
</Frame>

Give the role a descriptive name (for example: PipelineForCFAndEC2) and an optional description. The role trust policy should allow CloudFormation to assume it; example trust policy:

```json theme={null}
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "",
      "Effect": "Allow",
      "Principal": {
        "Service": "cloudformation.amazonaws.com"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}
```

Create the role when permissions and trust are configured.

<Frame>
  <img src="https://mintcdn.com/kodekloud-c4ac6d9a/PAkNjEHEmrNfcejz/images/AWS-CloudFormation/Automation-and-Integration/Demo-Creating-a-pipeline-for-continuous-delivery/aws-iam-create-role-cloudformation-2.jpg?fit=max&auto=format&n=PAkNjEHEmrNfcejz&q=85&s=f0b76d3cc587d5ef381b6f37313752f1" alt="A browser screenshot of the AWS Management Console showing the IAM &#x22;Create role&#x22; page where a role name &#x22;PipelineForCFAn...&#x22; is being entered and a description about CloudFormation is visible. The left panel shows the step progress (Select trusted entity → Add permissions → Name, review, and create)." width="1920" height="1080" data-path="images/AWS-CloudFormation/Automation-and-Integration/Demo-Creating-a-pipeline-for-continuous-delivery/aws-iam-create-role-cloudformation-2.jpg" />
</Frame>

## 4 — Create the CodePipeline

Open CodePipeline and create a new pipeline (use the wizard and select “Build a custom pipeline”). Choose a name (for example PipelineCF) and decide how to handle the service role (let CodePipeline create a service role or provide an existing role).

<Frame>
  <img src="https://mintcdn.com/kodekloud-c4ac6d9a/PAkNjEHEmrNfcejz/images/AWS-CloudFormation/Automation-and-Integration/Demo-Creating-a-pipeline-for-continuous-delivery/aws-codepipeline-create-pipeline-service-role.jpg?fit=max&auto=format&n=PAkNjEHEmrNfcejz&q=85&s=afc180ac7d79ecad46c9ca132af20dcc" alt="A screenshot of the AWS CodePipeline &#x22;Create new pipeline&#x22; page showing the Service role section with &#x22;New service role&#x22; selected and a role name filled in (AWSCodePipelineServiceRole-us-east-2-PipelineCF). The page also displays an option to let CodePipeline create the role, an &#x22;Advanced settings&#x22; panel, and navigation buttons (Previous, Next)." width="1920" height="1080" data-path="images/AWS-CloudFormation/Automation-and-Integration/Demo-Creating-a-pipeline-for-continuous-delivery/aws-codepipeline-create-pipeline-service-role.jpg" />
</Frame>

Configure pipeline stages:

* Source
  * Provider: Amazon S3
  * Bucket: the bucket you created
  * Object key: the S3 object key for simple-ec2.zip (the ZIP you uploaded)
* Skip Build and Test stages if not required
* Deploy
  * Provider: AWS CloudFormation
  * Region: the region where you want resources created (example: us-east-2)
  * Action mode: Create/Replace stack (or Create stack when creating a new stack)
  * Stack name: choose a name (e.g., DemoStackPipeline)
  * Template file: path inside the ZIP to the template (format: SourceArtifact::simple-ec2.yaml)
  * Role: choose the IAM role you created for CloudFormation (PipelineForCFAndEC2)

Specifying TemplatePath as SourceArtifact::simple-ec2.yaml instructs CloudFormation to extract simple-ec2.yaml from the source ZIP artifact and use it as the stack template.

When you review and create the pipeline, CodePipeline will automatically start the first release: it downloads the ZIP from S3, extracts the template, and triggers CloudFormation.

<Frame>
  <img src="https://mintcdn.com/kodekloud-c4ac6d9a/PAkNjEHEmrNfcejz/images/AWS-CloudFormation/Automation-and-Integration/Demo-Creating-a-pipeline-for-continuous-delivery/aws-codepipeline-create-pipeline-confirmation.jpg?fit=max&auto=format&n=PAkNjEHEmrNfcejz&q=85&s=b8c24f182abfd2d931711a2f0872d17c" alt="A screenshot of the AWS CodePipeline &#x22;Create new pipeline&#x22; confirmation screen showing pipeline details: StackName &#x22;DemoStackPipeline&#x22;, TemplatePath &#x22;SourceArtifact::simple-ec2.yaml&#x22;, the IAM Role ARN, automatic rollback enabled and automatic retry disabled. The browser and Windows taskbar are visible around the console." width="1920" height="1080" data-path="images/AWS-CloudFormation/Automation-and-Integration/Demo-Creating-a-pipeline-for-continuous-delivery/aws-codepipeline-create-pipeline-confirmation.jpg" />
</Frame>

Monitor the pipeline execution in CodePipeline. Both Source and Deploy stages should show success if everything is configured correctly.

<Frame>
  <img src="https://mintcdn.com/kodekloud-c4ac6d9a/PAkNjEHEmrNfcejz/images/AWS-CloudFormation/Automation-and-Integration/Demo-Creating-a-pipeline-for-continuous-delivery/aws-codepipeline-pipelinecf-source-deploy-release.jpg?fit=max&auto=format&n=PAkNjEHEmrNfcejz&q=85&s=9c2f5b49b6f273835715632f7c6c8c2f" alt="A screenshot of the AWS CodePipeline console showing a pipeline named &#x22;PipelineCF&#x22; with Source and Deploy stages (both actions succeeded). The top bar shows controls like Edit, Stop execution, Create trigger, Clone pipeline and an orange &#x22;Release change&#x22; button." width="1920" height="1080" data-path="images/AWS-CloudFormation/Automation-and-Integration/Demo-Creating-a-pipeline-for-continuous-delivery/aws-codepipeline-pipelinecf-source-deploy-release.jpg" />
</Frame>

## 5 — Verify the deployment

* Open CloudFormation and confirm the stack listed with the Stack name you specified.
* Open EC2 and verify an instance exists and is in the running state, matching the properties in simple-ec2.yaml.

If the pipeline completed successfully and CloudFormation created the stack and EC2 instance, the end-to-end pipeline is functioning: CodePipeline pulled the ZIP from S3, CloudFormation used the template inside the ZIP, and resources were provisioned.

## Quick reference: AWS resources used

| Resource       | Purpose                                                   | Example/Notes                                                     |
| -------------- | --------------------------------------------------------- | ----------------------------------------------------------------- |
| S3 bucket      | Store zipped CloudFormation templates/artifacts           | Enable versioning for Source artifact tracking                    |
| IAM role       | CloudFormation execution role (assumed by CloudFormation) | Attach AWSCloudFormationFullAccess and AmazonEC2FullAccess (demo) |
| CodePipeline   | Orchestrates Source → (Build) → Deploy stages             | Source: Amazon S3; Deploy: CloudFormation                         |
| CloudFormation | Creates and manages the stack/resources                   | Template path: SourceArtifact::simple-ec2.yaml                    |

## Tips and troubleshooting

* Ensure S3 bucket versioning is enabled so CodePipeline can reference object versions reliably.
* Confirm the Template file path inside the ZIP matches the TemplatePath you configure in CodePipeline (format: SourceArtifact::file.yaml).
* If stack creation fails, check CloudFormation events and logs for missing permissions or invalid parameters.

<Callout icon="lightbulb" color="#1CB2FE">
  Enable S3 bucket versioning before using the bucket as a pipeline source so CodePipeline can reference and track specific object versions.
</Callout>

<Callout icon="warning" color="#FF6B6B">
  AMI IDs (ImageId) are region-specific. If the AMI in the template is not available in your target region, the CloudFormation stack will fail. Use a region-appropriate AMI or implement a parameterized AMI lookup.
</Callout>

## Links and references

* [AWS CloudFormation User Guide](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/Welcome.html)
* [AWS CodePipeline User Guide](https://docs.aws.amazon.com/codepipeline/latest/userguide/welcome.html)
* [Amazon S3 Versioning](https://docs.aws.amazon.com/AmazonS3/latest/userguide/Versioning.html)
* [IAM Roles for Amazon CloudFormation](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/using-iam-template.html)

That’s it — you now have a continuous-delivery pipeline that deploys a CloudFormation template stored in S3.

<CardGroup>
  <Card title="Watch Video" icon="video" cta="Learn more" href="https://learn.kodekloud.com/user/courses/aws-cloud-formation/module/3ad06612-9246-4700-953b-662d3eace39b/lesson/8da48c60-b5e8-4429-983c-1feb9daac8e4" />
</CardGroup>
