Giter Site home page Giter Site logo

aws-iam-operator's Introduction

AWS IAM Operator

An operator that enables AWS IAM management via Kubernetes custom resources.

Installation

CRD

The CRDs can easily be applied to the cluster with kubectl:

kubectl kustomize 'github.com/redradrat/aws-iam-operator/config/crd?ref=master' | kubectl apply -f -

or for a specific GITREF (e.g. branch, tag) with:

kubectl kustomize 'github.com/redradrat/aws-iam-operator/config/crd?ref=GITREF' | kubectl apply -f -

Controllers

The controller deployment incl. RBAC & CRD can be applied to the cluster with kubectl:

kubectl kustomize 'github.com/redradrat/aws-iam-operator/config/default?ref=master' | kubectl apply -f -

Controller Manager Options

The controller manager has a couple of input options, which you can set as paramaters on container startup.

...
    spec:
      containers:
      - command:
        - /manager
        args:
        - --enable-leader-election # For HA setup
        - --resource-prefix "testcluster-" # set a prefix to all created AWS resources (e.g. "testcluster-" -> "testcluster-user")
        - --oidc-provider-arn # OPTIONAL: allows setting a oidc provider arn for auto-injecting trust for roles
        image: redradrat/aws-iam-operator:latest
        name: manager

Custom Resources

Role

The Role resource abstracts an AWS IAM Role.

Setting an assumeRolePolicy or an assumeRolePolicyRef is mandatory. Creating a ServiceAccount resource is possible via createServiceAccount. The created ServiceAccount includes the EKS OIDC support annotation. When addIRSAPolicy is true, the controller will automatically add the trust policy for the OIDC provider given as controller argument.

apiVersion: aws-iam.redradrat.xyz/v1beta1
kind: Role
metadata:
  name: role-sample
  namespace: default
spec:
  // Either
  assumeRolePolicyRef:
    name: assumerolepolicy-sample
    namespace: default
  // OR
  assumeRolePolicy:
    - effect: "Allow"
      principal:
        "Federated": "blabla"
      actions:
        - "sts:AssumeRoleWithWebIdentity"
      conditions:
        "StringEquals":
          "blablabla": "system:serviceaccount:kube-system:aws-cluster-autoscaler"
  createServiceAccount: true
  addIRSAPolicy: true
  maxSessionDuration: 3600
  // spec.awsRoleName takes precendence over metadata.name
  awsRoleName: the-role

Resulting ServiceAccount:

❯ k get sa role-sample -o yaml
apiVersion: v1
kind: ServiceAccount
metadata:
  annotations:
    eks.amazonaws.com/role-arn: arn:aws:iam::0000000000:role/role-sample
  creationTimestamp: "2020-02-30T00:25:61Z"
  name: role-sample
  namespace: default
  ownerReferences:
  - apiVersion: aws-iam.redradrat.xyz/v1beta1
    blockOwnerDeletion: true
    controller: true
    kind: Role
    name: role-sample
    uid: ...

AssumeRolePolicy

The AssumeRolePolicy is an auxiliary resource for the Role resource. It provides a way to define a single trust policy for multiple roles.

apiVersion: aws-iam.redradrat.xyz/v1beta1
kind: AssumeRolePolicy
metadata:
  name: assumerolepolicy-sample
spec:
  statement:
    - sid: someid
      effect: "Allow"
      principal:
        "Federated": "blabla"
      actions:
        - "xxxx:DescribeSomething"
      resources:
        - "*"
      conditions:
        "StringEquals":
          "aws:SourceIp": "172.0.0.1"

Policy

The Policy resource abstracts an AWS IAM Policy.

For conditions, please check https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_condition_operators.html for valid Operators. For the comparison, only single String-type values are allowed as comparison values. For keys please check out https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_condition-keys.html

apiVersion: aws-iam.redradrat.xyz/v1beta1
kind: Policy
metadata:
  name: policy-sample
spec:
  statement:
    - sid: someid
      effect: "Allow"
      actions:
        - "xxxx:DescribeSomething"
      resources:
        - "*"
      conditions:
        "StringEquals":
          "aws:SourceIp": "172.0.0.1"
  // spec.awsPolicyName takes precendence over metadata.name
  awsPolicyName: the-policy

