Skip to content

Commit

Permalink
Merge pull request #142 from Clever/INFRANG-6695
Browse files Browse the repository at this point in the history
[INFRANG-6695] Update goci to use OIDC
  • Loading branch information
andruwm authored Jan 7, 2025
2 parents aabd13c + 7b3985c commit 37cd3c6
Show file tree
Hide file tree
Showing 5 changed files with 46 additions and 25 deletions.
2 changes: 1 addition & 1 deletion cmd/goci/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ of each application.

# Multi-app Support

goci will automatically detect all laucn configs in the `launch`
goci will automatically detect all launch configs in the `launch`
directory, then perform the following actions as needed.

1. detect the run type of the application
Expand Down
2 changes: 1 addition & 1 deletion internal/docker/docker.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ func New(ctx context.Context) (*Docker, error) {
}
d := &Docker{
cli: cl,
awsCfg: environment.AWSCfg(ctx, environment.ECRAccessKeyID, environment.ECRSecretAccessKey),
awsCfg: environment.AWSCfg(ctx, environment.OidcEcrUploadRole),
}

grp, ctx := errgroup.WithContext(ctx)
Expand Down
57 changes: 38 additions & 19 deletions internal/environment/environment.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ import (

"github.com/aws/aws-sdk-go-v2/aws"
"github.com/aws/aws-sdk-go-v2/config"
"github.com/aws/aws-sdk-go-v2/credentials"
"github.com/aws/aws-sdk-go-v2/credentials/stscreds"
"github.com/aws/aws-sdk-go-v2/service/sts"
)

var (
Expand All @@ -19,25 +20,13 @@ var (
// ShortSHA1 is the first 7 characters of the git commit SHA being
// built in CI.
ShortSHA1 = FullSHA1[:7]
// ECRAccessKeyID is the AWS access key ID which has correct
// permissions to upload images to ECR.
ECRAccessKeyID = envMustString("ECR_PUSH_ID", false)
// ECRSecretAccessKey is the AWS secret key which has correct
// permissions to upload images to ECR.
ECRSecretAccessKey = envMustString("ECR_PUSH_SECRET", false)
// LambdaArtifactBucketPrefix is the prefix of the S3 buckets which
// hold Clever's lambda artifacts. There are 4 total – one for each
// region. The naming scheme is '<prefix>-<region>'
LambdaArtifactBucketPrefix = envMustString("LAMBDA_AWS_BUCKET", true)
// CatapultURL is the dns of the circle-ci-integrations ALB
// including the protocol.
CatapultURL = envMustString("CATAPULT_URL", true)
// LambdaAccessKeyID is the AWS access key ID which has correct
// permissions to upload to S3 lambda artifact buckets.
LambdaAccessKeyID = envMustString("LAMBDA_AWS_ACCESS_KEY_ID", false)
// LambdaSecretAccessKey is the AWS secret key which has correct
// permissions to upload to S3 lambda artifact buckets.
LambdaSecretAccessKey = envMustString("LAMBDA_AWS_SECRET_ACCESS_KEY", false)
// CatapultUser is the username to access circle-ci-integrations via
// basic auth.
CatapultUser = envMustString("CATAPULT_USER", true)
Expand All @@ -54,31 +43,61 @@ var (
CircleBuildNum = envMustInt64("CIRCLE_BUILD_NUM", true)
// Branch is the git branch being built in CI.
Branch = envMustString("CIRCLE_BRANCH", true)
// OidcLambdaRole is the ARN of the role used to assume the lambda
// publishing role.
OidcLambdaRole = envMustString("OIDC_LAMBDA_ROLE", false)
// OidcEcrUploadRole is the ARN of the role used to assume the ecr
// upload role.
OidcEcrUploadRole = envMustString("OIDC_ECR_UPLOAD_ROLE", false)
// circleOidcTokenV2 is the oidc token used to assume roles in CI.
// It is provided by circle-ci.
circleOidcTokenV2 = envMustString("CIRCLE_OIDC_TOKEN_V2", false)

// Regions is the set of regions this app should perform
// operations in.
Regions = []string{"us-west-1", "us-west-2", "us-east-1", "us-east-2"}
Regions = []string{"us-west-1", "us-west-2", "us-east-1"}

// Local is a boolean which should be set to true when running
// locally on a developers machine.
Local = os.Getenv("LOCAL") == "true"
)

// AWS doesn't provide a way to get the token from a string so we will
// use this to satisfy the interface.
type tokenRetriever struct{}

func (tokenRetriever) GetIdentityToken() ([]byte, error) {
return []byte(circleOidcTokenV2), nil
}

// AWSCfg initializes an AWS config or exits with code 0 on failure. If
// this app is run locally, then this function automatically pulls
// config from the default credential chain which can be populated with
// saml2aws. If not run locally, then the passed in id and secret key
// are used with a static credentials provider.
func AWSCfg(ctx context.Context, accessKeyID, secretKey string) aws.Config {
// saml2aws. If not run locally, then the passed role and profile are
// used with oidc in circle ci.
func AWSCfg(ctx context.Context, oidcRole string) aws.Config {
opts := []func(*config.LoadOptions) error{
config.WithRegion("us-west-1"),
config.WithRegion("us-west-2"),
}

// In local environment we use the default credentials chain that
// will automatically pull creds from saml2aws,
if !Local {
stsCfg, err := config.LoadDefaultConfig(ctx, opts...)
if err != nil {
fmt.Println("failed to load aws sts config:", err)
os.Exit(1)
}

opts = append(opts, config.WithCredentialsProvider(
credentials.NewStaticCredentialsProvider(accessKeyID, secretKey, ""),
stscreds.NewWebIdentityRoleProvider(
sts.NewFromConfig(stsCfg),
oidcRole,
tokenRetriever{},
func(o *stscreds.WebIdentityRoleOptions) {
o.RoleSessionName = "oidc-goci-role-session"
},
),
))
}

Expand Down
2 changes: 1 addition & 1 deletion internal/lambda/lambda.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ type Lambda struct {
// New initializes a new Lambda handling wrapper with it's s3 client.
func New(ctx context.Context) *Lambda {
return &Lambda{
awsCfg: environment.AWSCfg(ctx, environment.LambdaAccessKeyID, environment.LambdaSecretAccessKey),
awsCfg: environment.AWSCfg(ctx, environment.OidcLambdaRole),
}
}

Expand Down
8 changes: 5 additions & 3 deletions internal/repo/repo.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,6 @@ func DiscoverApplications(dir string) (map[string]*models.LaunchConfig, error) {
if f.IsDir() {
continue
}
if strings.HasSuffix(f.Name(), "-db.yml") {
continue
}
if path.Ext(f.Name()) != ".yml" {
continue
}
Expand All @@ -47,6 +44,11 @@ func DiscoverApplications(dir string) (map[string]*models.LaunchConfig, error) {
return nil, fmt.Errorf("failed to unmarshal yaml in %s: %v", f.Name(), err)
}

// These are DB launch configs, which we don't want to build.
if lc.PodConfig == nil || lc.PodConfig.Group == "" {
continue
}

m[strings.TrimSuffix(f.Name(), ".yml")] = &lc
}

Expand Down

0 comments on commit 37cd3c6

Please sign in to comment.