Read AWS Region from EC2 Metadata

Tackles kubernetes/autoscaler#1208. EC2 Metadata helpfully supplies AWS
Region info, so rather than _requiring_ an environment variable, this
patch enables `aws_manager.go` to retrieve that information from EC2
itself.

Example YAMLs no longer reference the vestigial `AWS_REGION` environment
variable, but supplying it to `cluster-autoscaler` still relays it to
the AWS SDK like before.
This commit is contained in:
Shatil Rafiullah 2018-09-28 22:45:34 -07:00
parent e14f2670e9
commit a36f8007af
6 changed files with 44 additions and 13 deletions

View File

@ -22,11 +22,13 @@ import (
"fmt"
"io"
"math/rand"
"os"
"regexp"
"strings"
"time"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/ec2metadata"
"github.com/aws/aws-sdk-go/aws/session"
"github.com/aws/aws-sdk-go/service/autoscaling"
"github.com/aws/aws-sdk-go/service/ec2"
@ -64,6 +66,18 @@ type asgTemplate struct {
Tags []*autoscaling.TagDescription
}
// getRegion deduces the current AWS Region.
func getRegion(cfg ...*aws.Config) string {
region, present := os.LookupEnv("AWS_REGION")
if !present {
svc := ec2metadata.New(session.New(), cfg...)
if r, err := svc.Region(); err == nil {
region = r
}
}
return region
}
// createAwsManagerInternal allows for a customer autoScalingWrapper to be passed in by tests
func createAWSManagerInternal(
configReader io.Reader,
@ -80,7 +94,7 @@ func createAWSManagerInternal(
}
if autoScalingService == nil || ec2Service == nil {
sess := session.New()
sess := session.New(aws.NewConfig().WithRegion(getRegion()))
if autoScalingService == nil {
autoScalingService = &autoScalingWrapper{autoscaling.New(sess)}

View File

@ -18,6 +18,9 @@ package aws
import (
"fmt"
"net/http"
"net/http/httptest"
"os"
"testing"
"github.com/aws/aws-sdk-go/aws"
@ -30,6 +33,32 @@ import (
kubeletapis "k8s.io/kubernetes/pkg/kubelet/apis"
)
// TestGetRegion ensures correct source supplies AWS Region.
func TestGetRegion(t *testing.T) {
key := "AWS_REGION"
originalRegion, originalPresent := os.LookupEnv(key)
defer func(region string, present bool) {
os.Unsetenv(key)
if present {
os.Setenv(key, region)
}
}(originalRegion, originalPresent)
// Ensure environment variable retains precedence.
expected1 := "the-shire-1"
os.Setenv(key, expected1)
assert.Equal(t, expected1, getRegion())
// Ensure without environment variable, EC2 Metadata used... and it merely
// chops the last character off the Availability Zone.
expected2 := "mordor-2"
expected2a := expected2 + "a"
os.Unsetenv(key)
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte(expected2a))
}))
cfg := aws.NewConfig().WithEndpoint(server.URL)
assert.Equal(t, expected2, getRegion(cfg))
}
func TestBuildGenericLabels(t *testing.T) {
labels := buildGenericLabels(&asgTemplate{
InstanceType: &instanceType{

View File

@ -138,9 +138,6 @@ spec:
- --skip-nodes-with-local-storage=false
- --expander=least-waste
- --node-group-auto-discovery=asg:tag=k8s.io/cluster-autoscaler/enabled,k8s.io/cluster-autoscaler/<YOUR CLUSTER NAME>
env:
- name: AWS_REGION
value: us-east-1
volumeMounts:
- name: ssl-certs
mountPath: /etc/ssl/certs/ca-certificates.crt

View File

@ -139,9 +139,6 @@ spec:
- --expander=least-waste
- --nodes=1:10:k8s-worker-asg-1
- --nodes=1:3:k8s-worker-asg-2
env:
- name: AWS_REGION
value: us-east-1
volumeMounts:
- name: ssl-certs
mountPath: /etc/ssl/certs/ca-certificates.crt

View File

@ -137,9 +137,6 @@ spec:
- --cloud-provider=aws
- --skip-nodes-with-local-storage=false
- --nodes=1:10:k8s-worker-asg-1
env:
- name: AWS_REGION
value: us-east-1
volumeMounts:
- name: ssl-certs
mountPath: /etc/ssl/certs/ca-certificates.crt

View File

@ -144,9 +144,6 @@ spec:
- --cloud-provider=aws
- --skip-nodes-with-local-storage=false
- --nodes={{ node_asg_min }}:{{ node_asg_max }}:{{ name }}
env:
- name: AWS_REGION
value: {{ region }}
volumeMounts:
- name: ssl-certs
mountPath: /etc/ssl/certs/ca-certificates.crt