PolicyAttachment

The Policy resource abstracts the attachment of an AWS IAM Policy to another AWS IAM Resource e.g. Role (in future maybe User, Groups, etc.).

apiVersion: aws-iam.redradrat.xyz/v1beta1
kind: PolicyAttachment
metadata:
  name: policyattachment-sample
spec:
  policy:
    name: policy-sample
    namespace: default
  target:
    type: Role
    name: role-sample
    namespace: default

User

The User resource abstracts an AWS IAM User.

Setting createLoginProfile or an createProgrammaticAccess is optional. Creating a Secret resource, containing Console Login Data, is possible via createLoginProfile. The created secret includes the username and password. Creating a Secret resource, containing a Programmatic Access, is possible via createProgrammaticAccess. The created secret includes the both the Key ID and the Secret.

apiVersion: aws-iam.redradrat.xyz/v1beta1
kind: User
metadata:
  name: user-sample
spec:
  createLoginProfile: true
  createProgrammaticAccess: true

Resulting Secrets:

❯ k get secrets user-sample-login -o yaml
apiVersion: v1
data:
  password: ...
  username: ...
kind: Secret
metadata:
  name: user-sample-login
  namespace: default
  ownerReferences:
  - apiVersion: aws-iam.redradrat.xyz/v1beta1
    blockOwnerDeletion: true
    controller: true
    kind: User
    name: user-sample
    uid: 784d4ff5-377e-4172-a1cf-1b34387a3d6b
type: Opaque
❯ k get secret user-sample-accesskey -o yaml
apiVersion: v1
data:
  id: ...
  secret: ...
kind: Secret
metadata:
  name: user-sample-accesskey
  namespace: default
  ownerReferences:
  - apiVersion: aws-iam.redradrat.xyz/v1beta1
    blockOwnerDeletion: true
    controller: true
    kind: User
    name: user-sample
type: Opaque

Group

The Group resource abstracts an AWS IAM Group.

Adding IAM Users to the group, is possible via users. The referenced users need to be created via this operator.

apiVersion: aws-iam.redradrat.xyz/v1beta1
kind: Group
metadata:
  name: group-sample
spec:
  users:
  - name: user-sample
    namespace: default

aws-iam-operator's People

Contributors

eringet avatar gitter-badger avatar jorgeperis avatar moulick avatar redradrat avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

aws-iam-operator's Issues

Kubectl process getting stuck and does not exit

If we try to delete iamrole which already has a policy attached, the kubectl process gets stuck and does not exit. Had to force exit the command with ctrl+c

Controller logs shows continuous error:
ERROR controllers.Role unable to delete Role {"role": "default/role-sample1", "error": "DeleteConflict: Cannot delete entity, must detach all policies first.\n\tstatus code: 409, request id: 52f76e23-fa39-4f23-8584-9ca0e287d389"}

When we removed policy from role, the role got deleted automatically by the controller.

EntityAlreadyExists thrown and then deletion leads to Role 'xxxx' not yet created

kubectl get role.aws-iam.redradrat.xyz -A

jay nginx-deployment-role EntityAlreadyExists: Role with name nginx-deployment-role already exists.
status code: 409, request id: 042007ff-baf9-47d3-8960-b8bf9209c6ee ERROR
jay role-sample EntityAlreadyExists: Role with name role-sample already exists.
status code: 409, request id: 23bf242d-4a05-4668-b1e8-de3aa0538306 ERROR
test nginx-deployment-role arn:aws:iam::....:role/nginx-deployment-role Succesfully reconciled
test role-sample arn:aws:iam::....:role/role-sample Succesfully reconciled OK

jayzalowitz$ kubectl delete -f deployment.yaml -n jay
deployment.apps "nginx-deployment" deleted
role.aws-iam.redradrat.xyz "nginx-deployment-role" deleted
role.aws-iam.redradrat.xyz "role-sample" deleted

SFO-WXLVCF:application jayzalowitz$ kubectl get role.aws-iam.redradrat.xyz -A

