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

# Codepipeline deployment count remediation

### Triage and Remediation

<Tabs>
  <Tab title="Remediation">
    ### Remediation

    <AccordionGroup>
      <Accordion title="Using Console" defaultOpen="true">
        For this finding, there’s nothing to “flip” in a single setting. The AWS managed control **CodePipeline deployment limit should be reviewed** (Config rule: `codepipeline-deployment-limit-check`) is **manual**: you must review how often your pipelines (and underlying CodeBuild projects) deploy and put proper controls in place.

        Below is how to do that for **CodeBuild-based pipelines using the AWS Console**.

        ***

        ### 1. Identify the affected pipeline(s) and CodeBuild project(s)

        1. In the AWS Console, go to **Security Hub**.
        2. In the left menu, choose **Findings**.
        3. Filter:
           * **Product name**: `Security Hub`
           * **Resource type**: `AWS::CodePipeline::Pipeline`
           * **Title / Rule ID** contains: `CodePipeline deployment limit should be reviewed` or `codepipeline-deployment-limit-check`.
        4. Open a finding and note:
           * The **pipeline name**.
           * The **region**.
        5. Go to **CodePipeline** (same region) → find and open the pipeline.
        6. For each **Build** action, note the **CodeBuild project name**.

        ***

        ### 2. Review and control deployment frequency using approvals

        If the issue is that deployments are happening too frequently (e.g., straight to a shared/test/prod environment):

        1. In **CodePipeline**, open the pipeline.
        2. Click **Edit** (top right).
        3. Between the **build** stage and the “risky” stage (e.g., deploy-to-shared, deploy-to-prod), add an approval:
           1. Click **+ Add stage** (or **+ Add action group** in an existing stage).
           2. Name it something like `Manual-Approval` or `Change-Review`.
           3. Choose **Action provider**: `Manual approval`.
           4. Configure:
              * **SNS topic**: an existing topic that notifies approvers, or create one.
              * **Comments** / **URL**: link to your change ticketing system (optional).
           5. Save the action.
        4. Click **Save** at the top, then **Release change** if required to re-run.

        This creates a gate so that not every pipeline execution will automatically deploy.

        ***

        ### 3. Use CodeBuild project settings to avoid excessive or uncontrolled builds

        1. Go to **CodeBuild** → **Build projects** → open the affected project.
        2. Click **Edit**:
           * Confirm that **Environment** settings (privileged mode, IAM role) are appropriate and not allowing overly broad actions in downstream stages that increase deployment risk.
        3. Under **Buildspec** / build commands, ensure you are not:
           * Triggering additional **nested pipelines**.
           * Manually invoking **deployments** to multiple environments from one build in an uncontrolled way.
        4. If necessary, split the build into:
           * One build project for **build and test**.
           * Another separate, more controlled pipeline for **deployment**, with approvals.

        ***

        ### 4. Control triggers so deployments don’t happen too often

        1. In **CodePipeline** → your pipeline → **Edit**.
        2. At the **Source** stage:
           * If using **CloudWatch Events / EventBridge** or **Git webhooks**, consider:
             * Enabling **filtering** (branch, directory).
             * Configuring your repo (GitHub/CodeCommit) to only trigger on specific events.
        3. Or, switch some pipelines to **manual** trigger (click **Release change** on demand instead of on every commit) for non-critical or noisy branches.

        ***

        ### 5. (Optional) Restrict who can start/approve deployments

        1. Go to **IAM** → **Roles / Users**.
        2. Find the role or user groups that:
           * Run the pipeline (`codepipeline` service role).
           * Have **StartPipelineExecution** or **PutApprovalResult** permissions.
        3. Tighten policies so only appropriate users/groups can:
           * Manually start the pipeline.
           * Approve the manual approval steps.

        ***

        ### 6. Mark the finding as addressed (if using Security Hub)

        1. Once you’ve implemented the controls above and are satisfied with the deployment behavior:
           * In **Security Hub → Findings**, open the finding.
           * Set the **Workflow status** to **Resolved**, or add a **note** indicating:
             * What controls you added (manual approval, trigger changes, IAM restrictions).
             * That deployment frequency and limits have been reviewed.

        ***

        In summary, the remediation is to **review how often your CodePipeline+CodeBuild combination can deploy and add gates (approvals, restricted triggers, IAM)** so that deployments are intentionally controlled rather than unconstrained.
      </Accordion>

      <Accordion title="Using CLI">
        For the “CodePipeline Deployment Limit Check Should Be Reviewed” finding, the remediation is **not** a change on a specific CodeBuild project; it’s about making sure you’re not too close to (or exceeding) AWS service quotas for CodePipeline/CodeBuild and cleaning up or increasing those limits.

        Below are step‑by‑step AWS CLI actions you can take to remediate from the CodeBuild side.

        ***

        ## 1. Identify which limit you are close to

        This Trusted Advisor check generally warns when you’re close to CodePipeline/CodeBuild quotas (e.g., number of pipelines, actions, concurrent builds, etc.).

        List relevant CodeBuild quotas via Service Quotas:

        ```bash theme={null}
        aws service-quotas list-service-quotas \
          --service-code codebuild \
          --region <REGION>
        ```

        Common CodeBuild-related quotas include:

        * `CODEBUILD_CONCURRENT_BUILDS`
        * `CODEBUILD_PROJECTS_PER_ACCOUNT`

        Similarly, for CodePipeline (for context):

        ```bash theme={null}
        aws service-quotas list-service-quotas \
          --service-code codepipeline \
          --region <REGION>
        ```

        Locate the quota whose `UsageMetric` or description matches what you’re nearing (e.g., concurrent builds, number of projects, etc.).

        ***

        ## 2. Reduce current usage (clean up unused CodeBuild resources)

        ### 2.1. List all CodeBuild projects

        ```bash theme={null}
        aws codebuild list-projects --region <REGION>
        ```

        Get details to identify unused projects:

        ```bash theme={null}
        aws codebuild batch-get-projects \
          --names project1 project2 ... \
          --region <REGION>
        ```

        ### 2.2. Delete unused projects

        ```bash theme={null}
        aws codebuild delete-project \
          --name <PROJECT_NAME> \
          --region <REGION>
        ```

        Repeat for all obsolete projects.

        ***

        ## 3. Adjust how many builds run concurrently

        If the issue is around concurrent builds or load on CodeBuild:

        ### 3.1. Reduce parallel builds via batch builds or scheduling

        You can reduce parallelism by controlling how many builds are triggered at once (e.g., from CodePipeline or CI system), but directly on a project you can change `timeoutInMinutes`, environment, etc., not the hard limit. From CLI, update project configuration for better queue handling:

        ```bash theme={null}
        aws codebuild update-project \
          --name <PROJECT_NAME> \
          --source <JSON_SOURCE> \
          --artifacts <JSON_ARTIFACTS> \
          --environment <JSON_ENVIRONMENT> \
          --service-role <ROLE_ARN> \
          --region <REGION>
        ```

        (Use the current project config as a template: `aws codebuild batch-get-projects` → edit → `update-project`.)

        The actual **quota** of concurrent builds itself is an account‑level limit, not per project.

        ***

        ## 4. Request a quota increase (if needed)

        If cleanup/optimization isn’t enough, request a higher limit with Service Quotas.

        1. Find the specific quota code:

        ```bash theme={null}
        aws service-quotas list-service-quotas \
          --service-code codebuild \
          --region <REGION> \
          --output table
        ```

        Note the `QuotaCode` for the quota you need to raise (e.g., `L-XXXXXXX`).

        2. Request an increase:

        ```bash theme={null}
        aws service-quotas request-service-quota-increase \
          --service-code codebuild \
          --quota-code <QUOTA_CODE> \
          --desired-value <NEW_NUMERIC_VALUE> \
          --region <REGION>
        ```

        You can then track the request:

        ```bash theme={null}
        aws service-quotas list-requested-service-quota-change-history \
          --service-code codebuild \
          --region <REGION>
        ```

        ***

        ## 5. Re-run/check the finding

        Once you’ve:

        * Deleted unused projects,
        * Reduced parallelism where practical,
        * And/or increased the service quota,

        re‑run your auditing tool (Security Hub / Trusted Advisor / Config integration) or wait for the next evaluation cycle. The “CodePipeline Deployment Limit Check” should move to a passing or informational state once you’re back under safe utilization of the limit.
      </Accordion>

      <Accordion title="Using Python">
        “CodePipeline Deployment Limit Check Should Be Reviewed” is an AWS Config *managed rule* (`CODEPIPELINE_DEPLOYMENT_LIMIT_CHECK`).\
        It flags CodePipelines whose **Deploy stage has no safe deployment limit** (for example, a CodeDeploy action pushing to too many instances at once).

        Below is how to remediate this specifically for **pipelines that use CodeBuild + CodeDeploy**, using Python (`boto3`).

        ***

        ## 1. Understand what you must change

        For pipelines that deploy via **CodeDeploy**, the “deployment limit” is effectively controlled by the **deployment configuration** on the CodeDeploy *deployment group*:

        * `CodeDeployDefault.OneAtATime` – safest (deploy to one instance at a time).
        * `CodeDeployDefault.HalfAtATime` – deploy to 50% at a time.
        * `CodeDeployDefault.AllAtOnce` – deploy to all at once (usually what the Config rule flags as risky).

        So the usual remediation is:

        1. Identify the CodeDeploy deployment groups your pipeline’s Deploy stage uses.
        2. Change those deployment groups to use a safer `deploymentConfigName`
           (typically `CodeDeployDefault.OneAtATime` or a custom config with suitably low percentages).

        CodeBuild itself does not hold the “deployment limit”; it just builds artifacts. The *Deploy* action in CodePipeline (backed by CodeDeploy) does.

        ***

        ## 2. Find noncompliant CodePipelines from AWS Config (Python)

        ```python theme={null}
        import boto3

        config = boto3.client('config')

        def list_noncompliant_pipelines():
            rule_name = 'CODEPIPELINE_DEPLOYMENT_LIMIT_CHECK'
            paginator = config.get_paginator('get_compliance_details_by_config_rule')

            noncompliant_arns = set()

            for page in paginator.paginate(
                ConfigRuleName=rule_name,
                ComplianceTypes=['NON_COMPLIANT']
            ):
                for result in page['EvaluationResults']:
                    arn = result['EvaluationResultIdentifier']['EvaluationResultQualifier']['ResourceId']
                    noncompliant_arns.add(arn)

            return list(noncompliant_arns)

        print(list_noncompliant_pipelines())
        ```

        This gives you the pipeline names/IDs that the rule is flagging.

        ***

        ## 3. For each pipeline, locate the Deploy action and its CodeDeploy deployment group

        ```python theme={null}
        import boto3

        codepipeline = boto3.client('codepipeline')

        def get_deploy_actions(pipeline_name):
            response = codepipeline.get_pipeline(name=pipeline_name)
            stages = response['pipeline']['stages']

            deploy_actions = []
            for stage in stages:
                if stage['name'].lower() == 'deploy':
                    for action in stage['actions']:
                        if action['actionTypeId']['category'] == 'Deploy' and \
                           action['actionTypeId']['provider'] == 'CodeDeploy':
                            deploy_actions.append(action)
            return deploy_actions

        pipeline_name = 'your-pipeline-name'
        deploy_actions = get_deploy_actions(pipeline_name)
        for a in deploy_actions:
            print(a['name'], a['configuration'])
        ```

        In the Deploy action configuration you should see keys similar to:

        * `ApplicationName`
        * `DeploymentGroupName`

        These map to the CodeDeploy deployment group whose deployment configuration you must change.

        ***

        ## 4. Update the CodeDeploy deployment group to a safer deployment config (Python)

        Example: change `deploymentConfigName` to `CodeDeployDefault.OneAtATime`.

        ```python theme={null}
        import boto3

        codedeploy = boto3.client('codedeploy')

        def set_safer_deployment_config(application_name, deployment_group_name,
                                        deployment_config_name='CodeDeployDefault.OneAtATime'):
            # Get existing group
            dg = codedeploy.get_deployment_group(
                applicationName=application_name,
                deploymentGroupName=deployment_group_name
            )['deploymentGroupInfo']

            # Update only the deploymentConfigName (other required params must be preserved)
            codedeploy.update_deployment_group(
                applicationName=application_name,
                currentDeploymentGroupName=deployment_group_name,
                deploymentConfigName=deployment_config_name,
                # You must re‑pass any fields that are required in your setup
                # e.g. serviceRoleArn, autoScalingGroups, etc., if you modify more fields.
            )

        # Example usage from one pipeline's deploy action
        application_name = 'my-codedeploy-app'
        deployment_group_name = 'my-codedeploy-dg'

        set_safer_deployment_config(application_name, deployment_group_name)
        ```

        Notes:

        * In practice, `update_deployment_group` may require additional parameters if you want to modify other aspects; the minimal example above focuses on `deploymentConfigName`.
        * If you need a more tailored rollout (e.g., 10% at a time), create a custom deployment configuration first (`create_deployment_config`) and then reference it here.

        ***

        ## 5. Optional: End‑to‑end automation for all noncompliant pipelines

        Sketch:

        ```python theme={null}
        def remediate_all_noncompliant():
            pipelines = list_noncompliant_pipelines()
            for pipeline in pipelines:
                deploy_actions = get_deploy_actions(pipeline)
                for action in deploy_actions:
                    app = action['configuration']['ApplicationName']
                    dg  = action['configuration']['DeploymentGroupName']
                    print(f"Remediating {pipeline} → {app}/{dg}")
                    set_safer_deployment_config(app, dg, 'CodeDeployDefault.OneAtATime')

        remediate_all_noncompliant()
        ```

        ***

        If you can paste one of the actual noncompliant pipeline definitions (or the AWS Config rule message), I can tailor the Python exactly to your case (e.g., ECS, CloudFormation, Lambda deployments instead of CodeDeploy).
      </Accordion>

      <Accordion title="Using Terraform">
        ```hcl theme={null}
        resource "aws_codepipeline" "PIPELINE_NAME" {
          name     = "PIPELINE_NAME"            # replace with your pipeline name
          role_arn = "PIPELINE_SERVICE_ROLE_ARN" # replace with pipeline IAM role

          artifact_store {
            type     = "S3"
            location = "ARTIFACT_BUCKET_NAME"   # replace with S3 bucket name
          }

          # First stage must NOT perform more than the allowed number of deployments.
          # This example shows a single deploy action in the first deployment stage.
          stage {
            name = "DeployToDev"

            action {
              name             = "DeployToDevSingle"   # single deployment
              category         = "Deploy"
              owner            = "AWS"
              provider         = "CodeDeploy"
              version          = "1"
              input_artifacts  = ["BuildOutput"]
              region           = "DEPLOY_REGION"       # replace with region for deployment
              run_order        = 1

              configuration = {
                ApplicationName     = "CODEDEPLOY_APP_NAME"           # replace
                DeploymentGroupName = "CODEDEPLOY_DEPLOYMENT_GROUP"   # replace
              }
            }

            # REMOVE any additional deploy actions here that would exceed the
            # allowed deploymentLimit for this first stage.
            # Example of what to avoid (commented out):
            # action {
            #   name             = "DeployToAnotherEnv"
            #   category         = "Deploy"
            #   owner            = "AWS"
            #   provider         = "CodeDeploy"
            #   version          = "1"
            #   input_artifacts  = ["BuildOutput"]
            #   region           = "ANOTHER_REGION"
            #   run_order        = 1
            #   configuration = {
            #     ApplicationName     = "ANOTHER_CODEDEPLOY_APP"
            #     DeploymentGroupName = "ANOTHER_DEPLOYMENT_GROUP"
            #   }
            # }
          }

          # Subsequent stages must also respect the deploymentLimit if you use it:
          # keep the number of Deploy actions in each stage <= your chosen limit.
          stage {
            name = "DeployToProd"

            action {
              name             = "DeployToProdSingle"
              category         = "Deploy"
              owner            = "AWS"
              provider         = "CodeDeploy"
              version          = "1"
              input_artifacts  = ["BuildOutput"]
              region           = "PROD_REGION"         # replace
              run_order        = 1

              configuration = {
                ApplicationName     = "PROD_CODEDEPLOY_APP"           # replace
                DeploymentGroupName = "PROD_DEPLOYMENT_GROUP"         # replace
              }
            }

            # If your policy allows more than one deployment per stage (deploymentLimit > 1),
            # you can add up to that many Deploy actions here, but not more.
          }

          # other stages (Source, Build, etc.) as needed...
        }
        ```

        This AWS Config rule is evaluated against the CodePipeline pipeline (AWS::CodePipeline::Pipeline), not the `aws_codedeploy_deployment_group` or CodeBuild project, so the remediation is to reduce the number of `Deploy` actions per stage in `aws_codepipeline`, especially in the first deployment stage, to be at or below your chosen `deploymentLimit`.

        This change normally does not force replacement of the pipeline resource itself, but it will update stages and actions in place; expect `terraform plan` to show modifications to the `stage` blocks (removal or reduction of extra `Deploy` actions) and no changes to unrelated resources.
      </Accordion>
    </AccordionGroup>
  </Tab>
</Tabs>
