AWS secrets handling into Jenkins pipelines

AWS secrets handling into Jenkins pipelines
Madhumita Yadav
AWS secrets handling into Jenkins pipelines

With Manage Credentials,Jenkins provides a helpful mechanism to manage secrets. This provides a centralplace to add and update credentials, as well as see which jobs are using aparticular credential. The traditional approach is to maintain thesecredentials manually, which introduces the below disadvantages -

  • not a DRY(do not repeat yourself) approach - the secret value is duplicated in several places e.g. you define a database password in CloudFormation and manually copy it into the Jenkins credential
  • Update propagations - if the source secret changes, the Jenkins credential must be kept up to date e.g. if you change the database password you need to remember to update Jenkins

With the ever-evolving technology space, where things are moving very fast and Organizations are looking for more IaaC based deployments leveraging CloudFormation, Terraform, etc - managing credentials with the above approach seems quite outdated.

Fortunately, Jenkins plugins exist allowing us to access the right services within AWS to better manage these credentials.

Let's explore a few of them  -

Parameter Store – injected via JCasC plugin + Configuration as Code AWS SSM plugin

With the Configuration as Code AWS SSM plugin, we can define a credential directly in the JCasC YAML file and refer to a value defined in a Parameter Store parameter.

Sample - JCasC YAML code, where we are creating a credential whose value comes from the Parameter Store parameter named JenkinsPipelineParameter.

credentials:  system:    domainCredentials:      - credentials:          - string:              id: "jcasc-credential-from-parameter-store"              scope: GLOBAL              secret: "${JenkinsPipelineParameter}"

We can then use the credential as normal within the pipeline.

environment {                SECRET_VALUE = credentials('jcasc-credential-from-parameter-store')            }

To use this technique, the Jenkins role needs the ssm:GetParameter permission to access the parameter (not ssm:GetParameters).

Using Parameter Store & environment variable

One can also store secrets in the AWS Parameter Store. ECS allows injecting Parameter Store values directly into the Jenkins container.

Here’s how the CloudFormation looks for the AWS::ECS::TaskDefinition resource, with ValueFrom taking the ARN of the Parameter Store parameter.

     ContainerDefinitions:          Secrets:            - Name: SECRET_FROM_ENVIRONMENT_VARIABLE_INJECTED_FROM_PARAMETER_STORE              ValueFrom: !Sub 'arn:aws:ssm:${AWS::Region}:${AWS::AccountId}:parameter/${JenkinsPipelineParameter}'

As expected, we can then access the value directly from within a pipeline definition.

           steps {                echo "Secret value '$SECRET_FROM_ENVIRONMENT_VARIABLE_INJECTED_FROM_PARAMETER_STORE'"            }

For this technique to work, the Jenkins execution role must have the ssm:GetParameters permission to retrieve the parameter.

Using Secrets manager – via JCasC plugin & AWS Secrets Manager Credentials Provider plugin

The Jenkins Configuration as Code (JCasC) plugin allows defining the Jenkins configuration in YAML. It has integration with the AWS Secrets Manager Credentials Provider plugin, allowing you to refer to the Secrets Manager secret directly within a credential declaration in the YAML file.

Sample code for a credential being created based on the value of the Secrets Manager secret named JenkinsPipelineSecret.

credentials:  system:    domainCredentials:      - credentials:          - string:              id: "jcasc-credential-from-secrets-manager"              scope: GLOBAL              secret: "${JenkinsPipelineSecret}"

With this in place, you can then refer to the credential in the normal way in your pipeline definition.

           environment {                SECRET_VALUE = credentials('jcasc-credential-from-secrets-manager')            }

For this technique to work, the Jenkins role must have the secretsmanager:GetSecretValue permission to access the secret and secretsmanager:ListSecrets permission to list all secrets.

Back to blog