Skip to content
This repository has been archived by the owner on Dec 12, 2024. It is now read-only.

Commit

Permalink
Merge pull request #8 from 3scale/feat/enable-service-account-iam-rol…
Browse files Browse the repository at this point in the history
…e-auth

feat: enable IAM role based AWS authentication
  • Loading branch information
raelga authored Sep 28, 2020
2 parents ae69b40 + e738e08 commit d14cf73
Show file tree
Hide file tree
Showing 12 changed files with 175 additions and 19 deletions.
11 changes: 10 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,18 @@ some extra annotations to the kubernetes service objects.
| Target Group Stickness | `aws-nlb-helper.3scale.net/enable-targetgroups-stickness` | `true`, `false` | `false` |
| Target Group Deregistration Delay | `aws-nlb-helper.3scale.net/targetgroups-deregisration-delay` | `0-3600` | `300` |

## AWS authentication

By default, the operator will use the role provided by the service acccount to
connect to the AWS API. The YAMLs for deploying using [IAM roles for service accounts](https://docs.aws.amazon.com/eks/latest/userguide/iam-roles-for-service-accounts.html) are available at [deploy/iam-service-accocunt](deploy/iam-service-accocunt).

Otherwise, if the environment variables `AWS_ACCESS_KEY_ID` and `AWS_SECRET_ACCESS_KEY` are set,
the operator will use them to interact with the AWS API. You can find the YAMLs
for deploying the resources using the environment access keys at [deploy/iam-env-credentials](deploy/iam-env-credentials).

## Requirements

### Secret with IAM credentials
### Secret with IAM credentials (when using env based credentials)

```yaml
kind: Secret
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
48 changes: 48 additions & 0 deletions deploy/iam-service-accocunt/operator.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: aws-nlb-helper-operator
spec:
replicas: 1
selector:
matchLabels:
name: aws-nlb-helper-operator
template:
metadata:
labels:
name: aws-nlb-helper-operator
spec:
serviceAccountName: aws-nlb-helper-operator
containers:
- name: aws-nlb-helper-operator
# Replace this with the built image name
image: REPLACE_IMAGE
command:
- aws-nlb-helper-operator
imagePullPolicy: Always
env:
- name: OPERATOR_NAME
value: "aws-nlb-helper-operator"
- name: WATCH_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: AWS_REGION
valueFrom:
secretKeyRef:
name: aws-nlb-helper-iam
key: AWS_REGION
resources:
limits:
cpu: 150m
memory: 128Mi
requests:
cpu: 50m
memory: 64Mi
securityContext:
# Required for accessing the service acccount token
fsGroup: 65534
67 changes: 67 additions & 0 deletions deploy/iam-service-accocunt/role.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: aws-nlb-helper-operator
rules:
- apiGroups:
- ""
resources:
- pods
- services
- services/finalizers
- endpoints
- persistentvolumeclaims
- events
- configmaps
- secrets
verbs:
- create
- delete
- get
- list
- patch
- update
- watch
- apiGroups:
- apps
resources:
- deployments
- daemonsets
- replicasets
- statefulsets
verbs:
- create
- delete
- get
- list
- patch
- update
- watch
- apiGroups:
- monitoring.coreos.com
resources:
- servicemonitors
verbs:
- "get"
- "create"
- apiGroups:
- apps
resources:
- deployments/finalizers
resourceNames:
- aws-nlb-helper-operator
verbs:
- "update"
- apiGroups:
- ""
resources:
- pods
verbs:
- get
- apiGroups:
- apps
resources:
- replicasets
- deployments
verbs:
- get
11 changes: 11 additions & 0 deletions deploy/iam-service-accocunt/role_binding.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: aws-nlb-helper-operator
subjects:
- kind: ServiceAccount
name: aws-nlb-helper-operator
roleRef:
kind: Role
name: aws-nlb-helper-operator
apiGroup: rbac.authorization.k8s.io
7 changes: 7 additions & 0 deletions deploy/iam-service-accocunt/service_account.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
apiVersion: v1
kind: ServiceAccount
metadata:
annotations:
# Replace this with the AWS role ARN created for the AWS NLB helper
eks.amazonaws.com/role-arn: AWS_IAM_ROLE_ARN
name: aws-nlb-helper-operator
48 changes: 31 additions & 17 deletions pkg/controller/aws/aws_helper.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import (
var log = logf.Log.WithName("helper_aws")

const (
awsDefaultRegion = "us-east-1"
awsLoadBalancerResourceTypeFilter = "elasticloadbalancing"
awsTargetGroupResourceTypeFilter = "elasticloadbalancing:targetgroup"
awsNetworkLoadBalancerResourceTypeFilter = "elasticloadbalancing:loadbalancer/net"
Expand All @@ -41,17 +42,10 @@ func UpdateNetworkLoadBalancer(loadBalancerDNS string, serviceNameTagValue strin
ulbLogger := log.WithValues("LoadBalancerDNS", loadBalancerDNS, "ServiceName", serviceNameTagValue)

// Get AWS Clients for ELBV2 and ResourceGroupsTaggingAPI APIs
awsClient, err := newAPIClient(
os.Getenv("AWS_ACCESS_KEY_ID"),
os.Getenv("AWS_SECRET_ACCESS_KEY"),
os.Getenv("AWS_REGION"),
)
awsClient, err := newAPIClient()

if err != nil {
ulbLogger.Error(err, "Unable to create AWS Client",
"AWS_ACCESS_KEY_ID", os.Getenv("AWS_ACCESS_KEY_ID"),
"AWS_REGION", os.Getenv("AWS_REGION"),
)
ulbLogger.Error(err, "Unable to initialize an AWS Client")
return false, err
}

Expand Down Expand Up @@ -94,18 +88,38 @@ func UpdateNetworkLoadBalancer(loadBalancerDNS string, serviceNameTagValue strin
return true, nil
}

// newAPIClient obtains an AWS session and initiates the needed AWS clients.
func newAPIClient(id string, secret string, region string) (*APIClient, error) {
// newAWSConfig generates an AWS config.
func newAWSConfig() *aws.Config {

awsRegion := os.Getenv("AWS_REGION")

// Get AWS config
awsConfig := &aws.Config{
Region: aws.String(region),
Credentials: credentials.NewStaticCredentials(id, secret, ""),
if awsRegion == "" {
awsRegion = awsDefaultRegion
log.Info("Empty AWS_REGION, using default value", "awsRegion", awsRegion)
}

if (os.Getenv("AWS_ACCESS_KEY_ID") != "") && (os.Getenv("AWS_SECRET_ACCESS_KEY") != "") {
log.Info("Configuring AWS client using the environment credentials", "AWS_ACCESS_KEY_ID", os.Getenv("AWS_ACCESS_KEY_ID"))
return &aws.Config{
Region: aws.String(awsRegion),
Credentials: credentials.NewStaticCredentials(
os.Getenv("AWS_ACCESS_KEY_ID"),
os.Getenv("AWS_SECRET_ACCESS_KEY"),
"",
),
}
}

log.Info("Configuring AWS client using the service account")
return &aws.Config{Region: aws.String(awsRegion)}

}

// newAPIClient obtains an AWS session and initiates the needed AWS clients.
func newAPIClient() (*APIClient, error) {

// Initialize an AWS session
awsConfig = awsConfig.WithCredentialsChainVerboseErrors(true)
sess, err := session.NewSession(awsConfig)
sess, err := session.NewSession(newAWSConfig())
if err != nil {
return nil, fmt.Errorf("Unable to initialize AWS session: %v", err)
}
Expand Down
2 changes: 1 addition & 1 deletion version/version.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@ package version

var (
// Version of the aws-nlb-helper operator
Version = "0.0.1"
Version = "0.0.4"
)

0 comments on commit d14cf73

Please sign in to comment.