How to use Code Pipeline to continuously deploy to a CloudFormation Stack

Viewed 760

I am trying to build a code pipeline to:

  1. Take a github Java source project
  2. Build it to generate a jar file
  3. Use an sam-template.yml to deploy the jar

I can build the jar, ie I have stage 2 working. I assume stage 3 will involve invoking a sam-template to do the deployment. The template is part of the same github repo.

My question is: I cannot see how to supply the jar and template file to a third stage to do the deployment.

I attached three files below for information:

  1. A build spec, which works but I cannot find the generated artifacts.
  2. A json of the pipeline so far, generated by aws codepipeline get-pipeline
  3. A copy of the sam-template.yml that will be used in Stage 3

1. buildspec.yml

version: 0.2

phases:
  install:
    commands:
      - echo Entered the install phase...
      - apt-get update -y
      - apt-get install -y maven
  build:
    commands:
      - echo Entered the build phase...
      - mvn package
  post_build:
    commands:
      - echo Entered the post_build phase...
artifacts:
  files:
    - server/harvest/target/harvest-1.0-SNAPSHOT.jar
  discard-paths: yes
secondary-artifacts:
  cf-config:
    files:
      - server/aws/sam-app/sam-template.yml
    discard-paths: yes
  jar-file:
    files:
      - server/harvest/target/harvest-1.0-SNAPSHOT.jar
    discard-paths: yes

2. codepipeline.json

{
    "pipeline": {
        "name": "<<Name>>",
        "roleArn": "arn:aws:iam::xxxxxxxx",
        "artifactStore": {
            "type": "S3",
            "location": "codepipeline-eu-west-1-xxxxxxx"
        },
        "stages": [
            {
                "name": "Source",
                "actions": [
                    {
                        "name": "Source",
                        "actionTypeId": {
                            "category": "Source",
                            "owner": "ThirdParty",
                            "provider": "GitHub",
                            "version": "1"
                        },
                        "runOrder": 1,
                        "configuration": {
                            "Branch": "master",
                            "OAuthToken": "****",
                            "Owner": "<<username>>",
                            "PollForSourceChanges": "false",
                            "Repo": "repo-name"
                        },
                        "outputArtifacts": [
                            {
                                "name": "SourceArtifact"
                            }
                        ],
                        "inputArtifacts": []
                    }
                ]
            },
            {
                "name": "Build",
                "actions": [
                    {
                        "name": "Build",
                        "actionTypeId": {
                            "category": "Build",
                            "owner": "AWS",
                            "provider": "CodeBuild",
                            "version": "1"
                        },
                        "runOrder": 1,
                        "configuration": {
                            "ProjectName": "Harvest"
                        },
                        "outputArtifacts": [
                            {
                                "name": "BuildArtifact"
                            }
                        ],
                        "inputArtifacts": [
                            {
                                "name": "SourceArtifact"
                            }
                        ]
                    }
                ]
            }
        ],
        "version": 3
    },
    "metadata": {
        "pipelineArn": "arn:aws:codepipeline:eu-west-1:xxxxxxxxx",
        "created": 1546780342.845,
        "updated": 1547288970.709
    }
}

3. sam-template.yml

AWSTemplateFormatVersion: '2010-09-09'
Description: AWS Serverless Spring Boot API - uk.co.pack::harvest
Globals:
  Api:
    EndpointConfiguration: REGIONAL
Outputs:
  HarvestApi:
    Description: URL for application
    Export:
      Name: HarvestApi
    Value: !Sub 'https://${ServerlessRestApi}.execute-api.${AWS::Region}.amazonaws.com/Prod/ping'
Parameters:
  amazonawsaccessKey:
    Type: String
  amazonawssecretkey:
    Type: String
  amazondynamodbendpoint:
    Type: String
  appid:
    Type: String
  url:
    Type: String
Resources:
  HarvestRatingsFunction:
    Properties:
      CodeUri: build/harvest-1.0-SNAPSHOT.jar
      Environment:
        Variables:
          AMAZON_AWS_ACCESSKEY: !Ref 'amazonawsaccessKey'
          AMAZON_AWS_SECRETKEY: !Ref 'amazonawssecretkey'
          AMAZON_DYNAMODB_ENDPOINT: !Ref 'amazondynamodbendpoint'
          IOS_APP_ID: !Ref 'appid'
          IOS_URL: !Ref 'url'
      Events:
        GetResource:
          Properties:
            Method: any
            Path: /{proxy+}
          Type: Api
      Handler: uk.co.pack.StreamLambdaHandler::handleRequest
      MemorySize: 512
      Policies: AWSLambdaBasicExecutionRole
      Runtime: java8
      Timeout: 60
    Type: AWS::Serverless::Function
  RatingsDbTable:
    Properties:
      AttributeDefinitions:
      - AttributeName: id
        AttributeType: S
      BillingMode: PROVISIONED
      KeySchema:
      - AttributeName: id
        KeyType: HASH
      ProvisionedThroughput:
        ReadCapacityUnits: '1'
        WriteCapacityUnits: '1'
      TableName: Review
    Type: AWS::DynamoDB::Table
Transform: AWS::Serverless-2016-10-31
1 Answers

Your third stage in the CodePipeline could look something like this:

  {
"Name": "Deploy",
"Actions": [
  {
    "Name": "Beta",
    "ActionTypeId": {
      "Category": "Deploy",
      "Owner": "AWS",
      "Provider": "CloudFormation",
      "Version": 1
    },
    "Configuration": {
      "ActionMode": "CREATE_UPDATE",
      "Capabilities": "CAPABILITY_IAM",
      "RoleArn": "CloudformationRole.Arn",
      "StackName": "Harvest",
      "TemplatePath": "BuildOutput::sam-template.yml",
      "ParameterOverrides": "{\"appid\": \"${app123456}\", \"url\": \"https://apple.com\"}"
    },
    "InputArtifacts": [
      {
        "Name": "BuildOutput"
      }
    ],
    "RunOrder": 1
  }
]
}

The jar and the template are available in the BuildOutput artifact bundle, since you specified them in your buildspec.yml. As long as you have the BuildOutput (or SourceOutput for that matter) as InputArtifacts, you can use them as seen above.

Related