AWS Credentials

Description

With OpenID Connect (OIDC), you can configure your pipeline to request a short-lived set of credentials from AWS.

Source Code: https://github.com/Cargill/vela-aws-credentials

Registry: https://hub.docker.com/r/cargill/vela-aws-credentials

Prerequisites

Adding the identity provider to AWS

To add the GitHub OIDC provider to IAM, see the AWS docs.

  • Provider URL: https://<VELA API>/_services/token.
  • Audience: sts.amazonaws.com.

Terraform example:

data "tls_certificate" "vela" {
  url = "https://vela-server.com/_services/token"
}

resource "aws_iam_openid_connect_provider" "vela" {
  url             = "https://vela-server.com/_services/token"
  client_id_list  = ["sts.amazonaws.com"]
  thumbprint_list = [data.tls_certificate.vela.certificates[0].sha1_fingerprint]
}

Configuring the IAM role

Review the official AWS documentation for IAM roles with OIDC.

NOTE: It is critical that the IAM trust policy has conditions to limit which Vela pipelines/steps are able to assume the IAM role.

The example below includes several conditions that limit the ability to assume the IAM role:

  1. The StringLike condition on the sub claim with a wildcard operator (*) allows any branch or pull request merge branch from the octo-org/octo-repo organization and repository to assume the IAM role in AWS.
  2. The StringLike condition on the image claim with a wildcard operator (*) permits only steps that use the golang:<tag> image to assume the IAM role in AWS.
  3. The StringEquals condition on the aud claim ensures that only tokens with the audience of sts.amazonaws.com can assume the IAM role in AWS. sts.amazonaws.com is the default audience when utilizing this plugin.
  4. The StringEquals condition on the commands claim ensures that only steps without a commands section can assume the IAM role in AWS.

NOTE: AWS requires that all conditions must be met for the role assumption to succeed. If any condition is not met, the role assumption will fail.

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "Federated": "arn:aws:iam::123456123456:oidc-provider/vela-server.com/_services/token"
            },
            "Action": "sts:AssumeRoleWithWebIdentity",
            "Condition": {
                "StringLike": {
                    "vela-server.com/_services/token:sub": "repo:octo-org/octo-repo:*",
                    "vela-server.com/_services/token:image": "golang:*"
                },
                "StringEquals": {
                    "vela-server.com/_services/token:aud": "sts.amazonaws.com",
                    "vela-server.com/_services/token:commands": false
                }
            }
        }
    ]
}

The full list of claims that Vela exposes to AWS can be found within the Vela docs.

Terraform example:

data "aws_iam_policy_document" "assume_role_policy" {
  statement {
    actions = [ "sts:AssumeRoleWithWebIdentity" ]
    principals {
      identifiers = [ aws_iam_openid_connect_provider.vela.arn ]
      type = "Federated"
    }

    condition {
      test = "StringLike"
      variable = "vela-server.com/_services/token:sub"
      values = ["repo:octo-org/octo-repo:*"]
    }

    condition {
      test = "StringLike"
      variable = "vela-server.com/_services/token:image"
      values = ["golang:*"]
    }

    condition {
      test = "StringEquals"
      variable = "vela-server.com/_services/token:aud"
      values = ["sts.amazonaws.com"]
    }

    condition {
      test = "StringEquals"
      variable = "vela-server.com/_services/token:commands"
      values = [false]
    }
  }
}

resource "aws_iam_role" "test_role" {
  name = "test_role"

  assume_role_policy = data.aws_iam_policy_document.assume_role_policy.json
}

Usage

NOTE:

Users should refrain from using latest as the tag for the Docker image.

It is recommended to use a semantically versioned tag instead.

Example of generating credentials:

steps:
  - name: generate_aws
    image: cargill/vela-aws-credentials:latest
    id_request: yes
    parameters:
      role: "arn:aws:iam::123456123456:role/test"

Example of generating credentials with a different region:

steps:
  - name: generate_aws
    image: cargill/vela-aws-credentials:latest
    id_request: yes
    parameters:
      role: "arn:aws:iam::123456123456:role/test"
+     region: "us-west-2"

Sample of generating credentials, writing credentials script, and utilizing them with the AWS CLI:

steps:
  - name: generate_aws
    image: cargill/vela-aws-credentials:latest
    id_request: yes
    parameters:
      role: "arn:aws:iam::123456123456:role/test"
      script_write: true

  - name: test_aws
    image: amazon/aws-cli:latest
    commands:
      - source /vela/secrets/aws/setup.sh
      - aws sts get-caller-identity

Parameters

NOTE:

The plugin supports reading all parameters via environment variables or files.

Any values set from a file take precedence over values set from the environment.

The following parameters are used to configure the image:

NameDescriptionRequiredDefaultEnvironment Variables
roleAWS IAM Role ARN for which to generate credentialstrueN/APARAMETER_ROLE
AWS_CREDENTIALS_ROLE
regionAWS region where you want to obtain credentials.falseus-east-1PARAMETER_REGION
AWS_CREDENTIALS_REGION
role_duration_secondsAssumed role duration in seconds.false3600PARAMETER_ROLE_DURATION_SECONDS
AWS_CREDENTIALS_ROLE_DURATION_SECONDS
role_session_nameSession name to use when assuming the role.falsevelaPARAMETER_ROLE_SESSION_NAME
AWS_CREDENTIALS_ROLE_SESSION_NAME
log_levelLog level for the plugin.falseinfoPARAMETER_LOG_LEVEL
AWS_CREDENTIALS_LOG_LEVEL
audienceAudience to use for the OIDC provider.falsests.amazonaws.comPARAMETER_AUDIENCE
AWS_CREDENTIALS_AUDIENCE
verifyIf the AWS credentials should be verified.falsefalsePARAMETER_VERIFY
AWS_CREDENTIALS_VERIFY
script_pathPath where to write script that contains AWS credentialsfalse/vela/secrets/aws/setup.shPARAMETER_SCRIPT_PATH
AWS_CREDENTIALS_SCRIPT_PATH
script_writeIf the credentials script should be created.falsefalsePARAMETER_SCRIPT_WRITE
AWS_CREDENTIALS_SCRIPT_WRITE
inline_session_policyAn IAM policy in JSON format that you want to use as an inline session policy when assuming the IAM role.falseN/APARAMETER_INLINE_SESSION_POLICY
AWS_CREDENTIALS_INLINE_SESSION_POLICY
managed_session_policiesList of ARNs of the IAM managed policies that you want to use as managed session policies when assuming the IAM role. The policies must exist in the same account as the role.falseN/APARAMETER_MANAGED_SESSION_POLICIES
AWS_CREDENTIALS_MANAGED_SESSION_POLICIES

Troubleshooting

You can start troubleshooting this plugin by tuning the level of logs being displayed:

steps:
  - name: message
    image: cargill/vela-aws-credentials:latest
    pull: always
    id_request: yes
    parameters:
+     log_level: trace
      role: "arn:aws:iam::123456123456:role/test"