nitinr708
nitinr708

Reputation: 1467

Unable to set environment variable for aws lambda function executed as AWS::CloudFormation::CustomResource

I am trying to set the environment variable which takes it's value at runtime through my CloudFormation template json for CustomResource. So that later it executes a python lambda and I can read the environment variable in the lambda and process some data.

I want my python lambda to be able to read this variable inside os.environ

Following is my Cloudformation for CustomResource

"TriggerRedshiftSetupLambda": {
      "Type": "AWS::CloudFormation::CustomResource",
      "Version": 1.0,
      "Properties": {
       "Environment": {
          "Variables": {
            "AHost": {
                "Fn::GetAtt" : [ "A", "Endpoint.Address" ]
            },
            "APort": {
                "Fn::GetAtt" : [ "A", "Endpoint.Port" ]
            }
         }
        },
        "ServiceToken": {
          "Fn::GetAtt" : [ "ASetupLambda", "Arn" ]
        }
      }
    }

Here is my lambda code using the variable

def lambda_handler(event, context):
    print(os.environ)
    print(os.environ['AHost'])

The 1st print statement prints the entire environment variables list but doesn't have any key / value pair for 'AHost'

Am I doing something wrong? How to initialize environment variables through customresource for lambda correctly?

Upvotes: 0

Views: 2479

Answers (2)

nitinr708
nitinr708

Reputation: 1467

As stated by @jens above it's not possible to set environment variables under os.environ using the CustomResource CloudFormation.

Instead, the Lambda CloudFormation needs to define those values -

"RedshiftSetupLambda": {
  "Type": "AWS::Lambda::Function",
  "Properties": {
    "Code": {
      "S3Bucket": { "Fn::Sub": "XYZ-${Branch}" },
      "S3Key": { "Fn::Sub": "XYZ-${Commit}.zip" }
    },
    "Description": "Setup Lambda",
    "FunctionName": { "Fn::Sub": "${BlockId}-setup-${Branch}" },
    "Handler": "setup.lambda_handler",
    "KmsKeyArn": {
      "Fn::ImportValue": {
        "Fn::Sub": "${BlockId}-Common-RolesKeys-${Branch}-KMSKeyArn"
      }
    },
    "Role": {
      "Fn::ImportValue": {
        "Fn::Sub": "${BlockId}-Common-RolesKeys-${Branch}-LambdaIAMRoleArn"
      }
    },
    "Runtime": "python2.7",
    "Timeout": 30,
    "VpcConfig": {
      "SecurityGroupIds": [ {"Ref": "SecurityGroup"} ],
      "SubnetIds": [
        { "Fn::ImportValue": "VPCCreate-PrivateSubnet1Id" },
        { "Fn::ImportValue": "VPCCreate-PrivateSubnet2Id" },
        { "Fn::ImportValue": "VPCCreate-PrivateSubnet3Id" }
      ]
    },
    "Environment": {
      "Variables": {
        "DB_USERNAME": {
          "Ref": "MasterUsername"
        },
        "AHOST": {
          "Fn::GetAtt": ["RedshiftCluster", "Endpoint.Address"]
        },
        "APORT": {
          "Fn::GetAtt": ["RedshiftCluster", "Endpoint.Port"]
        },
        "CLUSTER_IDENTIFIER": {
          "Ref": "RedshiftCluster"
        }
      }
    }
  }
}

They can be accessed this way:

print(os.environ['AHOST'])

Upvotes: 0

jens walter
jens walter

Reputation: 14049

Setting environment variables through the custom resource definition seems not to be supported. What you are setting is the properties section for the actual invocation (so event data).

So taking your template, your configuration should be accessible under the following path.

event['ResourceProperties']['Environment']['Variables']['AHost']

Upvotes: 2

Related Questions