In AWS a Lambda function does not move: you create an identical one in the new region and, once you have checked it works, you switch off or delete the old one. The scary part is not the code (it is a zip you download and upload again), but everything around it: the schedule that launches it every night, the public URL your website uses, the queue that feeds it. Some of that is regional and does not travel. This guide tells you what comes along, what does not, and the safe order: first the copy, then the test, and only at the end the old one.
Before you start: what each thing means
- Region
- The group of data centres where the function lives (eu-west-1 is Ireland, eu-west-3 is Paris, eu-south-2 is Spain). Almost everything in Lambda is regional: the function, its logs, its rules.
- Zip package
- The file with the function's code. It is what gets copied. Functions built as a container image are moved differently (the image has to be copied to an ECR registry in the new region).
- Execution role
- The permission the function runs with (what it may touch). IAM is global, so the same role works in any region: no need to create another one.
- Schedule (EventBridge)
- The rule "run it every 15 minutes" or "every day at 3:00". It is regional: it has to be created again in the destination region, with the same frequency.
- Public URL
- The function's web address. It has the region inside it: in the new region the address changes and whatever used it has to be updated.
- Layer
- Shared libraries the function loads on start-up. Layers are regional: a layer of yours has to be published in the new region as well.
Step by step
Take stock of what surrounds the function
Open the function in the Lambda console and look in three places. Under Configuration → Triggers: what runs it (EventBridge, S3, SNS, API Gateway, an SQS queue). Under Configuration → Function URL: whether it has a public URL. Under Code → Layers: whether it uses layers. Also note down memory, timeout, environment variables and the execution role (Configuration → Permissions). With that list you will know what will travel on its own and what you will have to redo.
Decide what comes along and what does not
Comes along as is: the code, the language (runtime), the handler, the memory, the maximum time, the architecture, the environment variables, the description and the same execution role. AWS public layers usually exist in every region under the same name; yours do not.
Schedules are recreated at the destination with the same expression. EventBridge events with a pattern (for example "when a machine stops") are regional rules about what happens in that region: there is no point in taking them along, you create new ones if needed. Queues and streams (SQS, DynamoDB, Kinesis) stay in their region and will keep calling the old function. S3 notifications only reach functions in the bucket's region. SNS allows cross-region subscriptions, but you have to subscribe the new function by hand. API Gateway has to be pointed at the new function. And the logs and metrics stay where they were: the new function starts with an empty history.
Download the code and create the function in the new region
In the old function, Code → Actions → Export function → Download deployment package: that gives you the zip. Switch region at the top right, Create function, same name, same runtime and architecture, and under Permissions → Change default execution role → Use an existing role, choose the old one's role. Then Upload from → .zip file with the one you downloaded. Under General configuration set the same memory and timeout; under Environment variables, the same ones. Wait until the state is no longer "Pending".
If you use the CLI, it is a single command from the zip:
aws lambda create-function --region eu-west-3 --function-name mi-funcion \ --runtime python3.12 --handler lambda_function.lambda_handler \ --role arn:aws:iam::123456789012:role/mi-rol --zip-file fileb://mi-funcion.zip \ --memory-size 256 --timeout 60 --environment Variables={CLAVE=valor}Recreate the schedules and the URL
In the new region, open EventBridge → Rules → Create rule with the same name and the same expression the old one had (copy it from the original rule:
rate(15 minutes),cron(0 3 * * ? *)). Target: the new function. EventBridge adds the permission to invoke it on its own. If the original rule was disabled, leave the new one disabled too: you will enable it when you switch off the old one.If it had a public URL, Configuration → Function URL → Create function URL, same authentication type. Note down the new address: you will have to change it in the website or program that called it.
Test the new one with both switched on
While you check, both functions exist and both schedules run. If the task is harmless to repeat (a report, a clean-up), leave it like that for a day and compare the CloudWatch logs of the two. If repeating is a problem (it sends emails, charges money, writes to a database), create the new schedule disabled, test the new function by hand with the Test button and a real event, and in the next step make the switch all at once.
Switch off the old one, do not delete it yet
First leave the old one unable to run: Configuration → Concurrency → Reserve concurrency → 0. With that AWS rejects all its executions, but the code and the rules are still there in case you have to go back in a minute. Also disable its EventBridge rule so it does not pile up failures. Enable the new one's rule. Change the URL in whatever used it and re-subscribe SNS or API Gateway if it had them.
Delete the old one once you have had a quiet week
After a week without scares, delete the old EventBridge rule and then the function (Actions → Delete). The old logs stay in CloudWatch Logs: they are neither deleted nor needed for the new function, but it is worth setting a retention on them (for example 90 days) so they do not cost money forever.
What can go wrong
The new function gets created but fails with "not authorized" when it runs
The execution role is the same, but what the function touches (a bucket, a table, a secret) is in the old region or its policy restricts it by region. Check the role for aws:RequestedRegion conditions and ARNs with a region, and that whatever the function uses exists or is reachable from the new region.
When creating it, it says the layer does not exist
Layers are regional. If it is yours, publish it in the new region (Lambda → Layers → Create layer with the same zip) and add the new version to the function. If it is an AWS public layer, look up its ARN for that region in the layer's documentation: the region changes and sometimes the version number too.
It runs twice every night
You have both schedules enabled. That is expected while you test; if you no longer want it, disable the old one's rule (or set its concurrency to 0).
The website that used the public URL has stopped working
The new URL is different (it contains the region). Change the address on the website. If you cannot touch it right now, leave the old one on a little longer and make the change calmly.
The SQS queue keeps calling the old one
Queues do not change region. Options: keep the old function as a "bridge" that forwards to the new one, create a new queue in the destination region and have whoever writes to the queue change address, or accept that this part stays where it is.
What about another AWS account?
It is the same process with one important difference: the execution role lives in the account, so in the new account the function cannot use the old one's. Create a role for Lambda there (or use one you already have) and, if the function touches S3, databases or queues, give it those permissions: the copy gets created fine but will fail when it runs until the role can do what the code does. Environment variables are copied as is: if they hold addresses or keys from the old account, change them. And queues, buckets and APIs do not change account: they have to be recreated or connected again.
In Simplio, "Move to another account" asks for an access key of the other account registered under Access keys, checks beforehand that it has permission to create functions, and creates the copy with that account's simplio-lambda-ejecucion role (the one from the Help script), warning you that it only writes logs and that you should extend that role if the function needs more.
In Simplio
In Simplio, the function card has a Move region… button. You choose the region, see beforehand what comes along (code, settings, role, schedules) and what does not (queues, S3 notifications, logs), confirm with two-factor and the copy appears with its schedules recreated, paused if they were. The original is not touched: its card keeps the notice "Copied to … on …; the original is still active" with the buttons Pause the original and Delete the original, which only deletes if the copy exists and is active. If something fails along the way, Simplio undoes what was created at the destination and tells you in plain words.
The same task, in AWS and in Simplio
| In the AWS console | In Simplio | |
|---|---|---|
| Knowing what travels and what does not | Go through triggers, URL, layers and role by hand across several screens | A preview on the same card: what comes along, what is recreated and what has to be redone, before touching anything |
| Creating the copy | Download the zip, create the function, repeat memory, time, variables and role; create the rules one by one | A "Move region…" button: copies, waits until it is active, recreates the schedules with the same frequency and the URL if it had one |
| If something fails halfway | You are left with a half-created function and loose rules to clean up | Everything created at the destination is undone and the original is not touched |
| Switching off and deleting the old one | Concurrency to 0, disable rules, delete later | Two buttons on the original's card: "Pause the original" (reversible) and "Delete the original", which only acts if the copy is active |