通过boto3 Lambda函数获取新建EC2实例的公网IPv4与解密密钥对
修正后完整Lambda代码
import boto3 import json import base64 import os from cryptography.hazmat.primitives import serialization from cryptography.hazmat.primitives.asymmetric import padding from cryptography.hazmat.backends import default_backend def lambda_handler(event, context): # 初始化EC2客户端 ec2 = boto3.client('ec2', region_name=event['REGION']) # 创建EC2实例 run_response = ec2.run_instances( ImageId=event['AMI'], InstanceType=event['INSTANCE_TYPE'], KeyName=event['KEY_NAME'], SubnetId=event['SUBNET_ID'], # 修正硬编码安全组,读取入参传入的安全组ID SecurityGroupIds = [event['SECURITYGROUP_ID']], MaxCount=1, MinCount=1, InstanceInitiatedShutdownBehavior="terminate", TagSpecifications=[ { 'ResourceType': 'instance', 'Tags': [ { 'Key': 'Name', 'Value': 'myserver' }, ] }, ], ) instance_id = run_response['Instances'][0]['InstanceId'] print(f"新实例创建成功,实例ID:{instance_id}") # 等待实例进入running状态,确保公网IP分配完成 waiter = ec2.get_waiter('instance_running') waiter.wait(InstanceIds=[instance_id]) print("实例已进入运行状态") # 获取最新实例信息,提取公网IP desc_response = ec2.describe_instances(InstanceIds=[instance_id]) instance_info = desc_response['Reservations'][0]['Instances'][0] public_ip = instance_info.get('PublicIpAddress', '未分配公网IP') private_ip = instance_info.get('PrivateIpAddress', '未分配私网IP') # 解密Windows实例初始密码(Linux实例可删除该部分逻辑) password = '非Windows实例无默认密码' try: pwd_response = ec2.get_password_data(InstanceId=instance_id) encrypted_pwd = pwd_response['PasswordData'] if encrypted_pwd: # 私钥建议存储在Secrets Manager,此处示例从环境变量读取私钥内容 private_key_str = os.environ.get('PRIVATE_KEY') private_key = serialization.load_pem_private_key( private_key_str.encode('utf-8'), password=None, backend=default_backend() ) decrypted_pwd = private_key.decrypt( base64.b64decode(encrypted_pwd), padding.PKCS1v15() ) password = decrypted_pwd.decode('utf-8') except Exception as e: print(f"密码解密失败:{str(e)}") password = '密码解密失败' # 构造返回结果 return { 'statusCode': 200, 'body': json.dumps({ 'instance_id': instance_id, 'public_ipv4': public_ip, 'private_ipv4': private_ip, 'decrypted_password': password }) }
关键修正说明
- 实例状态等待:新增EC2内置等待器,阻塞到实例进入
running状态,避免刚创建实例时公网IP未分配导致取值为空 - IP获取逻辑修正:你提供的代码片段是boto3 resource的属性调用写法,本次代码基于你原有的client写法,调用
describe_instances获取最新实例元数据提取IP,适配原有代码风格 - 密码解密逻辑:新增Windows实例初始密码解密逻辑,仅Windows EC2支持该接口获取初始管理员密码,Linux实例默认使用密钥对登录无初始密码,不需要该逻辑可直接删除
- 硬编码修复:修正原代码中安全组ID硬编码问题,改为读取event传入的
SECURITYGROUP_ID参数 - 返回结构优化:调整返回值为结构化JSON,包含实例ID、公网IP、私网IP、解密后密码四个字段
前置依赖配置
- Lambda执行角色需新增以下权限:
ec2:RunInstancesec2:DescribeInstancesec2:GetPasswordData- 若私钥存储在AWS Secrets Manager需额外新增
secretsmanager:GetSecretValue权限
- 解密依赖
cryptography库,需提前打包上传为Lambda层,或使用Lambda内置的加密库替代 - 若实例所属子网未开启自动分配公网IP功能,返回的公网IP字段会显示
未分配公网IP
内容的提问来源于stack exchange,提问作者Praveen Sivakumar
相关产品推荐
相关产品推荐

