EC2 service discovery: reuse EC2 client instead of recreating it every time (#8311)

This also caches credentials that are obtained e.g. via IRSA on AWS EKS.
Previously, every refresh cycle would request the credentials again.

Signed-off-by: Alfred Krohmer <alfred.krohmer@logmein.com>
This commit is contained in:
Alfred Krohmer 2020-12-22 16:47:44 +01:00 committed by GitHub
parent faa1554aa1
commit 4efca5ab70
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -129,12 +129,11 @@ func (c *SDConfig) UnmarshalYAML(unmarshal func(interface{}) error) error {
// the Discoverer interface. // the Discoverer interface.
type Discovery struct { type Discovery struct {
*refresh.Discovery *refresh.Discovery
aws *aws.Config region string
interval time.Duration interval time.Duration
profile string
roleARN string
port int port int
filters []*Filter filters []*Filter
ec2 *ec2.EC2
} }
// NewDiscovery returns a new EC2Discovery which periodically refreshes its targets. // NewDiscovery returns a new EC2Discovery which periodically refreshes its targets.
@ -146,17 +145,33 @@ func NewDiscovery(conf *SDConfig, logger log.Logger) *Discovery {
if logger == nil { if logger == nil {
logger = log.NewNopLogger() logger = log.NewNopLogger()
} }
d := &Discovery{
aws: &aws.Config{ sess, err := session.NewSessionWithOptions(session.Options{
Config: aws.Config{
Endpoint: &conf.Endpoint, Endpoint: &conf.Endpoint,
Region: &conf.Region, Region: &conf.Region,
Credentials: creds, Credentials: creds,
}, },
profile: conf.Profile, Profile: conf.Profile,
roleARN: conf.RoleARN, })
if err != nil {
return nil
}
var ec2s *ec2.EC2
if conf.RoleARN != "" {
creds := stscreds.NewCredentials(sess, conf.RoleARN)
ec2s = ec2.New(sess, &aws.Config{Credentials: creds})
} else {
ec2s = ec2.New(sess)
}
d := &Discovery{
region: conf.Region,
filters: conf.Filters, filters: conf.Filters,
interval: time.Duration(conf.RefreshInterval), interval: time.Duration(conf.RefreshInterval),
port: conf.Port, port: conf.Port,
ec2: ec2s,
} }
d.Discovery = refresh.NewDiscovery( d.Discovery = refresh.NewDiscovery(
logger, logger,
@ -168,23 +183,8 @@ func NewDiscovery(conf *SDConfig, logger log.Logger) *Discovery {
} }
func (d *Discovery) refresh(ctx context.Context) ([]*targetgroup.Group, error) { func (d *Discovery) refresh(ctx context.Context) ([]*targetgroup.Group, error) {
sess, err := session.NewSessionWithOptions(session.Options{
Config: *d.aws,
Profile: d.profile,
})
if err != nil {
return nil, errors.Wrap(err, "could not create aws session")
}
var ec2s *ec2.EC2
if d.roleARN != "" {
creds := stscreds.NewCredentials(sess, d.roleARN)
ec2s = ec2.New(sess, &aws.Config{Credentials: creds})
} else {
ec2s = ec2.New(sess)
}
tg := &targetgroup.Group{ tg := &targetgroup.Group{
Source: *d.aws.Region, Source: d.region,
} }
var filters []*ec2.Filter var filters []*ec2.Filter
@ -197,7 +197,7 @@ func (d *Discovery) refresh(ctx context.Context) ([]*targetgroup.Group, error) {
input := &ec2.DescribeInstancesInput{Filters: filters} input := &ec2.DescribeInstancesInput{Filters: filters}
if err = ec2s.DescribeInstancesPagesWithContext(ctx, input, func(p *ec2.DescribeInstancesOutput, lastPage bool) bool { if err := d.ec2.DescribeInstancesPagesWithContext(ctx, input, func(p *ec2.DescribeInstancesOutput, lastPage bool) bool {
for _, r := range p.Reservations { for _, r := range p.Reservations {
for _, inst := range r.Instances { for _, inst := range r.Instances {
if inst.PrivateIpAddress == nil { if inst.PrivateIpAddress == nil {