Home > Software design >  How can I pass AWS lambda environement variable into userdata script ( script will fire during ec2 s
How can I pass AWS lambda environement variable into userdata script ( script will fire during ec2 s

Time:12-31

Need help in my aws lambda/python script , I am intending to call a environment variable into my userdata script which will run during instance spinup, but I am facing issue passing environment variable into my user data script. This code is bigger as I am running codepipeline, cloudformation, lambda , etc.. . What exactly you need to look is "aws sns publish --topic-arn {} --message "echo $message" --region us-east-1 2>&1| tee sns.log" I am trying to pass snstopic arn crated part of the cloudformation , I am able to pass that in the lambda env variable but that is not working in user data. Hence after my instance creation its uable to sned sns as "TopicArn" not able to passing actual arn for the sns topic in the above mentioned .

Anyone can look into this and let me know/help me understood how we can pass variable from lambda to userdata if possible at all, that would be a great help. Thanks in advanced and please let me know if any questions.

''' LambdaFunction: DependsOn: - "LambdaFunctionLogGroup" Type: AWS::Lambda::Function

Type: AWS::Serverless::Function

Properties:
  Runtime: python3.9
  FunctionName: VPC_Custom_Resource
  Timeout: 60

Handler: index.handler

  Role: !GetAtt LambdaFunctionRole.Arn
  Environment:
    Variables:
      SUBNET_ID: !Ref PublicSubnet1
      Name: !Ref NameTagValue
      INSTANCE_TYPE: t3.small
      AMI: ami-0c4e4b4eb2e11d1d4
      KEY_NAME: sudsark-dev
      TopicArn: !Ref SNSTopic
      InstanceProfile: !GetAtt Ec2InstanceProfile.Arn
      InstanceProfileName: !Ref Ec2InstanceProfile
  Handler: index.lambda_handler
  Code:
    ZipFile: |

          #/usr/bin/env python3
          
          import cfnresponse
          import logging
          import traceback

          #lambda to luanch EC2
          import boto3
          import os
          ec2 = boto3.resource('ec2')
          import logging

          #Start Logging
          #lOGGER = logging.getLogger()
          logger = logging.getLogger(__name__)
          #LOGGER.setLevel(logging.INFO)
          logging.getLogger().setLevel(logging.INFO)

          #code block for Environment variable declaration which would be 

          INSTANCE_TYPE = os.environ['INSTANCE_TYPE'] #These will be environment variables that we must specify in lambda
          KEY_NAME = os.environ['KEY_NAME']
          AMI=os.environ['AMI']
          SUBNET_ID=os.environ['SUBNET_ID']
          TopicArn=os.environ['TopicArn']
          Name=os.environ['Name']
          InstanceProfile=os.environ['InstanceProfile']
          InstanceProfileName= os.environ['InstanceProfileName']
          topicarn=TopicArn
          #code block for variable of user data
          userData= ''' #!/bin/bash
          cat << 'EOF' >> /tmp/connectiontest.sh
          #!/bin/bash
          echo "PINGTEST Result:"
          echo "================================"
          v=$(ping google.com -c 3)
          w=$(ping google.com -c 3 | wc -l)
          x=$(ping google.com -c 3 | sed -n 7p)
          printf '%s\n' "TrafficStatus :" "$x"
          echo "--------------------------------"
          y=$(ping google.com -c 3 | awk '{if(NR==7) print $0}')
          printf '%s\n' "TrafficStatus :" "$y"
          if ping google.com -c 3 | grep -w "time=\|ms" 2>&1 ; then
                  echo " Ec2 is reachable to internet as ping to google.com is working fine"
          else
                  echo "Ec2 is not rechable over icmp as ping to google.com is failing"
          fi

          echo "==========================================="
          echo "Curl test result:"
          echo "================="
          if curl -I "https://google.com" 2>&1 | grep -w "200\|301" ; then
            echo "Ec2 is reachable to Internet (https://google.com)"
          else
            echo "Ec2 is not reachable to Internet (https://google.com)"
          fi

          echo "========================================================"
          EOF

          sleep 1m
          chmod  x /tmp/connectiontest.sh
          ./tmp/connectiontest.sh >> /tmp/connectiontest.log
          sleep 15
          cd /tmp
          message=$(<connectiontest.log)
          sudo -i
          aws sns publish --topic-arn {} --message "echo $message" --region us-east-1 2>&1| tee sns.log
          '''

          # Function to create Ec2 instance :

          def lambda_handler(event, context):   #Start of our function
              subnet_id=SUBNET_ID
              instance = ec2.create_instances(
                  InstanceType=INSTANCE_TYPE,
                  KeyName=KEY_NAME,
                  ImageId=AMI,
                  MaxCount=1,
                  MinCount=1,
                  NetworkInterfaces=[{
                    'DeviceIndex': 0,
                    'SubnetId': subnet_id,
                    'AssociatePublicIpAddress': True,
                   }],              
                  IamInstanceProfile={ 
                    'Name': InstanceProfileName
                    },
                  UserData=userData,
                  TagSpecifications=[{    #This creates a tag for our resource
                      'ResourceType': 'instance',
                      'Tags': [{'Key': 'Name','Value': 'Dry-run'}]
                  }]
              )
              print("New instance created:", instance[0].id)
              codepipeline = boto3.client('codepipeline')
              job_id = event['CodePipeline.job']['id']
              response = codepipeline.put_job_success_result(jobId=job_id)
              return response

CodePudding user response:

I have update only userdata section

you just need to use python string formatting https://realpython.com/python-string-formatting/

          userData= ''' #!/bin/bash
          cat << 'EOF' >> /tmp/connectiontest.sh
          #!/bin/bash
          echo "PINGTEST Result:"
          echo "================================"
          v=$(ping google.com -c 3)
          w=$(ping google.com -c 3 | wc -l)
          x=$(ping google.com -c 3 | sed -n 7p)
          printf '%s\n' "TrafficStatus :" "$x"
          echo "--------------------------------"
          y=$(ping google.com -c 3 | awk '{if(NR==7) print $0}')
          printf '%s\n' "TrafficStatus :" "$y"
          if ping google.com -c 3 | grep -w "time=\|ms" 2>&1 ; then
                  echo " Ec2 is reachable to internet as ping to google.com is working fine"
          else
                  echo "Ec2 is not rechable over icmp as ping to google.com is failing"
          fi

          echo "==========================================="
          echo "Curl test result:"
          echo "================="
          if curl -I "https://google.com" 2>&1 | grep -w "200\|301" ; then
            echo "Ec2 is reachable to Internet (https://google.com)"
          else
            echo "Ec2 is not reachable to Internet (https://google.com)"
          fi

          echo "========================================================"
          EOF

          sleep 1m
          chmod  x /tmp/connectiontest.sh
          ./tmp/connectiontest.sh >> /tmp/connectiontest.log
          sleep 15
          cd /tmp
          message=$(<connectiontest.log)
          sudo -i
          '''
          
          userData  = f'aws sns publish --topic-arn ${topicarn} --message "echo $message" --region us-east-1 2>&1| tee sns.log'
  • Related