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

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 {