无法为AWS::CloudFormation::CustomResource关联的AWS Lambda设置环境变量
Got it, let's break down how to configure environment variables for your Python Lambda function (used as a CloudFormation Custom Resource) so you can read them via os.environ during execution.
Key Background
First, a quick clarification: The AWS::CloudFormation::CustomResource itself doesn't set Lambda environment variables directly. Instead, you define the environment variables on the Lambda function resource in your CloudFormation template, then reference that Lambda's ARN in the CustomResource's ServiceToken property.
Full CloudFormation JSON Example
Here's a complete snippet that includes both the Lambda function (with environment variables) and the CustomResource that triggers it:
{ "Resources": { "RedshiftSetupLambda": { "Type": "AWS::Lambda::Function", "Properties": { "Handler": "lambda_function.lambda_handler", "Runtime": "python3.12", "Code": { "S3Bucket": "your-lambda-code-bucket", "S3Key": "redshift-setup-lambda.zip" }, "Role": { "Fn::GetAtt": ["RedshiftSetupLambdaRole", "Arn"] }, // This is where you define your runtime environment variables "Environment": { "Variables": { "REDSHIFT_CLUSTER_ID": "my-production-redshift-cluster", "S3_LOAD_BUCKET": "my-redshift-data-bucket", "ENVIRONMENT": "production" } } } }, "RedshiftSetupLambdaRole": { "Type": "AWS::IAM::Role", "Properties": { "AssumeRolePolicyDocument": { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Service": "lambda.amazonaws.com" }, "Action": "sts:AssumeRole" } ] }, "Policies": [ { "PolicyName": "RedshiftSetupPermissions", "PolicyDocument": { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "redshift:DescribeClusters", "s3:GetObject" ], "Resource": "*" } ] } } ] } }, "TriggerRedshiftSetupLambda": { "Type": "AWS::CloudFormation::CustomResource", "Properties": { // Reference the Lambda's ARN as the service token "ServiceToken": { "Fn::GetAtt": ["RedshiftSetupLambda", "Arn"] }, // Optional: Pass dynamic parameters to the Lambda via ResourceProperties // These will be available in the Lambda's event object, not os.environ "DynamicClusterParam": "some-value-passed-at-deploy-time" } } } }
Python Lambda Code Example
In your Lambda function code, you can read the environment variables using os.environ like this:
import os import boto3 import json def lambda_handler(event, context): # Read environment variables redshift_cluster_id = os.environ.get("REDSHIFT_CLUSTER_ID") s3_bucket = os.environ.get("S3_LOAD_BUCKET") env = os.environ.get("ENVIRONMENT") # Use the variables in your logic print(f"Processing Redshift cluster: {redshift_cluster_id} in {env} environment") # Example: Describe the Redshift cluster redshift_client = boto3.client("redshift") response = redshift_client.describe_clusters(ClusterIdentifier=redshift_cluster_id) # Return a response to CloudFormation return { "Status": "SUCCESS", "PhysicalResourceId": redshift_cluster_id, "Data": { "ClusterStatus": response["Clusters"][0]["ClusterStatus"] } }
Important Notes
- Static vs Dynamic Values: Environment variables are set at Lambda deployment time. If you need dynamic values that change per CloudFormation stack deployment, use the CustomResource's
Propertiesfield (likeDynamicClusterParamin the example) and read them fromevent["ResourceProperties"]in your Lambda code instead. - Permissions: Ensure your Lambda's IAM role has permissions to access any resources referenced by your environment variables (e.g., Redshift clusters, S3 buckets).
- CustomResource Version: The
Versionfield you included in your original snippet isn't a valid property forAWS::CloudFormation::CustomResource—you can remove it.
内容的提问来源于stack exchange,提问作者nitinr708

