You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

通过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:RunInstances
    • ec2:DescribeInstances
    • ec2:GetPasswordData
    • 若私钥存储在AWS Secrets Manager需额外新增secretsmanager:GetSecretValue权限
  • 解密依赖cryptography库,需提前打包上传为Lambda层,或使用Lambda内置的加密库替代
  • 若实例所属子网未开启自动分配公网IP功能,返回的公网IP字段会显示未分配公网IP

内容的提问来源于stack exchange,提问作者Praveen Sivakumar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 15:54:04