> For the complete documentation index, see [llms.txt](https://developer.harness.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://developer.harness.io/continuous-delivery/use-continuous-delivery/provision-infrastructure/cloudformation-infra/cloud-formation-provisioning-with-harness.md).

# CloudFormation provisioning

Harness supports [AWS CloudFormation](https://aws.amazon.com/cloudformation/) as an infrastructure provisioner. You can use CloudFormation templates to provision AWS resources as part of your deployment process.

Harness can provision any AWS resource that is supported by CloudFormation. You can use CloudFormation to provision infrastructure for deployments or to provision any AWS resources on demand.

***

### What you will learn from this topic <a href="#what-you-will-learn-from-this-topic" id="what-you-will-learn-from-this-topic"></a>

* How to understand the [supported deployment types and provisioning modes](#supported-deployment-types-and-modes) for CloudFormation provisioning.
* How to choose between [ad hoc provisioning](#ad-hoc-provisioning) and [dynamic provisioning](#dynamic-provisioning) for CloudFormation.
* How to use CloudFormation steps to [create](#cloudformation-steps), [delete](#cloudformation-steps), and [rollback](#cloudformation-steps) stacks in your pipelines.
* How to configure [complete pipeline examples](#pipeline-examples) for both ad hoc and dynamic provisioning modes.

***

### Supported deployment types and modes <a href="#supported-deployment-types-and-modes" id="supported-deployment-types-and-modes"></a>

* Harness CloudFormation provisioning is supported in the following deployment types:
  * Basic
  * Canary
  * Blue-Green
* Harness can provision any AWS resource that is supported by CloudFormation.
* CloudFormation templates must be in JSON or YAML format.

{% hint style="info" %}
**SERVICE INSTANCE LICENSING**

Harness does not consume Service Instances (SIs) when you use CloudFormation for infrastructure provisioning alone, so you can provision infrastructure at no additional licensing cost. SI licensing applies only when Harness deploys an application to the provisioned infrastructure in the same stage or pipeline.
{% endhint %}

{% hint style="info" %}
**AWS OIDC CONNECTOR SUPPORT**

CloudFormation provisioning supports AWS connectors with OIDC authentication. This requires Delegate version `854xx` or later. For more information, refer to [AWS connector settings reference](/harness-ai/use-harness-platform/connectors/cloud-providers/ref-cloud-providers/aws-connector-settings-reference.md).
{% endhint %}

***

### Before you begin <a href="#before-you-begin" id="before-you-begin"></a>

* **Harness project access:** View, Create/Edit, and Execute permissions on Pipelines, Environments, and Infrastructure Definitions. For more information, refer to [RBAC in Harness](/harness-platform/3.0/harness-platform-resources/platform-access-control/rbac-in-harness.md) to configure roles.
* **AWS connector:** A Harness AWS connector with permissions to provision resources in your target AWS account. For more information, refer to [AWS connector settings reference](/harness-ai/use-harness-platform/connectors/cloud-providers/ref-cloud-providers/aws-connector-settings-reference.md) to configure the connector and review required AWS IAM roles for CloudFormation provisioning.
* **Harness Delegate:** A delegate installed in an environment that can connect to AWS. For more information, refer to [Delegate installation overview](/harness-ai/use-harness-platform/delegates/delegate/install-delegates/overview.md) to install a delegate.
* **CloudFormation template:** A JSON or YAML CloudFormation template that defines the AWS resources to provision.

***

### Provisioning modes <a href="#provisioning-modes" id="provisioning-modes"></a>

Harness supports two CloudFormation provisioning modes:

* [Ad hoc provisioning](#ad-hoc-provisioning): Provision infrastructure as a standalone task without deploying an application in the same flow.
* [Dynamic provisioning](#dynamic-provisioning): Provision the target infrastructure and deploy your application to it in the same stage.

The pipeline steps are configured the same way for both modes. Choose the mode that matches your goal: use ad hoc provisioning to manage infrastructure on its own, and dynamic provisioning to provision and deploy in one stage.

For more information, refer to [Provisioning overview](/continuous-delivery/use-continuous-delivery/provision-infrastructure/provisioning-overview.md) to understand Harness provisioning concepts and use cases.

#### Ad hoc provisioning <a href="#ad-hoc-provisioning" id="ad-hoc-provisioning"></a>

Ad hoc provisioning lets you provision infrastructure as a standalone workflow without deploying an application in the same flow. This mode is useful to create test environments, set up shared resources, or make infrastructure changes independently of application deployments.

For ad hoc provisioning, add the CloudFormation Create Stack step to the **Execution** section of a CD Deploy stage. The step provisions your resources when the stage runs.

```mermaid
flowchart TD
    subgraph stage["Execution section"]
        direction TB
        A["CloudFormation template
+ parameters"] --> B["CloudFormation Create
Stack step"]
        B --> C["Standalone
infrastructure
provisioned"]
    end
```

Example use cases:

* Provision a shared AWS VPC, subnets, and security groups that other pipelines consume.
* Stand up a temporary test environment for validation, then destroy it in a later step.
* Run a one-time infrastructure change defined in a CloudFormation template.

#### Dynamic provisioning <a href="#dynamic-provisioning" id="dynamic-provisioning"></a>

For dynamic provisioning, add the CloudFormation Create Stack step to the **Environment** section of a CD Deploy stage and map the CloudFormation stack outputs to the Infrastructure Definition. Harness then deploys your application to the provisioned infrastructure in the same stage.

```mermaid
flowchart TD
    subgraph stage["Environment section"]
        direction TB
        A["CloudFormation template
+ parameters"] --> B["CloudFormation Create
Stack step"]
        B --> C["Map stack outputs
to Infrastructure
Definition"]
        C --> D["Deploy application
to provisioned
infrastructure"]
    end
```

Example use cases:

* Provision an AWS EC2 instance and deploy your application to it in a single pipeline.
* Create ephemeral AWS resources per pull request, deploy to them, and tear them down afterward.

For detailed steps on configuring dynamic provisioning, refer to [Provision target deployment infrastructure dynamically with CloudFormation](/continuous-delivery/use-continuous-delivery/provision-infrastructure/cloudformation-infra/provision-target-deployment-infra-dynamically-with-cloud-formation.md).

***

### CloudFormation steps <a href="#cloudformation-steps" id="cloudformation-steps"></a>

Harness provides the following CloudFormation steps for your CD pipelines:

* **CloudFormation Create Stack:** Provisions AWS resources using a CloudFormation template. For more information, refer to [Provision with the CloudFormation Create Stack step](/continuous-delivery/use-continuous-delivery/provision-infrastructure/cloudformation-infra/provision-with-the-cloud-formation-create-stack-step.md).
* **CloudFormation Delete Stack:** Deletes a CloudFormation stack to clean up provisioned resources. For more information, refer to [Remove provisioned infrastructure with the CloudFormation Delete step](/continuous-delivery/use-continuous-delivery/provision-infrastructure/cloudformation-infra/remove-provisioned-infra-with-the-cloud-formation-delete-step.md).
* **CloudFormation Rollback Stack:** Rolls back a CloudFormation stack to the last successfully provisioned version. For more information, refer to [Rollback provisioned infrastructure with the CloudFormation Rollback step](/continuous-delivery/use-continuous-delivery/provision-infrastructure/cloudformation-infra/rollback-provisioned-infra-with-the-cloud-formation-rollback-step.md).

***

### Pipeline examples <a href="#pipeline-examples" id="pipeline-examples"></a>

The following examples show complete pipeline YAML for ad hoc provisioning and dynamic provisioning using CloudFormation.

#### Ad hoc provisioning example <a href="#ad-hoc-provisioning-example" id="ad-hoc-provisioning-example"></a>

This example provisions infrastructure using CloudFormation without deploying an application. The CloudFormation Create Stack step is in the **Execution** section of the stage.

<details>

<summary>Ad hoc provisioning pipeline YAML</summary>

```yaml
# CloudFormation Ad Hoc Provisioning Pipeline <a href="#cloudformation-ad-hoc-provisioning-pipeline" id="cloudformation-ad-hoc-provisioning-pipeline"></a>
# This pipeline demonstrates ad hoc provisioning: CloudFormation provisions infrastructure <a href="#this-pipeline-demonstrates-ad-hoc-provisioning-cloudformation-provisions-infrastructure" id="this-pipeline-demonstrates-ad-hoc-provisioning-cloudformation-provisions-infrastructure"></a>
# as a standalone task in the Execution section without deploying an application. <a href="#as-a-standalone-task-in-the-execution-section-without-deploying-an-application" id="as-a-standalone-task-in-the-execution-section-without-deploying-an-application"></a>

pipeline:
  name: CloudFormation Ad Hoc Provisioning
  identifier: CloudFormation_Ad_Hoc_Provisioning
  projectIdentifier: your_project  # Replace with your project identifier
  orgIdentifier: default
  tags:
    provisioner: cloudformation

  # Pipeline variables for CloudFormation stack configuration
  variables:
    - name: stack_name
      type: String
      description: CloudFormation stack name
      required: true
      value: my-adhoc-stack
    - name: aws_region
      type: String
      description: AWS Region for stack deployment
      required: true
      value: us-east-2

  stages:
    - stage:
        name: Provision Infrastructure
        identifier: Provision_Infrastructure
        description: Ad hoc CloudFormation provisioning in Deploy stage
        type: Deployment
        spec:
          deploymentType: AwsLambda
          service:
            serviceRef: your_service         # Replace with your service reference
            serviceInputs:
              serviceDefinition:
                type: AwsLambda
                spec:
                  artifacts:
                    primary:
                      primaryArtifactRef: <+input>
                      sources: <+input>

          environment:
            environmentRef: your_environment  # Replace with your environment reference
            deployToAll: false
            infrastructureDefinitions:
              - identifier: your_infrastructure  # Replace with your infrastructure definition

          # Execution section: CloudFormation steps run here for ad hoc provisioning
          execution:
            steps:
              # Step 1: Create CloudFormation Stack
              - step:
                  type: CreateStack           # CloudFormation Create Stack step type
                  name: Create S3 Bucket Stack
                  identifier: Create_Stack
                  spec:
                    # Provisioner Identifier links Create, Delete, and Rollback steps
                    provisionerIdentifier: s3_provisioner
                    configuration:
                      connectorRef: your_aws_connector  # AWS connector reference
                      region: <+pipeline.variables.aws_region>
                      stackName: <+pipeline.variables.stack_name>

                      # Template file configuration - using inline template
                      templateFile:
                        type: Inline           # Options: Inline, S3Url, Git
                        spec:
                          templateBody: |
                            AWSTemplateFormatVersion: '2010-09-09'
                            Description: Ad hoc S3 bucket provisioning example

                            # CloudFormation Resources section
                            Resources:
                              S3Bucket:
                                Type: AWS::S3::Bucket
                                Properties:
                                  BucketName: !Sub 'my-bucket-${AWS::AccountId}'
                                  Tags:
                                    - Key: ManagedBy
                                      Value: Harness
                                    - Key: Purpose
                                      Value: AdHoc-Provisioning

                            # Outputs section: Required for Harness to access CloudFormation stack outputs
                            Outputs:
                              BucketName:
                                Description: Name of the S3 bucket
                                Value: !Ref S3Bucket
                              BucketArn:
                                Description: ARN of the S3 bucket
                                Value: !GetAtt S3Bucket.Arn
                              Region:
                                Description: AWS Region
                                Value: !Ref AWS::Region
                  timeout: 10m

              # Step 2: Display CloudFormation Stack Outputs
              - step:
                  type: ShellScript
                  name: Display Stack Outputs
                  identifier: Display_Stack_Outputs
                  spec:
                    shell: Bash
                    executionTarget: {}
                    source:
                      type: Inline
                      spec:
                        script: |
                          echo "=========================================="
                          echo "CloudFormation Stack Outputs"
                          echo "=========================================="
                          echo "Stack Name:    <+pipeline.variables.stack_name>"
                          echo "Region:        <+pipeline.variables.aws_region>"
                          echo ""
                          echo "=== CloudFormation Outputs ==="
                          # Ad hoc provisioning expression format:
                          # <+pipeline.stages.STAGE_ID.spec.execution.steps.STEP_ID.output.OUTPUT_NAME>
                          echo "Bucket Name:   <+pipeline.stages.Provision_Infrastructure.spec.execution.steps.Create_Stack.output.BucketName>"
                          echo "Bucket ARN:    <+pipeline.stages.Provision_Infrastructure.spec.execution.steps.Create_Stack.output.BucketArn>"
                          echo "Region:        <+pipeline.stages.Provision_Infrastructure.spec.execution.steps.Create_Stack.output.Region>"
                          echo "=========================================="
                  timeout: 10m

              # Step 3: Delete CloudFormation Stack
              - step:
                  type: DeleteStack           # CloudFormation Delete Stack step type
                  name: Delete S3 Bucket Stack
                  identifier: Delete_Stack
                  spec:
                    configuration:
                      type: Inline             # Options: Inline, InheritFromCreate
                      spec:
                        connectorRef: your_aws_connector
                        region: <+pipeline.variables.aws_region>
                        stackName: <+pipeline.variables.stack_name>
                      connectorRef: your_aws_connector  # Required at configuration level
                  timeout: 10m

            # Rollback steps: Execute if any step in execution fails
            rollbackSteps:
              - step:
                  type: RollbackStack         # CloudFormation Rollback Stack step type
                  name: Rollback Stack
                  identifier: Rollback_Stack
                  spec:
                    configuration:
                      # Must match the Create Stack provisionerIdentifier
                      provisionerIdentifier: s3_provisioner
                  timeout: 10m

        tags: {}
        failureStrategies:
          - onFailure:
              errors:
                - AllErrors
              action:
                type: StageRollback  # Triggers rollback steps on failure
```

</details>

#### Dynamic provisioning example <a href="#dynamic-provisioning-example" id="dynamic-provisioning-example"></a>

This example provisions infrastructure using CloudFormation in the **Environment** section. CloudFormation stack outputs are accessible in execution steps. The application is then deployed to the provisioned infrastructure in the **Execution** section.

{% hint style="info" %}
**CLOUDFORMATION DYNAMIC PROVISIONING LIMITATIONS**

CloudFormation does **not** automatically map stack outputs to infrastructure definition fields (unlike AWS CDK). Infrastructure definitions must be pre-configured in the environment. CloudFormation outputs are accessible in execution steps via expressions.
{% endhint %}

<details>

<summary>Dynamic provisioning pipeline YAML</summary>

```yaml
# CloudFormation Dynamic Provisioning Pipeline - Working Example <a href="#cloudformation-dynamic-provisioning-pipeline-working-example" id="cloudformation-dynamic-provisioning-pipeline-working-example"></a>
# This pipeline demonstrates dynamic provisioning: CloudFormation provisions infrastructure <a href="#this-pipeline-demonstrates-dynamic-provisioning-cloudformation-provisions-infrastructure" id="this-pipeline-demonstrates-dynamic-provisioning-cloudformation-provisions-infrastructure"></a>
# in the environment.provisioner section, and CloudFormation outputs are accessible in execution steps. <a href="#in-the-environmentprovisioner-section-and-cloudformation-outputs-are-accessible-in-execution-steps" id="in-the-environmentprovisioner-section-and-cloudformation-outputs-are-accessible-in-execution-steps"></a>

pipeline:
  name: CloudFormation Dynamic Provisioning
  identifier: CloudFormation_Dynamic_Provisioning
  projectIdentifier: your_project  # Replace with your project identifier
  orgIdentifier: default
  tags:
    provisioner: cloudformation

  # Pipeline variables for CloudFormation stack configuration
  variables:
    - name: stack_name
      type: String
      value: my-dynamic-stack
    - name: aws_region
      type: String
      value: us-east-2

  stages:
    - stage:
        name: Dynamic Provision and Deploy
        identifier: Dynamic_Provision_Deploy
        type: Deployment
        spec:
          deploymentType: AwsLambda
          service:
            serviceRef: your_service         # Replace with your service reference
            serviceInputs:
              serviceDefinition:
                type: AwsLambda
                spec:
                  artifacts:
                    primary:
                      primaryArtifactRef: <+input>
                      sources: <+input>

          # Environment configuration with provisioner section
          # This is where "dynamic provisioning" happens - CloudFormation runs BEFORE execution
          environment:
            environmentRef: your_environment  # Replace with your environment reference
            deployToAll: false

            # PROVISIONER SECTION: CloudFormation runs here (before execution section)
            # This is the key difference between ad hoc and dynamic provisioning
            provisioner:
              steps:
                # CloudFormation Create Stack step
                - step:
                    type: CreateStack                      # CloudFormation Create Stack step type
                    name: Create Lambda Infrastructure
                    identifier: Create_Stack               # Used in expressions to reference outputs
                    timeout: 10m
                    spec:
                      # Provisioner Identifier: Links Create Stack and Rollback Stack
                      provisionerIdentifier: lambda_provisioner

                      configuration:
                        connectorRef: your_aws_connector             # AWS connector reference
                        region: <+pipeline.variables.aws_region>     # AWS region for stack deployment
                        stackName: <+pipeline.variables.stack_name>  # CloudFormation stack name

                        # CloudFormation template configuration
                        templateFile:
                          type: Inline  # Options: Inline, S3Url, Git
                          spec:
                            templateBody: |
                              AWSTemplateFormatVersion: '2010-09-09'
                              Description: Dynamic Lambda infrastructure provisioning

                              # Parameters allow runtime configuration
                              Parameters:
                                EnvironmentStage:
                                  Type: String
                                  Default: dev
                                  Description: Environment stage name

                              # CloudFormation Resources section
                              Resources:
                                LambdaExecutionRole:
                                  Type: AWS::IAM::Role
                                  Properties:
                                    AssumeRolePolicyDocument:
                                      Version: '2012-10-17'
                                      Statement:
                                        - Effect: Allow
                                          Principal:
                                            Service: lambda.amazonaws.com
                                          Action: sts:AssumeRole
                                    ManagedPolicyArns:
                                      - arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
                                    Tags:
                                      - Key: ManagedBy
                                        Value: Harness

                              # Outputs section: REQUIRED to access CloudFormation stack values in Harness
                              # These outputs become available in execution steps via expressions
                              Outputs:
                                Region:
                                  Description: AWS Region for Lambda deployment
                                  Value: !Ref AWS::Region
                                Stage:
                                  Description: Environment stage
                                  Value: !Ref EnvironmentStage
                                RoleArn:
                                  Description: Lambda execution role ARN
                                  Value: !GetAtt LambdaExecutionRole.Arn

              # Rollback steps: Execute if Create Stack or any Execution step fails
              rollbackSteps:
                - step:
                    type: RollbackStack                    # CloudFormation Rollback Stack step type
                    name: Rollback Lambda Infrastructure
                    identifier: Rollback_Stack
                    timeout: 10m
                    spec:
                      configuration:
                        # Must match the Create Stack provisionerIdentifier
                        provisionerIdentifier: lambda_provisioner

            # Infrastructure Definition: References pre-configured infrastructure in the environment
            # IMPORTANT: For CloudFormation, the infrastructure definition must be stored in the
            # environment and cannot be dynamically mapped from CloudFormation outputs
            infrastructureDefinitions:
              - identifier: your_infrastructure  # Must match infrastructure definition ID in environment

          # EXECUTION SECTION: Runs AFTER infrastructure is provisioned
          # At this point, CloudFormation stack is already created
          execution:
            steps:
              # Display provisioned infrastructure details
              - step:
                  type: ShellScript
                  name: Display Provisioned Infrastructure
                  identifier: Display_Provisioned_Infrastructure
                  timeout: 10m
                  spec:
                    shell: Bash
                    executionTarget: {}
                    source:
                      type: Inline
                      spec:
                        script: |
                          echo "=========================================="
                          echo "CloudFormation Dynamic Provisioning"
                          echo "=========================================="
                          echo ""
                          echo "=== CloudFormation Outputs (from provisioner) ==="
                          # Dynamic provisioning expression format for Execution section:
                          # <+stage.spec.provisioner.steps.STEP_ID.output.OUTPUT_NAME>
                          echo "Region:    <+stage.spec.provisioner.steps.Create_Stack.output.Region>"
                          echo "Stage:     <+stage.spec.provisioner.steps.Create_Stack.output.Stage>"
                          echo "Role ARN:  <+stage.spec.provisioner.steps.Create_Stack.output.RoleArn>"
                          echo ""
                          echo "=== Infrastructure Definition ==="
                          echo "Infra Name: <+infra.name>"
                          echo "Infra ID:   <+infra.identifier>"
                          echo "Connector:  <+infra.connectorRef>"
                          echo "Region:     <+infra.region>"
                          echo ""
                          echo "=== Pipeline Execution ==="
                          echo "Stack Name:    <+pipeline.variables.stack_name>"
                          echo "Pipeline:      <+pipeline.name>"
                          echo "Execution ID:  <+pipeline.executionId>"
                          echo "=========================================="

            rollbackSteps: []

        failureStrategies:
          - onFailure:
              errors:
                - AllErrors
              action:
                type: StageRollback  # Triggers provisioner rollback steps on failure
```

</details>

***

### Next steps <a href="#next-steps" id="next-steps"></a>

* [Provision target deployment infrastructure dynamically with CloudFormation](/continuous-delivery/use-continuous-delivery/provision-infrastructure/cloudformation-infra/provision-target-deployment-infra-dynamically-with-cloud-formation.md): Configure dynamic provisioning to create infrastructure at runtime.
* [Kubernetes deployments](/continuous-delivery/use-continuous-delivery/deploy-services-on-different-platforms/kubernetes/kubernetes-deployments-overview.md): Deploy applications to Kubernetes infrastructure provisioned with CloudFormation.
* [Provisioning overview](/continuous-delivery/use-continuous-delivery/provision-infrastructure/provisioning-overview.md): Understand Harness provisioning concepts across all cloud providers.
