Created
July 28, 2023 18:55
-
-
Save thereisnotime/31569e00a430ef4c85b2d1673ed934f3 to your computer and use it in GitHub Desktop.
Deploy / update AWS Lambda environment variables / secrets from .env or key-value file
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
- name: Prepare | Secrets | |
id: prep_secret | |
run: echo "::set-output name=LAMBDA_SECRET_NAME::LAMBDA_$(echo '${{ github.event.inputs.lambda_name }}' | tr '[:lower:]' '[:upper:]')_ENV" | |
- name: Setup | Serverless Secret Config | |
# Write a big ENV secret to a .env file | |
run: | | |
echo "${{ secrets[steps.prep_secret.outputs.LAMBDA_SECRET_NAME] }}" >> .env | |
- name: Deploy | Update Lambda Secrets | |
uses: actions/setup-python@v4 | |
with: | |
python-version: '3.11' | |
- run: pip install -r ./deployments/scripts/requirements.txt | |
- run: | | |
python ./deployments/scripts/updateLambdaEnvironment.py --lambda_name lambda-${{ inputs.environment }}-${{ inputs.lambda_name }} --aws_access_key_id ${{ secrets.AWS_ACCESS_KEY_ID }} --aws_secret_access_key ${{ secrets.AWS_SECRET_ACCESS_KEY }} --aws_region ${{ env.AWS_REGION }} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
boto3==1.20.23 | |
python-dotenv==0.19.2 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import os | |
import boto3 | |
import argparse | |
from dotenv import load_dotenv | |
""" | |
Script for updating AWS Lambda function environment variables from a .env file. | |
Usage: | |
python lambda_env_updater.py --lambda_name <your_lambda_function_name> [--debug] [--aws_access_key_id <your_access_key>] [--aws_secret_access_key <your_secret_key>] [--aws_region <your_region>] [--aws_profile <your_profile>] [--env_file <path_to_your_.env_file>] | |
Arguments: | |
--debug: Enable debug mode to print changes without applying them. | |
--lambda_name: Name of the Lambda function to update (Required). | |
--aws_access_key_id: AWS Access Key ID. | |
--aws_secret_access_key: AWS Secret Access Key. | |
--aws_region: AWS Region. | |
--aws_profile: AWS CLI profile to use. Defaults to 'default'. | |
--env_file: Path to the .env file. Defaults to '.env' in the current folder. | |
In the absence of AWS credentials (access key, secret access key, and region) in the arguments, the script will use the default AWS CLI profile's credentials. | |
The .env file should contain one 'KEY=VALUE' pair per line. Lines starting with '#' are treated as comments and ignored. | |
Example usage: | |
python lambda_env_updater.py --lambda_name my_lambda_function --debug --aws_access_key_id XXXX --aws_secret_access_key YYYY --aws_region us-west-2 --aws_profile my_profile --env_file /path/to/my/.env | |
""" | |
def load_env_variables(file_path=".env"): | |
load_dotenv(file_path) | |
def get_env_variables_from_file(file_path=".env"): | |
env_variables = {} | |
with open(file_path) as f: | |
for i, line in enumerate(f, start=1): | |
line = line.strip() | |
if line and not line.startswith("#"): | |
try: | |
key, value = line.split("=", 1) | |
env_variables[key] = value | |
except ValueError: | |
raise ValueError(f"Line {i} in {file_path} is not correctly formatted. " | |
f"Each line should be in the form 'KEY=VALUE'.") | |
return env_variables | |
def update_lambda_environment(function_name, env_variables, debug_mode, aws_credentials): | |
# AWS reserved keys | |
reserved_keys = ["AWS_ACCESS_KEY_ID", "AWS_SECRET_ACCESS_KEY", "AWS_SESSION_TOKEN", "AWS_REGION"] | |
session = boto3.Session(**aws_credentials) | |
lambda_client = session.client('lambda') | |
# Get the current configuration of the Lambda function | |
response = lambda_client.get_function(FunctionName=function_name) | |
current_env_variables = response['Configuration']['Environment']['Variables'] | |
# Placeholder for new environment variables | |
new_env_variables = current_env_variables.copy() | |
# Compare and update the environment variables | |
for key, value in env_variables.items(): | |
# Skip if the key is an AWS reserved key | |
if key in reserved_keys: | |
continue | |
if key in new_env_variables: | |
if new_env_variables[key] != value: | |
# Print the changes | |
print(f"Updating: {key}") | |
if not debug_mode: | |
new_env_variables[key] = value | |
else: | |
# Print the changes | |
print(f"Adding: {key}") | |
if not debug_mode: | |
new_env_variables[key] = value | |
# Remove any environment variables that are not in the .env file | |
for key in list(new_env_variables.keys()): | |
# Skip if the key is an AWS reserved key | |
if key in reserved_keys: | |
continue | |
if key not in env_variables: | |
# Print the changes | |
print(f"Removing: {key}") | |
if not debug_mode: | |
del new_env_variables[key] | |
# Update the Lambda function configuration with the new environment variables | |
if not debug_mode: | |
lambda_client.update_function_configuration( | |
FunctionName=function_name, | |
Environment={ | |
'Variables': new_env_variables | |
} | |
) | |
lambda_client.close() | |
def get_aws_credentials_from_args_or_file(args): | |
if args.aws_access_key_id and args.aws_secret_access_key and args.aws_region: | |
return { | |
"aws_access_key_id": args.aws_access_key_id, | |
"aws_secret_access_key": args.aws_secret_access_key, | |
"region_name": args.aws_region | |
} | |
else: | |
# Use the default AWS CLI profile if AWS credentials are not provided | |
session = boto3.Session(profile_name=args.aws_profile) | |
credentials = session.get_credentials() | |
if credentials is None: | |
raise ValueError("AWS credentials not found. Make sure to set --aws_access_key_id, " | |
"--aws_secret_access_key, --aws_region, or configure AWS CLI credentials.") | |
return { | |
"region_name": session.region_name | |
} | |
def parse_arguments(): | |
parser = argparse.ArgumentParser(description="Update Lambda function environment variables from .env file") | |
parser.add_argument("--debug", action="store_true", help="Enable debug mode to print changes without applying them") | |
parser.add_argument("--lambda_name", required=True, help="Name of the Lambda function to update") | |
parser.add_argument("--aws_access_key_id", help="AWS Access Key ID") | |
parser.add_argument("--aws_secret_access_key", help="AWS Secret Access Key") | |
parser.add_argument("--aws_region", help="AWS Region") | |
parser.add_argument("--aws_profile", default="default", help="AWS CLI profile to use (default: default)") | |
parser.add_argument("--env_file", help="Path to the .env file (default: .env in current folder)") | |
return parser.parse_args() | |
if __name__ == "__main__": | |
args = parse_arguments() | |
# Load environment variables from .env file | |
env_file_path = args.env_file or ".env" | |
load_env_variables(env_file_path) | |
print(f"Loaded environment variables from: {os.path.abspath(env_file_path)}") | |
if args.debug: | |
print("Running in debug mode. No changes will be applied.") | |
if args.aws_access_key_id and args.aws_secret_access_key and args.aws_region: | |
print("Using AWS credentials from command-line arguments") | |
else: | |
print("Using AWS credentials from the default AWS CLI configuration file") | |
# Specify the name of the Lambda function you want to update | |
lambda_function_name = args.lambda_name | |
# Define the environment variables to be updated (loaded from .env file) | |
env_variables = get_env_variables_from_file(env_file_path) | |
# Get AWS credentials either from command-line arguments or from AWS CLI configuration file | |
aws_credentials = get_aws_credentials_from_args_or_file(args) | |
# Update the Lambda function environment | |
update_lambda_environment(lambda_function_name, env_variables, args.debug, aws_credentials) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment