我有这个函数,我打算用它来处理 ec2 的实例,用 get 列出该区域中的所有实例,post 来创建一个新实例,put 来修改一个实例,delete 来删除一个实例,我正在使用 python 3.9 lambda 和无服务器
import json
import boto3
def ec2_crud(event, context):
http_method = event['httpMethod']
try:
# Crear una conexión con EC2 usando la región en la que se encuentra la función Lambda
region = context.invoked_function_arn.split(":")[3]
ec2 = boto3.resource('ec2', region_name=region)
if http_method == 'GET':
# Obtener todas las instancias de EC2 en la región
instances = ec2.instances.all()
instance_list = []
for instance in instances:
instance_info = {
'InstanceId': instance.id,
'InstanceType': instance.instance_type,
'State': instance.state['Name']
}
instance_list.append(instance_info)
return {
'statusCode': 200,
'body': json.dumps(instance_list)
}
elif http_method == 'POST':
try:
request_data = json.loads(event['body'])
instance_name = request_data['name']
instance_size = request_data['size']
instance_keys = request_data['keys']
ec2_client = boto3.client('ec2')
new_instance = ec2_client.run_instances(
ImageId='ami-03f65b8614a860c29', # Reemplaza con la AMI que desees usar
InstanceType=instance_size,
KeyName=instance_keys,
MinCount=1,
MaxCount=1
)['Instances'][0]
ec2_client.create_tags(Resources=[new_instance['InstanceId']], Tags=[{'Key': 'Name', 'Value': instance_name}])
return {
'statusCode': 200,
'body': json.dumps({'message': 'Nueva instancia creada con éxito.', 'InstanceId': new_instance['InstanceId']})
}
except Exception as e:
return {
'statusCode': 500,
'body': json.dumps({'error': str(e)})
}
elif http_method == 'PUT':
# Implementar la lógica para actualizar una instancia de EC2
instance_id = event['pathParameters']['instance_id']
instance_size = json.loads(event['body'])['size']
instance_name = json.loads(event['body'])['name']
# Crear una conexión con el servicio EC2
ec2_client = boto3.client('ec2')
try:
# Actualizar el tamaño y el nombre de la instancia
ec2_client.modify_instance_attribute(InstanceId=instance_id, Attribute='instanceType', Value=instance_size)
ec2_client.create_tags(Resources=[instance_id], Tags=[{'Key': 'Name', 'Value': instance_name}])
return {
'statusCode': 200,
'body': json.dumps({'message': f'Instancia {instance_id} actualizada con éxito.'})
}
except Exception as e:
return {
'statusCode': 500,
'body': json.dumps({'error': str(e)})
}
elif http_method == 'DELETE':
# Implementar la lógica para eliminar una instancia de EC2
instance_id = event['pathParameters']['instance_id']
# Crear una conexión con el servicio EC2
ec2_client = boto3.client('ec2')
try:
# Eliminar la instancia
ec2_client.terminate_instances(InstanceIds=[instance_id])
return {
'statusCode': 200,
'body': json.dumps({'message': f'Instancia {instance_id} eliminada con éxito.'})
}
except Exception as e:
return {
'statusCode': 500,
'body': json.dumps({'error': str(e)})
}
else:
return {
'statusCode': 400,
'body': json.dumps({'error': 'Método HTTP inválido.'})
}
except Exception as e:
return {
'statusCode': 500,
'body': json.dumps({'error': str(e)})
}
当我使用curl测试get和post块时效果很好并运行任务,但是当我尝试使用put和delete时会出现此错误{“message”:“缺少身份验证令牌”}并且不知道为什么?
我尝试修改和删除ec2实例
错误消息“缺少身份验证令牌”表明您尝试在未经正确身份验证的情况下访问 AWS 资源。这可能是由于您的 AWS Lambda 函数配置为访问 EC2 实例并修改/删除它们的方式所致。
当您请求修改或删除 EC2 实例时,您需要确保您的 Lambda 函数具有执行这些操作所需的权限。
boto3
库使用 Lambda 函数可用的 AWS 凭证来验证这些请求。
您可以采取以下几个步骤来排查和解决问题:
IAM 角色权限:确保分配给您的 Lambda 函数的 IAM 角色具有修改和删除 EC2 实例的必要权限。该角色应附加适当的策略,例如
AmazonEC2FullAccess
或授予所需权限的自定义策略。
环境变量:检查您是否已为 Lambda 函数配置必要的 AWS 环境变量。这些变量包括
AWS_ACCESS_KEY_ID
和 AWS_SECRET_ACCESS_KEY
。但是,建议对 Lambda 函数使用 IAM 角色,而不是硬编码凭证。
凭证链:如果将函数配置为使用 IAM 角色,则 Lambda 函数可以自动从 IAM 角色获取凭证。在本地运行时(出于测试目的),您应确保 AWS CLI 配置了必要的凭证 (
aws configure
)。
调用权限:如果您使用 API Gateway 触发 Lambda 函数,请确保 API Gateway 具有调用 Lambda 函数所需的 IAM 权限。这对于
PUT
和 DELETE
等方法尤其重要。
端点配置:确保您的 Lambda 函数部署在正确的区域中,并且您尝试修改或删除的 EC2 实例也在同一区域中。
VPC 配置:如果您的 Lambda 函数配置为在 VPC 中运行,您可能需要配置 VPC 和安全组以允许 Lambda 函数进行出站互联网访问。
请记住,Lambda 函数执行上下文可能会影响凭证和网络访问的可用性。使用
curl
进行本地测试可能无法完全模拟 Lambda 函数运行的环境。
此外,我注意到您正在使用
context.invoked_function_arn
来确定区域。虽然这可行,但确定区域的更可靠、更直接的方法是使用 boto3
的内置 session
对象:
import boto3
def ec2_crud(event, context):
region = boto3.Session().region_name
# ... rest of your code ...
请务必彻底检查您的 AWS IAM 设置、Lambda 配置以及测试 Lambda 函数的环境,以确保它具有必要的权限和资源来对 EC2 实例执行所需的操作。