CodePipeline Versioner

Symphonia
Mike Roberts
Jan 23, 2020

AWS CodePipeline is AWS’ CD orchestration tool. We’re fans of CodePipeline at Symphonia : we use it with our clients, and on our own projects. To read a quick overview of CodePipeline see this earlier article that I wrote.

Most of the time we use CodePipeline in a “Continuous Deployment” scenario - the resources and application to deploy to production are precisely the ones defined within source control at the time the pipeline execution starts. In this case we’re rarely concerned about a version number or a build number - something like 1.0.1, 1.0.2, … - since we typically only care about the most recent execution, and most recent source code, because rolling back is a lie.

Sometimes, however, we do care about tracking such version or build numbers - perhaps because the pipeline is creating an artifact for consumption by other systems, such as a library or SAR application, or perhaps we want to have a phased release system.

At the current time CodePipeline doesn’t natively support linearly increasing build numbers, and so we’ve built a SAR component to allow you add such a capability to your CodePipeline pipelines.

This SAR component is available in the SAR registry here, alternatively you can see it on Github here.

How to use codepipeline-versioner

In these instructions we’re assuming that you’re using CloudFormation to define your CodePipeline configuration. We strongly recommend using this “Infrastructure as Code” approach. If you’re defining CodePipeline in a different way, perhaps via the web console, then you should adapt as necessary.

You can also use the example CloudFormation / SAM template that we provide for this component that you can copy and paste from.

First, make sure you’ve included the SAM transform in your CloudFormation template - we normally put it as the second line:

Transform: AWS::Serverless-2016-10-31

Next, in the Resources section of your template, add a SAR resource as follows:

  Versioner:
    Type: AWS::Serverless::Application
    Properties:
      Location:
        ApplicationId: arn:aws:serverlessrepo:us-east-1:073101298092:applications/codepipeline-versioner
        SemanticVersion: 1.0.0

Now, somewhere early in the Stages list of your AWS::CodePipeline::Pipeline , create a Lambda action that will call the Versioner:

- Name: IncrementVersion
  # This "Namespace" is how we can later reference variables set in the Lambda function
  Namespace: Versioner
  ActionTypeId:
    Category: Invoke
    Owner: AWS
    Version: 1
    Provider: Lambda
  Configuration:
  # "Versioner" here must be the same name as the SAR application resource name above
    FunctionName: !GetAtt Versioner.Outputs.LambdaFunction

The IAM Role that your CodePipeline assumes should have sufficient privileges to run the Lambda function in the SAR app.

After this action has run, the following Variables will be available in the Versioner namespace (assuming you’ve not changed the Namespace configuration defined above)

  • buildNumber - an integer that is the value one more than during the previous pipeline execution
  • version - The buildNumber value, with a prefix as specified in the SAR component configuration (see below).

CodePipeline Variables can be used by various other actions. See the CodePipeline documentation for more details. As an example, you may want to set environment variables for a CodeBuild action, as follows:

- Name: CodeBuildSample
  ActionTypeId:
    Category: Build
    Owner: AWS
    Version: 1
    Provider: CodeBuild
  InputArtifacts:
    - Name: SourceCode
  Configuration:
    ProjectName: !Ref CodeBuildSample
    # Here we capture both the 'buildNumber' and 'version' values produced by the Versioner (in the "Versioner" namespace configured earlier)
    # Typically you'd probably only want to use one of these
    EnvironmentVariables: '[{"name":"BUILD_NUMBER","value":"#{Versioner.buildNumber}"},{"name":"VERSION","value":"#{Versioner.version}"}]'

And that’s it. Now you have a CodePipeline that has a linearly increasing build number and/or version that you can use to generate semantically versioned libraries, versioned application deployment artifacts, and more.

Optional configuration

The SAR app also has a number of optionally configurable parameters. For more details, see its Github page

Conclusion

This SAR app provides a way to enable build numbers / versions in CodePipeline, in a way that integrates well with a CloudFormation infrastructure definition.

If you find this component useful, please let us know at Twitter, or email us at mikeandjohn@symphonia.io