Skip to content

Commit

Permalink
Merge pull request #288 from alphagov/iam_roles_chain
Browse files Browse the repository at this point in the history
Add support for AWS IAM roles chain
  • Loading branch information
aoldershaw authored Jul 9, 2021
2 parents 06ffede + 2ea7566 commit 4372334
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 14 deletions.
11 changes: 8 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,12 @@ differences:
* `aws_region`: *Optional. Default `""`.* The region to use for accessing ECR. This is required if you are using ECR. This region will help determine the full repository URL you are accessing (e.g., `012345678910.dkr.ecr.us-east-1.amazonaws.com`)

* `aws_role_arn`: *Optional. Default `""`.* If set, then this role will be
assumed before authenticating to ECR.
assumed before authenticating to ECR. An error will occur if `aws_role_arns`
is also specified. This is kept for backward compatibility.

* `aws_role_arns`: *Optional. Default `""`.* An array of AWS IAM roles.
If set, these roles will be assumed in the specified order before authenticating to ECR.
An error will occur if `aws_role_arn` is also specified.

* `debug`: *Optional. Default `false`.* If set, progress bars will be disabled
and debugging output will be printed instead.
Expand Down Expand Up @@ -110,7 +115,7 @@ differences:
This is used to validate the certificate of the docker registry when the
registry's certificate is signed by a custom authority (or itself).
### Signing with Docker Hub
### Signing with Docker Hub
Configure Docker Content Trust for use with the [Docker Hub](https:/hub.docker.io) and Notary service by specifying the above source parameters as follows:
Expand Down Expand Up @@ -265,7 +270,7 @@ Fetches an image at the exact digest specified by the version.

The resource will produce the following files:

* `./repository`: A file containing the image's full repository name, e.g. `concourse/concourse`.
* `./repository`: A file containing the image's full repository name, e.g. `concourse/concourse`.
For ECR images, this will include the registry the image was pulled from.
* `./tag`: A file containing the tag from the version.
* `./digest`: A file containing the digest from the version, e.g. `sha256:...`.
Expand Down
37 changes: 26 additions & 11 deletions types.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,12 +55,13 @@ type OutResponse struct {
}

type AwsCredentials struct {
AwsAccessKeyId string `json:"aws_access_key_id,omitempty"`
AwsSecretAccessKey string `json:"aws_secret_access_key,omitempty"`
AwsSessionToken string `json:"aws_session_token,omitempty"`
AwsRegion string `json:"aws_region,omitempty"`
AWSECRRegistryId string `json:"aws_ecr_registry_id,omitempty"`
AwsRoleArn string `json:"aws_role_arn,omitempty"`
AwsAccessKeyId string `json:"aws_access_key_id,omitempty"`
AwsSecretAccessKey string `json:"aws_secret_access_key,omitempty"`
AwsSessionToken string `json:"aws_session_token,omitempty"`
AwsRegion string `json:"aws_region,omitempty"`
AWSECRRegistryId string `json:"aws_ecr_registry_id,omitempty"`
AwsRoleArn string `json:"aws_role_arn,omitempty"`
AwsRoleArns []string `json:"aws_role_arns,omitempty"`
}

type BasicCredentials struct {
Expand Down Expand Up @@ -278,19 +279,33 @@ func (source *Source) Metadata() []MetadataField {

func (source *Source) AuthenticateToECR() bool {
logrus.Warnln("ECR integration is experimental and untested")

if source.AwsRoleArn != "" && len(source.AwsRoleArns) != 0 {
logrus.Errorf("`aws_role_arn` cannot be set at the same time as `aws_role_arns`")
return false
}

mySession := session.Must(session.NewSession(&aws.Config{
Region: aws.String(source.AwsRegion),
Credentials: credentials.NewStaticCredentials(source.AwsAccessKeyId, source.AwsSecretAccessKey, source.AwsSessionToken),
}))

var config aws.Config

// If a role arn has been supplied, then assume role and get a new session
// Note: This implementation gives precedence to `aws_role_arn` since it
// assumes that we've errored if both `aws_role_arn` and `aws_role_arns`
// are set
awsRoleArns := source.AwsRoleArns
if source.AwsRoleArn != "" {
config = aws.Config{Credentials: stscreds.NewCredentials(mySession, source.AwsRoleArn)}
awsRoleArns = []string{source.AwsRoleArn}
}
for _, roleArn := range awsRoleArns {
logrus.Debugf("assuming new role: %s", roleArn)
mySession = session.Must(session.NewSession(&aws.Config{
Region: aws.String(source.AwsRegion),
Credentials: stscreds.NewCredentials(mySession, roleArn),
}))
}

client := ecr.New(mySession, &config)
client := ecr.New(mySession)
result, err := source.GetECRAuthorizationToken(client)
if err != nil {
logrus.Errorf("failed to authenticate to ECR: %s", err)
Expand Down

0 comments on commit 4372334

Please sign in to comment.