简体   繁体   中英

aws lambda to create different init script on different ec2 machine

I have a lambda function to launch windows EC2 instance with below user data and gather instance details from environment variables.

#!/usr/bin/python
# -*- coding: utf-8 -*-
import os
import boto3

AMI = os.environ["AMI"]
INSTANCE_TYPE = os.environ["INSTANCE_TYPE"]
KEY_NAME = os.environ["KEY_NAME"]
SUBNET_ID = os.environ["SUBNET_ID"]
REGION = os.environ["REGION"]
ec2 = boto3.client("ec2", region_name=REGION)

def lambda_handler(event, context):
init_script = '''<powershell>$USERNAME="latchu"
$PASSWORD="eM2An@ydxk"
net user /add $USERNAME $PASSWORD</powershell>'''
instance = ec2.run_instances(
    ImageId=AMI,
    InstanceType=INSTANCE_TYPE,
    KeyName=KEY_NAME,
    SubnetId=SUBNET_ID,
    MaxCount=3,
    MinCount=1,
    InstanceInitiatedShutdownBehavior="terminate",
    UserData=init_script,
)

Here, i have used simple init script to create one user with password on Windows Instance. But its very easy when i go with launch one instance. Some times, I should create more than 100 instance with different userdata which is creating user. I can simply create more than 100 instance using MaxCount in boto3.

MaxCount=3

However, my case each Ec2 instance should have separate user credentials.

So i would like to one lambda function to handle more than 100 instances with different userdata. How can i achieve? Any help would be appreciated.

There are essentially two different ways to achieve this.Either creating the user during bootstrap as you so, or doing it post-boot once the instance is up and running.

  1. If you want to stick to the first approach rather than using MaxCount and hardcoding the credentials in the init-script within the lambda handler you need to fully templatize it and in addition use a for loop and iterate over something. Now, based on where you want to have the same username but with a different password on those 100 instances:
  • you can create function that will simply create 100 different password by generating a random script. In order to not lose those credentials another function could store them encrypted in Systems Manager Parameter Store or AWS Secrets Manager .
  • A slightly different approach would be to have a csv or a json file with your credentials pre-generated on which you can loop over and read them line by line in order to pass them as vars to the init-script. You'll need to make sure that file is stored securily somewhere.
  1. Rather than creating the user in the init-script you can do it once the instance is up. Here, you can rely on multitude of AWS Services based on your preference (like OpsWorks for example), but I would recommend Systems Manager and more specifically the RunCommand which you can use to run a PowerShell script to create the user locally on the instance. Here you would need a trigger for the RunCommand.

You'll still need to create or pass the credentials somehow in this second post-bootstrap approach and in general you can use a mixture between the two options and either generate random strings to pass to the RunCommand (or even generate them locally on the instance within the powershell script) or poll for credential pre-created and stored in Parameter Store or Secrets Manager.

  1. As suggested by John in the comments rather than creating local users you can go for Active Directory

  2. You can scrap credentials all together and use AWS Systems Manager Session Manager or even potentially tool like HashiCorp Boundary or similar.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM