Skip to content

Commit 79c824f

Browse files
committed
Use DescribeInstance to retrieve filtered AWS instances
initial implementation for issue #28
1 parent f06d6ab commit 79c824f

File tree

9 files changed

+47
-14495
lines changed

9 files changed

+47
-14495
lines changed

Gopkg.lock

Lines changed: 2 additions & 6 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

cmd/sync/aws.go

Lines changed: 39 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -6,20 +6,17 @@ import (
66
"time"
77

88
"github.com/aws/aws-sdk-go/aws"
9-
"github.com/aws/aws-sdk-go/aws/session"
109
"github.com/aws/aws-sdk-go/aws/ec2metadata"
11-
"github.com/aws/aws-sdk-go/service/autoscaling"
12-
"github.com/aws/aws-sdk-go/service/autoscaling/autoscalingiface"
10+
"github.com/aws/aws-sdk-go/aws/session"
1311
"github.com/aws/aws-sdk-go/service/ec2"
1412
"github.com/aws/aws-sdk-go/service/ec2/ec2iface"
1513
yaml "gopkg.in/yaml.v2"
1614
)
1715

1816
// AWSClient allows you to get the list of IP addresses of instanes of an Auto Scaling group. It implements the CloudProvider interface
1917
type AWSClient struct {
20-
svcEC2 ec2iface.EC2API
21-
svcAutoscaling autoscalingiface.AutoScalingAPI
22-
config *awsConfig
18+
svcEC2 ec2iface.EC2API
19+
config *awsConfig
2320
}
2421

