Creating an AWS Lambda Function with Environment Variables
Objective: create a lambda function that uses parameterized variable(s).
Currently, I’m building an application that uses AWS lambda functions to send a text message to a recipient. I’d like to parameterize the lambda so that I can personalize the phone number to send the message to.
There are a couple implementations:
- Create a single lambda and the phone number is parameterized & conveyed through the
event
body. - Create a lambda function for each phone number. On creation of the lambda, we would make use of environment variables to set the recipient phone number.
For some background, the lambda accesses the message published to an SNS topic like so:
def lambda_handler(event, context):
# Access the SNS record
for record in event['Records']:
sns_message = record['Sns']['Message']
Now, I will show both methods with code examples and/or screenshots:
- Single lambda
Encode both the message and phone number in JSON format:
{
"message": "This is the SNS message body.",
"phone_number": "+1234567890"
}
import json
from twilio.rest import Client
def lambda_handler(event, context):
# Access the SNS record
for record in event['Records']:
sns_message_json = record['Sns']['Message']
message_data = json.loads(sns_message_json)
message = message_data.get('message')
phone_number = message_data.get('phone_number')
account_sid = '[TWILIO_ACCOUNT]'
auth_token = '[TWILIO_AUTH_TOKEN]'
client = Client(account_sid, auth_token)
message_res = client.messages.create(
from_='[TWILIO_PHONE_NUMBER]',
body=message,
to=phone_number
)
print(message_res.sid)
return {
'statusCode': 200,
'body': json.dumps('Hello from Lambda!')
}
2. One lambda per phone number
The phone number is configured in the Configuration > Environment variables.
The environment variables are set when the lambda is created:
response = lambda_client.create_function(
FunctionName=phone_number,
Runtime='python3.13',
Role='arn:aws:iam::XXXXXXXXXXXX:role/service-role/[IAM_ROLE]', # Update with your IAM role
Handler='lambda_function.lambda_handler',
Code={
'S3Bucket': 'text-reminder-app',
'S3Key': 'sendTwilioSMSLambda.py.zip' # Lambda function code
},
Layers=[
'arn:aws:lambda:us-east-1:XXXXXXXXXXXX:layer:twilio_layer:1' # Update with your Twilio Layer ARN (needed for twilio Python dependency)
],
Environment={
'Variables': {
'SNS_TOPIC_ARN': sns_topic,
'PHONE_NUMBER': phone_number,
'ROLE_ARN': 'arn:aws:iam::XXXXXXXXXXXX:role/service-role/[IAM_ROLE]'
}
}
)
Here is the actual lambda code:
import json
import os
from twilio.rest import Client
def lambda_handler(event, context):
SNS_TOPIC_ARN = os.environ.get('SNS_TOPIC_ARN')
PHONE_NUMBER = os.environ.get('PHONE_NUMBER')
# Access the SNS record
for record in event['Records']:
sns_message = record['Sns']['Message']
account_sid = '[TWILIO_ACCOUNT]'
auth_token = '[TWILIO_AUTH_TOKEN]'
client = Client(account_sid, auth_token)
message = client.messages.create(
from_='[TWILIO_PHONE_NUMBER]',
body=sns_message,
to=PHONE_NUMBER
)
res = dict()
res['sns_topic_arn'] = SNS_TOPIC_ARN
res['message'] = sns_message
return {
'statusCode': 200,
'body': json.dumps(res)
}
If we want to reuse this lambda for multiple topics, then we should remove it as an environment variable, and instead pass any relevant data about the source SNS topic via the event
object:
import json
import os
from twilio.rest import Client
def lambda_handler(event, context):
PHONE_NUMBER = os.environ.get('PHONE_NUMBER')
# Access the SNS record
for record in event['Records']:
sns_message = record['Sns']['Message']
account_sid = '[TWILIO_ACCOUNT]'
auth_token = '[TWILIO_AUTH_TOKEN]'
client = Client(account_sid, auth_token)
message = client.messages.create(
from_='[TWILIO_PHONE_NUMBER]',
body=sns_message,
to=PHONE_NUMBER
)
res = dict()
res['message'] = sns_message
return {
'statusCode': 200,
'body': json.dumps(res)
}