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?