Assuming Role and calling Lambda from inside EKS Pod

Viewed 828

I have an application running in a pod on EKS, and would like for it to call a Lambda function, and am struggling with permissions and security.

What I'd like to do is use STS to assume my Lambda Invocation role (which has the AWSLambda_FullAccess managed policy applied to it), and then run the Lambda.

In EKS, my pod is running under a default service account, and as such, I believe the role that it has assigned to it is my EKS node role (which has AmazonEKSWorkerNodePolicy and AmazonEC2ContainerRegistryReadOnly applied per the documentation).

On the EKS Node role, I have the following trust relationship configured:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "",
      "Effect": "Allow",
      "Principal": {
        "Service": "ec2.amazonaws.com"
      },
      "Action": "sts:AssumeRole"
    },
    {
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::<my-account-number>:role/<lambda-invoker-role-name>"
      },
      "Action": "sts:AssumeRole",
      "Condition": {}
    }
  ]
}

On my Lambda Invoker role, I have the following the following trust relationships configured:

{
  "Version": "2012-10-17",
  "Statement": [

    {
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::<my-account-number>:role/<my-eks-worker-node-role-name>"
      },
      "Action": "sts:AssumeRole",
      "Condition": {}
    },
    {
      "Effect": "Allow",
      "Principal": {
        "Service": "lambda.amazonaws.com"
      },
      "Action": "sts:AssumeRole"
    }
  ]

When, in my app (running in the EKS pod), I attempt to use STS to assume my lambda invoker role, it seems to work -- I can print the credentials and actually get an AccessKeyId, SecretAccessKey, SessionToken, and Expiration.

The code that I'm running to assume the STS Role: Based heavily on this example

(defn assumed-role-credentials-provider [role-arn]
  (let [sts (aws/client {:api :sts})
        _ (println "defining cred provider")]
    (credentials/cached-credentials-with-auto-refresh
     (reify credentials/CredentialsProvider
       (fetch [_]
         (let [_ (println "Trying to assume role")
               {:keys [Credentials] :as creds}
               (aws/invoke sts
                           {:op      :AssumeRole
                            :request {:RoleArn         role-arn
                                      :RoleSessionName (str (gensym "example-session-"))}})]
           (if Credentials
             (do 
               (println Credentials)
               {:aws/access-key-id     (:AccessKeyId creds)
                :aws/secret-access-key (:SecretAccessKey creds)
                :aws/session-token     (:SessionToken creds)
                ::credentials/ttl      (credentials/calculate-ttl creds)})
             (println "Failed to assume role: " creds))))))))

(def lambda (aws/client {:api :lambda
                         :credentials-provider (assumed-role-credentials-provider "arn:aws:iam::<my-acct-number>:role/<lambda-executor-role-name>")}))

(defn aws-test []
  (let [session-name (str (gensym "example-session-"))]
    (aws/invoke lambda {:op :Invoke
                        :request {:FunctionName "clearflow-pipeline-fn-aster_ubs_zurich_transactions"
                                  ;; :RoleSessionName session-name
                                  :Payload (ch/generate-string {:start_time "2020-12-18"
                                                                :end_time "2020-12-19"})}})))

However, when I try to invoke my lambda, I get an error message of The security token included in the request is invalid.

I feel like my role assumption is working fine, however I must be missing something with running the actual lambda -- is there a configuration setting I'm missing or doing wrong?

0 Answers
Related