Codefresh "Best Practices"

Our tips for working with Codefresh

Managing Secrets

Use chamber to manage secrets. Provision a dedicated IAM user with limited scope by using the terraform-aws-iam-chamber-user terraform module. Review our guide on managing secrets with CI/CD. Also, a sample invocation of terraform-aws-iam-chamber-user is part of “root modules”.

Example AWS IAM Chamber User for Codefresh

# Chamber user for CI/CD systems that cannot leverage IAM instance profiles
# https://docs.aws.amazon.com/systems-manager/latest/userguide/sysman-paramstore-access.html
module "chamber_user" {
  source        = "git::https://github.com/cloudposse/terraform-aws-iam-chamber-user.git?ref=tags/0.1.4"
  namespace     = "${var.namespace}"
  stage         = "${var.stage}"
  name          = "chamber"
  attributes    = ["codefresh"]
  kms_key_arn   = "${module.chamber_kms_key.key_arn}"
  ssm_resources = ["${format("arn:aws:ssm:%s:%s:parameter/kops/*", var.region, var.account_id)}"]
}

output "chamber_user_name" {
  value       = "${module.chamber_user.user_name}"
  description = "Normalized IAM user name"
}

output "chamber_user_arn" {
  value       = "${module.chamber_user.user_arn}"
  description = "The ARN assigned by AWS for the user"
}

output "chamber_user_unique_id" {
  value       = "${module.chamber_user.user_unique_id}"
  description = "The user unique ID assigned by AWS"
}

output "chamber_access_key_id" {
  value       = "${module.chamber_user.access_key_id}"
  description = "The access key ID"
}

output "chamber_secret_access_key" {
  value       = "${module.chamber_user.secret_access_key}"
  description = "The secret access key. This will be written to the state file in plain-text"
}

Naming Kubernetes Contexts

Use cluster name. e.g. us-west-2-staing-example-com

Codefresh Kubernetes Integration

Use a codefresh.yml build file

Always include the pipeline manifest in the source repo. This allows it to be versioned alongside the code it builds.

Use YAML from Repository

Stick non-secrets in codefresh.yml

Set all non-secret values in the pipeline config so that they can be versioned.

Use Conditions to Control Flow

Use conditions to control when a build step should be run. This is useful for deploying to various kubernetes clusters by setting the KUBE_CONTEXT based on the branch or tag.

when:
  condition:
    all:
      executeForTag: "'${{SEMVERSION_TAG}}' != ''"

Use a Containerized Build Harness

A build-harness is like a “test harness”. It provides reusable methods for building and deploying software. This allows to keep things DRY by offloading the business logic to a centralized repo that can be versioned and shared across multiple projects. We provide one that we use in nearly all of our projects.

Cloud Posse’s Build Harness is free. GitHub: https://github.com/cloudposse/build-harness Docker Hub: https://hub.docker.com/r/cloudposse/build-harness/

An example invocation can be found in our CI/CD process for how we build helm charts

Use the cli

Codefresh provides a decent cli tool to control pipelines.

Use Cron Triggers

Codefresh provides the ability to run jobs periodically with cron-like functionality.

Add a Codefresh Cron Trigger

This is ideal for a couple of use-cases: 1. Rerun infrequently triggered pipelines periodically to ensure they still work 2. Rebuild containers containing time-sensitive data (e.g. figures for a database, or MaxMind GeoIP databases)