jay nginx-deployment-role Role 'nginx-deployment-role' not yet created
jay role-sample Role 'role-sample' not yet created
test nginx-deployment-role arn:aws:iam::....:role/nginx-deployment-role Succesfully reconciled
test role-sample arn:aws:iam::.....:role/role-sample Succesfully reconciled

kubectl delete -f deployment.yaml -n test
deployment.apps "nginx-deployment" deleted
role.aws-iam.redradrat.xyz "nginx-deployment-role" deleted
role.aws-iam.redradrat.xyz "role-sample" deleted

kubectl get role.aws-iam.redradrat.xyz -A
jay nginx-deployment-role Role 'nginx-deployment-role' not yet created ERROR 11 Feb 21 22:33 +0000
jay role-sample Role 'role-sample' not yet created ERROR 11 Feb 21 22:33 +0000

Updating PolicyAttachment with new policy name does not replace attached policy

Steps :

  1. create a PolicyAttachment which attaches policy1 to role1.
  2. update PolicyAttachment : change policy name to policy2 and apply the change.

Expected Behaviour :
role1 should have policy2 attached and policy1 removed

Actual Behaviour :
role1 has both the policies attached policy1 and policy2

Same issue happens when we update PolicyAttachment with new role

Error while updating the policy if its attached to role

If policy is already attached to role, and if we try to update the policy it gives error:
ERROR controller-runtime.controller Reconciler error {"controller": "policy", "request": "<namespace>/<policy-name>", "error": "cannot delete policy due to existing PolicyAttachment '<policyattachment>/<namespace>'"}

Remove mandatory namespace in PolicyAttachment reference

Right now it is mandatory to define namespace in the TargetReference inside the PolicyAttachment spec.

Per default it should take it's own namespace as the TargetReference namespace, and only allow for overriding manually.

Namespaced scoped object failing

Getting following error while applying namespaced scoped object

ERROR in IAM Operator :
reflector.go:153] pkg/mod/k8s.io/[email protected]/tools/cache/reflector.go:105: Failed to list *v1beta1.User: users.aws-iam.redradrat.xyz is forbidden: User "system:serviceaccount:hkp-admin:main-aws-iam-operator" cannot list resource "users" in API group "aws-iam.redradrat.xyz" at the cluster scope

EKS cluster auth mapping

User/Role resource should have an option to map a the created resource for EKS cluster access.

Proposal:
Custom Resource User/Role should offer an option to register itself with the context cluster's AWS authentication map, and provide an option to map to an RBAC role.

apiVersion: aws-iam.redradrat.xyz/v1beta1
kind: User
metadata:
  name: user-sample
spec:
  createLoginProfile: false
  createProgrammaticAccess: true
  eksClusterMapping:
    - username: "demouser"
      groups:
        - "demo:group"
---
apiVersion: aws-iam.redradrat.xyz/v1beta1
kind: Role
metadata:
  name: role-sample
spec:
  createServiceAccount: false
  eksClusterMapping:
    - username: "demouser"
      groups:
        - "demo:group"

Support 'bring your own secret store'

Instead of writing Secrets and ConfigMaps maybe we should consider triggering a hook for writing secrets elsewhere? Not sure, but a simple event hook could do the trick. Users could deploy their own service that then writes to an external store and maybe creates an ExternalSecret object within k8s to inject the secret somewhere.

Delete & update in certain IAM resource

As AWS does not allow for in-place updates of certain resources (Role, PolicyAttachment, ...) we currently delete the previous resource, and recreate it. This might cause issues, when hitting resource limits?

How to make this safe? The point is, if this happens in production due to something triggering the re-creation, this might leave a Role uncreated and cause services, using this role, to fail. Not sure about it...

// RECONCILE THE RESOURCE
// if there is already an ARN in our status, then we recreate the object completely
// (because AWS only supports description updates)
if role.Status.ARN != "" {
// delete the actual AWS Object and pass the cleanup function
statusUpdater, err := DeleteAWSObject(iamsvc, ins, cleanupFunc)
// we got a StatusUpdater function returned... let's execute it
statusUpdater(ins, &role, ctx, r.Status(), log)
if err != nil {
// we had an error during AWS Object deletion... so we return here to retry
log.Error(err, "error while deleting Role during reconciliation")
return ctrl.Result{}, err
}
}
statusUpdater, err := CreateAWSObject(iamsvc, ins, DoNothingPreFunc)
statusUpdater(ins, &role, ctx, r.Status(), log)
if err != nil {
log.Error(err, "error while creating Role during reconciliation")
return ctrl.Result{}, err
}
log.Info(fmt.Sprintf("Created Role '%s'", role.Status.ARN))

