Home > front end >  Can you add text files in an aws lambda layer?
Can you add text files in an aws lambda layer?

Time:10-06

I was thinking about using secrets manager or parameter store, but then if the jwt expires, then I'd have to copy / paste ways to handle an expired jwt across all my lambda functions and I figured that would be inefficient.

What I thought about next was using a lambda layer. Most of the functions that I'm writing already require said lambda layer so I thought it would be the most efficient way of sharing a jwt across multiple lambda functions.

My question is, if I had a lambda layer with a directory that included a text file of my jwt, would all my lambda functions be able to read and write from said text file inside the layer, and will they remain updated across all the lambda functions that are using the same layer?

CodePudding user response:

That won't work. A layer is just a ZIP file that gets unpacked when Lambda starts a new execution environment. Even if you could write to it, anything that you changed in one execution environment wouldn't affect any others. But that's moot, because you can't write to the directory where the layer gets unpacked. – kdgregory

CodePudding user response:

A Python layer is simply a ZIP file that gets unpacked into the Lambda execution environment when it starts.

So even if you could modify a file in that layer, it wouldn't be visible to other Lambdas, regardless of whether they're already running or newly started after your change.

But you can't modify a file in the layer, because (1) everything's owned by root, and (2) it's mounted read-only. You can see this with a Lambda function like the following:

import os

def lambda_handler(event, context):
    
    print("")
    print("**** id ****")
    os.system("id")
        
    print("")
    print("****")
    os.system("df -kh")
    
    print("")
    print("****")
    os.system("cat /etc/mtab")

When you run this, you'll see output like the following. The layer will be unpacked into /opt/python. As you can see, /opt is the volume /dev/vdc, which is mounted read-only like all of the other volumes except /tmp and -- surprisingly -- /dev (although I doubt you'd be able to write there because I'm sure it's owned by root).

**** id ****
uid=993(sbx_user1051) gid=990 groups=990
****
Filesystem                                                           Size  Used Avail Use% Mounted on
/mnt/root-rw/opt/amazon/asc/worker/tasks/rtfs/python3.7-amzn-201803  9.8G  8.4G  1.4G  87% /
/dev/vdb                                                             1.5G   14M  1.4G   1% /dev
/dev/vdd                                                             526M  872K  514M   1% /tmp
/dev/root                                                            9.8G  8.4G  1.4G  87% /var/rapid
/dev/vdc                                                             1.4M  1.4M     0 100% /opt
****
/mnt/root-rw/opt/amazon/asc/worker/tasks/rtfs/python3.7-amzn-201803 / overlay ro,nosuid,nodev,relatime,lowerdir=/tmp/es446846401/0e8fe4685588891:/tmp/es446846401/728da5137110572 0 0
/dev/vdb /dev ext4 rw,nosuid,noexec,noatime,data=writeback 0 0
/dev/vdd /tmp ext4 rw,relatime,data=writeback 0 0
none /proc proc rw,nosuid,nodev,noexec,noatime 0 0
/dev/vdb /proc/sys/kernel/random/boot_id ext4 ro,nosuid,nodev,noatime,data=writeback 0 0
/dev/root /etc/passwd ext4 ro,nosuid,nodev,relatime,data=ordered 0 0
/dev/root /var/rapid ext4 ro,nosuid,nodev,relatime,data=ordered 0 0
/dev/vdb /etc/resolv.conf ext4 ro,nosuid,nodev,noatime,data=writeback 0 0
/dev/vdc /var/task squashfs ro,nosuid,nodev,relatime 0 0
/dev/vdc /opt squashfs ro,nosuid,nodev,relatime 0 0

So, with that out of the way, how to solve your real problem, which is propagating an access token to all Lambdas, including (I presume) those that are currently running.

You could mount an EFS filesystem and write the file there. But you could still end up with a running Lambda using an expired token, so you'll still need to write all of the code to refresh the token. And using EFS to store config just seems like overkill.

The better solution depends on how long your tokens live.

  • If they're long-lived (on the order of months or years), store them in Parameter Store or Secrets Manager, retrieve on first use and cache the value using @lru_cache, and update them several days before they expire.
  • If they live for 30 minutes or more, create a module that will retrieve and cache the token. This module should live in a layer so that all of your Lambdas can call it rather than implement the logic themselves, and will expose a function to access the token. This function should validate the current cached token (if there is one), and retrieve a new one if it either (1) has expired, or (2) has never been retrieved.
  • If they live for only a few minutes, then retrieve on each use. You could potentially retrieve at the start of Lambda invocation and re-use, but that depends on how long your Lambda runs.
  • Related