2522
// NewAWSClient creates and configures an AWSClient
@@ -38,7 +35,7 @@ func NewAWSClient(data []byte) (*AWSClient, error) {
3835
if err != nil {
3936
return nil, err
4037
}
41-
38+
4239
metaClient := ec2metadata.New(metaSession)
4340
if !metaClient.Available() {
4441
return nil, fmt.Errorf("ec2metadata service is unavailable")
@@ -86,10 +83,8 @@ func (client *AWSClient) configure() error {
8683
return err
8784
}
8885

89-
svcAutoscaling := autoscaling.New(session)
9086
svcEC2 := ec2.New(session)
9187
client.svcEC2 = svcEC2
92-
client.svcAutoscaling = svcAutoscaling
9388
return nil
9489
}
9590

@@ -111,79 +106,58 @@ func parseAWSConfig(data []byte) (*awsConfig, error) {
111106

112107
// CheckIfScalingGroupExists checks if the Auto Scaling group exists
113108
func (client *AWSClient) CheckIfScalingGroupExists(name string) (bool, error) {
114-
_, exists, err := client.getAutoscalingGroup(name)
115-
if err != nil {
116-
return exists, fmt.Errorf("couldn't check if an AutoScaling group exists: %v", err)
117-
}
118-
return exists, nil
119-
}
120-
121-
// GetPrivateIPsForScalingGroup returns the list of IP addresses of instances of the Auto Scaling group
122-
func (client *AWSClient) GetPrivateIPsForScalingGroup(name string) ([]string, error) {
123-
group, exists, err := client.getAutoscalingGroup(name)
124-
if err != nil {
125-
return nil, err
126-
}
127-
128-
if !exists {
129-
return nil, fmt.Errorf("autoscaling group %v doesn't exist", name)
109+
params := &ec2.DescribeInstancesInput{
110+
Filters: []*ec2.Filter{
111+
&ec2.Filter{
112+
Name: aws.String("tag:aws:autoscaling:groupName"),
113+
Values: []*string{
114+
aws.String(name),
115+
},
116+
},
117+
},
130118
}
131119

132-
instances, err := client.getInstancesOfAutoscalingGroup(group)
120+
response, err := client.svcEC2.DescribeInstances(params)
133121
if err != nil {
134-
return nil, err
122+
return false, fmt.Errorf("couldn't check if an AutoScaling group exists: %v", err)
135123
}
136124

137-
var result []string
138-
for _, ins := range instances {
139-
if len(ins.NetworkInterfaces) > 0 && ins.NetworkInterfaces[0].PrivateIpAddress != nil {
140-
result = append(result, *ins.NetworkInterfaces[0].PrivateIpAddress)
141-
}
125+
if len(response.Reservations) == 0 {
126+
return false, nil
142127
}
143128

144-
return result, nil
129+
return true, nil
145130
}
146131

147-
func (client *AWSClient) getAutoscalingGroup(name string) (*autoscaling.Group, bool, error) {
148-
params := &autoscaling.DescribeAutoScalingGroupsInput{
149-
AutoScalingGroupNames: []*string{
150-
aws.String(name),
132+
// GetPrivateIPsForScalingGroup returns the list of IP addresses of instances of the Auto Scaling group
133+
func (client *AWSClient) GetPrivateIPsForScalingGroup(name string) ([]string, error) {
134+
params := &ec2.DescribeInstancesInput{
135+
Filters: []*ec2.Filter{
136+
&ec2.Filter{
137+
Name: aws.String("tag:aws:autoscaling:groupName"),
138+
Values: []*string{
139+
aws.String(name),
140+
},
141+
},
151142
},
152143
}
153144

154-
resp, err := client.svcAutoscaling.DescribeAutoScalingGroups(params)
145+
response, err := client.svcEC2.DescribeInstances(params)
155146
if err != nil {
156-
return nil, false, err
157-
}
158-
159-
if len(resp.AutoScalingGroups) != 1 {
160-
return nil, false, nil
161-
}
162-
163-
return resp.AutoScalingGroups[0], true, nil
164-
}
165-
166-
func (client *AWSClient) getInstancesOfAutoscalingGroup(group *autoscaling.Group) ([]*ec2.Instance, error) {
167-
var result []*ec2.Instance
168-
169-
if len(group.Instances) == 0 {
170-
return result, nil
147+
return nil, err
171148
}
172149

173-
var ids []*string
174-
for _, ins := range group.Instances {
175-
ids = append(ids, ins.InstanceId)
176-
}
177-
params := &ec2.DescribeInstancesInput{
178-
InstanceIds: ids,
150+
if len(response.Reservations) == 0 {
151+
return nil, fmt.Errorf("autoscaling group %v doesn't exist", name)
179152
}
180153

181-
resp, err := client.svcEC2.DescribeInstances(params)
182-
if err != nil {
183-
return result, err
184-
}
185-
for _, res := range resp.Reservations {
186-
result = append(result, res.Instances...)
154+
var result []string
155+
for _, res := range response.Reservations {
156+
for _, ins := range res.Instances {
157+
if len(ins.NetworkInterfaces) > 0 && ins.NetworkInterfaces[0].PrivateIpAddress != nil {
158+
result = append(result, *ins.NetworkInterfaces[0].PrivateIpAddress)
159+
}
160+
}
187161
}
188162

189163
return result, nil

examples/aws.md

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,10 @@ upstreams:
2626
autoscaling_group: backend-two-group
2727
port: 80
2828
kind: http
29+
- name: backend
30+
autoscaling_group: backend-*
31+
port: 80
32+
kind: http
2933
```
3034
3135
* The `api_endpoint` key defines the NGINX Plus API endpoint.
@@ -34,6 +38,6 @@ upstreams:
3438
* The `region` key defines the AWS region where we deploy NGINX Plus and the Auto Scaling groups. Setting `region` to `self` will use the EC2 Metadata service to retreive the region of the current instance.
3539
* The `upstreams` key defines the list of upstream groups. For each upstream group we specify:
3640
* `name` – The name we specified for the upstream block in the NGINX Plus configuration.
37-
* `autoscaling_group` – The name of the corresponding Auto Scaling group.
41+
* `autoscaling_group` – The name of the corresponding Auto Scaling group. Use of wildcards is supported.
3842
* `port` – The port on which our backend applications are exposed.
39-
* `kind` – The protocol of the traffic NGINX Plus load balances to the backend application, here `http`. If the application uses TCP/UDP, specify `stream` instead.
43+
* `kind` – The protocol of the traffic NGINX Plus load balances to the backend application, here `http`. If the application uses TCP/UDP, specify `stream` instead.

0 commit comments

Comments
 (0)