Enable SAML IdP creation

We need to create aws saml IdP for keycloak.

With aws cli this is how we create saml idp:
aws iam create-saml-provider --saml-metadata-document file:///<filepath> --name <idp-name>

Proposal:
New custom resource for idp creation should be implemented, with input file saml-metadata-document

updating assumerolepolicy does not update role's trust relationship

Steps to reproduce:

  1. create assumerolepolicy: assumerolepolicy-sample
  2. create a role role-sample with
assumeRolePolicyRef:
    name: assumerolepolicy-sample
  1. now update assumerolepolicy-sample

Here it does not actually update role-sample's trust policy

Also if assumerolepolicy is deleted, there is no impact on role(ideally if assumerolepolicy is attached to role, it should be restricted from deletion)

Attachment of Policy to User gives error

While attaching the policy to user controller gives error and policy doesn't get attached. Users and Policies tested independently and no issue with them. Attachment of Policy to Role also works.

File:

apiVersion: aws-iam.redradrat.xyz/v1beta1
kind: PolicyAttachment
metadata:
  name: policyattachment-sample-dpy
  namespace: capabilities
spec:
  policy:
    name: policy-sample-test-dpy
    namespace: capabilities
  target:
    type: User
    name: user-dpy
    namespace: capabilities

Error on controller:
ERROR controller-runtime.controller Reconciler error {"controller": "policyattachment", "request": "default/policyattachment-sample-dpy", "error": "defined references do not exist for PolicyAttachment 'policyattachment-sample-dpy/default"}

iam objects deletion issue (ordering required)

Currently iam object should be deleted in following order in order to get them cleaned properly in k8s cluster-

policyattachment
policy
role/user
assumerolepolicy

If we shuffle the above mentioned objects order in deletion it stuck and we have to patch the finalizer and have to remove manually iam objects e.g role/user in AWS Console.

delete eks cluster

Hello, we, company Yad2 from Israel, want to use your project "aws-iam-operator" for infrastructure as a code. We have two problems for this: when you delete the cluster, all users and groups and everything that we have created are also deleted. The second problem is the inability to delete an object after receiving an error. Maybe you have a solution? thanks.

Error in importing

Trying to import github.com/redradrat/aws-iam-operator/api/v1beta1 and build returns the following error

# github.com/redradrat/aws-iam-operator/api/v1beta1
../../go/pkg/mod/github.com/redradrat/aws-iam-operator@v0.4.0/api/v1beta1/assumerolepolicy_helpers.go:28:15: cannot use entry.Conditions.Normalize() (value of type map[string]map[string]string) as map[string]map[string][]string value in struct literal
../../go/pkg/mod/github.com/redradrat/aws-iam-operator@v0.4.0/api/v1beta1/assumerolepolicy_helpers.go:51:15: cannot use entry.Conditions.Normalize() (value of type map[string]map[string]string) as map[string]map[string][]string value in struct literal
../../go/pkg/mod/github.com/redradrat/aws-iam-operator@v0.4.0/api/v1beta1/policy_helpers.go:49:15: cannot use entry.Conditions.Normalize() (value of type map[string]map[string]string) as map[string]map[string][]string value in struct literal
../../go/pkg/mod/github.com/redradrat/aws-iam-operator@v0.4.0/api/v1beta1/role_helpers.go:32:15: cannot use entry.Conditions.Normalize() (value of type map[string]map[string]string) as map[string]map[string][]string value in struct literal

Same error on both v0.3.7 and v0.4.0

Sample code

package main

import (
	iamv1beta1 "github.com/redradrat/aws-iam-operator/api/v1beta1"
)

func main() {
	_ = iamv1beta1.Role{}
}

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.