Serverless, CodeStar, CodePipeline & CloudFormation

I think this should be possible.
Underneath codestar is just linking together general purpose components, and each one of them should be able to work with serverless.

I’ve managed to reproduce the s3 error in the build step of the pipeline. The fix for that is in several steps:

in my serverless.yml I told it to use the deployment artifact bucket created by codestar like so:

service: serverless
provider:
  name: aws
  deploymentBucket: aws-codestar-region-account_id-serverless-pipeline
...

In my buildspec.yml I changed it to use serverless only to package things up:

version: 0.2
phases:
  install:
    commands:
      - npm install -g serverless
      - yum -y -q update
      - yum -y -q install jq
  build:
    commands:
      - serverless package
      - ./upload.sh
      - cp .serverless/cloudformation-template-update-stack.json .serverless/template-export.json

artifacts:
  type: zip
  files:
    - .serverless/*
  discard-paths: yes

The upload.sh script copies the artifact to the deployment bucket:

#!/bin/bash

set -eu
set o pipefile

STATE_FILE=.serverless/serverless-state.json
S3_PREFIX=$(jq -r '.package.artifactDirectoryName' < "$STATE_FILE")
ARTIFACT=$(jq -r '.package.artifact' < "$STATE_FILE")
AWS_PROFILE=${AWS_PROFILE:-}

PROFILE_OPTS=""
if [ "" != "$AWS_PROFILE" ]; then
  PROFILE_OPTS="--profile $AWS_PROFILE"
fi

aws $PROFILE_OPTS s3 cp .serverless/$ARTIFACT s3://$S3_BUCKET/$S3_PREFIX/$ARTIFACT

It should work from your dev machine as long as you set the S3_BUCKET environment variable which codestar seems to set in its pipeline for us (it’s the name of the deployment bucket).

Finally you need to modify the role that codestar uses for the pipeline. Mine seems to be called CodeStarWorker-serverless-CloudFormation. You need to add the “s3:GetBucketLocation” permission on the deployment artifact bucket.
Note that codebuild can modify the role and role policy so there’s a chance the policy change could be overwritten. things to try in order to be more defensive there: using attached policy instead of modifying the inline one, or uncheck the tickbox that allows codebuild to edit the role in the codebuild project’s properties.

Having got this far the deploy step of my pipeline fails because it’s supplying cloudformation template parameters where none are expected.

So next, go to the codepipeline and edit it.
The parameters are specified in the deploy phase’s GenerateChangeSet step. Modify that so the parameters json object is empty.
Further, the pipeline needs to run the cloudformation GenerateChangeSet with a particular capability.
Change the capability from CAPABILITY_IAM to CAPABILITY_NAMED_IAM

Next need to add some more permissions, this time to the cloudformation deploy role. Mine seems to be called “CodeStarWorker-serverless-CloudFormation”.
That role needs permissions to create everything that serverless puts in its generated cloudformation template.
That includes cloudwatch log groups, iam execution role for lambda and any other bits and pieces you’ve added.
At the minimum I added

                "lambda:GetFunction",
                "lambda:ListVersionsByFunction",
                "lambda:PublishVersion",
                "logs:CreateLogGroup",
                "logs:DeleteLogGroup",
                "iam:AttachRolePolicy",
                "iam:GetRole",
                "iam:GetRolePolicy",
                "iam:CreatePolicy",
                "iam:CreateRole",
                "iam:DeleteRole",
                "iam:DeleteRolePolicy",
                "iam:PutRolePolicy"

I also had to add iam:PassRole for the lambda execution role that serverless created:

        {
            "Action": [
                "iam:PassRole"
            ],
            "Resource": [
                "arn:aws:iam::account_id:role/serverless-dev-region-lambdaRole"
            ],
            "Effect": "Allow"
        },
...

Also note that serverless uses a shared iam role for lambdas. I don’t believe this is good practice and it also complicates things when the role is managed by more than one cloudformation template.

One of the things I’m not sure about is what the codestar cloudformation transformation does.
There’s a resource that gets deleted – a SyncResources thing. It’s not present in the serverless cloudformation probably because serverless doesn’t use the codestar CF transformation. I don’t yet know what breaks when you mess with this.

2 Likes