Search code examples
amazon-web-servicesterraformaws-cloudformationaws-codepipelineaws-cloudformation-custom-resource

How to export an existing CodePipeline to CloudFormation template


This is more of a lack of understanding on my part but I cannot seem to debug this. I have created an codepipeline which runs terraform apply ( which internally creates the aws infrastructure for me ). the codepipeline seems to be working.

I need to implement the same codepipeline for another account, how can I do so.

I tried to get the json script using the below command. aws codepipeline get-pipeline --name

I convert json script to yaml script.

When I try to run the yaml script on another account I get below error

Template format error: At least one Resources member must be defined.

ISSUES: 1.) Best Way I can export codepipeline to cloudformation template 2.) The approach which I used didn't work, how to solve it?

{
    "pipeline": {
        "name": "my-code-pipeline",
        "roleArn": "arn:aws:iam::aws-account-id:role/service-role/AWSCodePipelineServiceRole-aws-region-my-code-pipeline",
        "artifactStore": {
            "type": "S3",
            "location": "codepipeline-aws-region-45856771421"
        },
        "stages": [
            {
                "name": "Source",
                "actions": [
                    {
                        "name": "Source",
                        "actionTypeId": {
                            "category": "Source",
                            "owner": "ThirdParty",
                            "provider": "GitHub",
                            "version": "1"
                        },
                        "runOrder": 1,
                        "configuration": {
                            "Branch": "master",
                            "OAuthToken": "****",
                            "Owner": "github-account-name",
                            "PollForSourceChanges": "false",
                            "Repo": "repo-name"
                        },
                        "outputArtifacts": [
                            {
                                "name": "SourceArtifact"
                            }
                        ],
                        "inputArtifacts": [],
                        "region": "aws-region",
                        "namespace": "SourceVariables"
                    }
                ]
            },
            {
                "name": "codebuild-for-terraform-init-and-plan",
                "actions": [
                    {
                        "name": "codebuild-for-terraform-init",
                        "actionTypeId": {
                            "category": "Build",
                            "owner": "AWS",
                            "provider": "CodeBuild",
                            "version": "1"
                        },
                        "runOrder": 1,
                        "configuration": {
                            "ProjectName": "my-code-pipeline-build-stage"
                        },
                        "outputArtifacts": [],
                        "inputArtifacts": [
                            {
                                "name": "SourceArtifact"
                            }
                        ],
                        "region": "aws-region"
                    }
                ]
            },
            {
                "name": "manual-approve",
                "actions": [
                    {
                        "name": "approval",
                        "actionTypeId": {
                            "category": "Approval",
                            "owner": "AWS",
                            "provider": "Manual",
                            "version": "1"
                        },
                        "runOrder": 1,
                        "configuration": {
                            "NotificationArn": "arn:aws:sns:aws-region:aws-account-id:Email-Service"
                        },
                        "outputArtifacts": [],
                        "inputArtifacts": [],
                        "region": "aws-region"
                    }
                ]
            },
            {
                "name": "codebuild-for-terraform-apply",
                "actions": [
                    {
                        "name": "codebuild-for-terraform-apply",
                        "actionTypeId": {
                            "category": "Build",
                            "owner": "AWS",
                            "provider": "CodeBuild",
                            "version": "1"
                        },
                        "runOrder": 1,
                        "configuration": {
                            "ProjectName": "codebuild-project-for-apply"
                        },
                        "outputArtifacts": [],
                        "inputArtifacts": [
                            {
                                "name": "SourceArtifact"
                            }
                        ],
                        "region": "aws-region"
                    }
                ]
            }
        ],
        "version": 11
    },
    "metadata": {
        "pipelineArn": "arn:aws:codepipeline:aws-region:aws-account-id:my-code-pipeline",
        "created": "2020-09-17T13:12:50.085000+05:30",
        "updated": "2020-09-21T15:46:19.613000+05:30"
    }
}

The given code is the yaml template that I used to create cloudformation template.


Solution

  • The aws codepipeline get-pipeline --name CLI command returns information about the pipeline structure and pipeline metadata, but it is not the same format as a CloudFormation template (or the resource part of it).

    There is no built-in support for exporting existing AWS resources to create a CloudFormation template, though you do have a couple of options.

    1. Use former2 (built and maintained by AWS Hero, Ian Mckay) to generate a CloudFormation template from the resources you select.
    2. Take the JSON output from the aws codepipeline get-pipeline --name command you used and manually craft a CloudFormation template. The pipeline will be one resource in the list of resources in the full template. The info it contains is pretty close, but needs some adjustments to conform to the CloudFormation resource specification for a CodePipeline, which you can find here. You'll also need to do the same for other resources that you need to bring into the template, with aws <service name> describe.

    If you go with option 2 (and even if you don't), I recommend using cfn-lint with your code editor to help adhere to the spec.