diff --git a/discovery/aws/aws.go b/discovery/aws/aws.go index 3d0c246199..c9f2ca2ec6 100644 --- a/discovery/aws/aws.go +++ b/discovery/aws/aws.go @@ -77,6 +77,7 @@ type SDConfig struct { SecretKey config.Secret `yaml:"secret_key,omitempty"` Profile string `yaml:"profile,omitempty"` RoleARN string `yaml:"role_arn,omitempty"` + ExternalID string `yaml:"external_id,omitempty"` RefreshInterval model.Duration `yaml:"refresh_interval,omitempty"` Port int `yaml:"port,omitempty"` HTTPClientConfig config.HTTPClientConfig `yaml:",inline"` @@ -136,6 +137,9 @@ func (c *SDConfig) UnmarshalYAML(unmarshal func(any) error) error { if c.RoleARN != "" { c.EC2SDConfig.RoleARN = c.RoleARN } + if c.ExternalID != "" { + c.EC2SDConfig.ExternalID = c.ExternalID + } if c.Port != 0 { c.EC2SDConfig.Port = c.Port } @@ -167,6 +171,9 @@ func (c *SDConfig) UnmarshalYAML(unmarshal func(any) error) error { if c.RoleARN != "" { c.ECSSDConfig.RoleARN = c.RoleARN } + if c.ExternalID != "" { + c.ECSSDConfig.ExternalID = c.ExternalID + } if c.Port != 0 { c.ECSSDConfig.Port = c.Port } @@ -198,6 +205,9 @@ func (c *SDConfig) UnmarshalYAML(unmarshal func(any) error) error { if c.RoleARN != "" { c.ElasticacheSDConfig.RoleARN = c.RoleARN } + if c.ExternalID != "" { + c.ElasticacheSDConfig.ExternalID = c.ExternalID + } if c.Port != 0 { c.ElasticacheSDConfig.Port = c.Port } @@ -229,6 +239,9 @@ func (c *SDConfig) UnmarshalYAML(unmarshal func(any) error) error { if c.RoleARN != "" { c.LightsailSDConfig.RoleARN = c.RoleARN } + if c.ExternalID != "" { + c.LightsailSDConfig.ExternalID = c.ExternalID + } if c.Port != 0 { c.LightsailSDConfig.Port = c.Port } @@ -257,6 +270,9 @@ func (c *SDConfig) UnmarshalYAML(unmarshal func(any) error) error { if c.RoleARN != "" { c.MSKSDConfig.RoleARN = c.RoleARN } + if c.ExternalID != "" { + c.MSKSDConfig.ExternalID = c.ExternalID + } if c.Port != 0 { c.MSKSDConfig.Port = c.Port } @@ -288,6 +304,9 @@ func (c *SDConfig) UnmarshalYAML(unmarshal func(any) error) error { if c.RoleARN != "" { c.RDSSDConfig.RoleARN = c.RoleARN } + if c.ExternalID != "" { + c.RDSSDConfig.ExternalID = c.ExternalID + } if c.Port != 0 { c.RDSSDConfig.Port = c.Port } diff --git a/discovery/aws/ecs.go b/discovery/aws/ecs.go index 0c2fd443fa..ff751ff414 100644 --- a/discovery/aws/ecs.go +++ b/discovery/aws/ecs.go @@ -99,6 +99,7 @@ type ECSSDConfig struct { SecretKey config.Secret `yaml:"secret_key,omitempty"` Profile string `yaml:"profile,omitempty"` RoleARN string `yaml:"role_arn,omitempty"` + ExternalID string `yaml:"external_id,omitempty"` Clusters []string `yaml:"clusters,omitempty"` Port int `yaml:"port"` RefreshInterval model.Duration `yaml:"refresh_interval,omitempty"` @@ -241,7 +242,11 @@ func (d *ECSDiscovery) initEcsClient(ctx context.Context) error { // If the role ARN is set, assume the role to get credentials and set the credentials provider in the config. if d.cfg.RoleARN != "" { - assumeProvider := stscreds.NewAssumeRoleProvider(sts.NewFromConfig(cfg), d.cfg.RoleARN) + assumeProvider := stscreds.NewAssumeRoleProvider(sts.NewFromConfig(cfg), d.cfg.RoleARN, func(o *stscreds.AssumeRoleOptions) { + if d.cfg.ExternalID != "" { + o.ExternalID = aws.String(d.cfg.ExternalID) + } + }) cfg.Credentials = aws.NewCredentialsCache(assumeProvider) } diff --git a/discovery/aws/elasticache.go b/discovery/aws/elasticache.go index 206374fce3..f65834a079 100644 --- a/discovery/aws/elasticache.go +++ b/discovery/aws/elasticache.go @@ -192,6 +192,7 @@ type ElasticacheSDConfig struct { SecretKey config.Secret `yaml:"secret_key,omitempty"` Profile string `yaml:"profile,omitempty"` RoleARN string `yaml:"role_arn,omitempty"` + ExternalID string `yaml:"external_id,omitempty"` Clusters []string `yaml:"clusters,omitempty"` Port int `yaml:"port"` RefreshInterval model.Duration `yaml:"refresh_interval,omitempty"` @@ -319,7 +320,11 @@ func (d *ElasticacheDiscovery) initElasticacheClient(ctx context.Context) error // If the role ARN is set, assume the role to get credentials and set the credentials provider in the config. if d.cfg.RoleARN != "" { - assumeProvider := stscreds.NewAssumeRoleProvider(sts.NewFromConfig(cfg), d.cfg.RoleARN) + assumeProvider := stscreds.NewAssumeRoleProvider(sts.NewFromConfig(cfg), d.cfg.RoleARN, func(o *stscreds.AssumeRoleOptions) { + if d.cfg.ExternalID != "" { + o.ExternalID = aws.String(d.cfg.ExternalID) + } + }) cfg.Credentials = aws.NewCredentialsCache(assumeProvider) } diff --git a/discovery/aws/msk.go b/discovery/aws/msk.go index 782574c0a9..bff8337576 100644 --- a/discovery/aws/msk.go +++ b/discovery/aws/msk.go @@ -106,6 +106,7 @@ type MSKSDConfig struct { SecretKey config.Secret `yaml:"secret_key,omitempty"` Profile string `yaml:"profile,omitempty"` RoleARN string `yaml:"role_arn,omitempty"` + ExternalID string `yaml:"external_id,omitempty"` Clusters []string `yaml:"clusters,omitempty"` Port int `yaml:"port"` RefreshInterval model.Duration `yaml:"refresh_interval,omitempty"` @@ -231,7 +232,11 @@ func (d *MSKDiscovery) initMskClient(ctx context.Context) error { // If the role ARN is set, assume the role to get credentials and set the credentials provider in the config. if d.cfg.RoleARN != "" { - assumeProvider := stscreds.NewAssumeRoleProvider(sts.NewFromConfig(cfg), d.cfg.RoleARN) + assumeProvider := stscreds.NewAssumeRoleProvider(sts.NewFromConfig(cfg), d.cfg.RoleARN, func(o *stscreds.AssumeRoleOptions) { + if d.cfg.ExternalID != "" { + o.ExternalID = aws.String(d.cfg.ExternalID) + } + }) cfg.Credentials = aws.NewCredentialsCache(assumeProvider) } diff --git a/discovery/aws/rds.go b/discovery/aws/rds.go index 603817831b..438338b060 100644 --- a/discovery/aws/rds.go +++ b/discovery/aws/rds.go @@ -225,6 +225,7 @@ type RDSSDConfig struct { SecretKey config.Secret `yaml:"secret_key,omitempty"` Profile string `yaml:"profile,omitempty"` RoleARN string `yaml:"role_arn,omitempty"` + ExternalID string `yaml:"external_id,omitempty"` Clusters []string `yaml:"clusters,omitempty"` Port int `yaml:"port"` RefreshInterval model.Duration `yaml:"refresh_interval,omitempty"` @@ -349,7 +350,11 @@ func (d *RDSDiscovery) initRdsClient(ctx context.Context) error { // If the role ARN is set, assume the role to get credentials and set the credentials provider in the config. if d.cfg.RoleARN != "" { - assumeProvider := stscreds.NewAssumeRoleProvider(sts.NewFromConfig(cfg), d.cfg.RoleARN) + assumeProvider := stscreds.NewAssumeRoleProvider(sts.NewFromConfig(cfg), d.cfg.RoleARN, func(o *stscreds.AssumeRoleOptions) { + if d.cfg.ExternalID != "" { + o.ExternalID = aws.String(d.cfg.ExternalID) + } + }) cfg.Credentials = aws.NewCredentialsCache(assumeProvider) } diff --git a/docs/configuration/configuration.md b/docs/configuration/configuration.md index c0cc50404d..70a6a693c8 100644 --- a/docs/configuration/configuration.md +++ b/docs/configuration/configuration.md @@ -1330,6 +1330,9 @@ role: # AWS Role ARN, an alternative to using AWS API keys. [ role_arn: ] +# Optional External ID that can go along with role_arn. +[ external_id: ] + # Refresh interval to re-read the targets list. [ refresh_interval: | default = 60s ]