首页 > 解决方案 > 使用 lambda 函数复制 ami 失败,kms 密钥无法访问

问题描述

我正在使用下面的 boto3 python 脚本将 AMI 从目标 AWS 账户复制到源账户。lambda 脚本正在源帐户上运行。

它从目标账户初始化源账户上的 AMI 副本。但是给出了这个错误:

"AMI snapshot copy failed with error: Given key ID is not accessible"

此处使用的 KMS 密钥属于源账户,该账户已附加了具有 kms:* 权限的 lambda 函数的 IAM 角色。

import boto3

target_account_id = 'TXXXXXXXXXXX'
source_account_id = 'SXXXXXXXXXXX'
source_profile = 'aws-cli-profile'
role_on_target_account = 'arn:aws:iam::TTTTTTTTTT:role/CopyAmiLambdaFunction'
source_region = 'eu-west-2'
target_region = 'eu-west-1'

def get_main_session():
    """
    This function returns the main session of the Master/Mgmt account.
    """
    # session = boto3.Session(profile_name=source_profile, region_name=source_region)
    print("Creating local session")
    session = boto3.Session(region_name=source_region)
    return session

def get_temp_cred(session, role_arn, account_id):
    """
    This function returns the temporary credentials using the trust
    relationship
    """
    print("Getting temp credentials")
    get_cred_client = session.client('sts')
    get_cred_response = get_cred_client.assume_role(\
        RoleArn=role_arn,
        RoleSessionName=account_id)
    return get_cred_response['Credentials']


def get_temp_session(cred, region):
    """
    This function returns the temporary session, using the temporary
    AccessKeyId, SecretAccessKey and the SessionToken returned by the
    temporary credentials
    """
    print("Creating temp session")
    temp_session = boto3.Session(\
        aws_access_key_id=cred['AccessKeyId'],
        aws_secret_access_key=cred['SecretAccessKey'],
        aws_session_token=cred['SessionToken'],
        region_name=region)
    return temp_session


def add_launch_permission(session, region):
    """
    This function reurns the list of filtered AMI
    """
    print("Retreiving list of images")
    ec2 = session.resource('ec2', region_name = region)
    images = ec2.images.filter(Filters=[{'Name':'name', 'Values':['amiiiiii-xxxx-iddd']}])
    for i in images:
        response = i.modify_attribute(
            Attribute='launchPermission',
            LaunchPermission={
                'Add': [
                    {
                        'UserId': source_account_id
                    }
                ]
            },
            OperationType='add'
        )
        print(response)
        
    for i in images:
        devices = i.block_device_mappings
        for device in devices:
            if 'Ebs' in device:
                snapshot_id = device["Ebs"]["SnapshotId"]
                snapshot = ec2.Snapshot(snapshot_id)
                snapshot.modify_attribute(
                            Attribute = 'createVolumePermission',
                            CreateVolumePermission = {
                                'Add' : [{ 'UserId': source_account_id }]
                                },
                            OperationType = 'add',
                            )

    return images

def copy_ami(session, source_region, target_region, ami_id):
    """
    This function is used to copy the unencrypted AMI to encrypted AMI using KMS key in BU account.
    """
    print("Start copy of AMI")
    for i in ami_id:
        client = session.client('ec2', region_name = source_region)
        response = client.copy_image(
            Description='Encrypted Golden Image',
            Encrypted=True,
            KmsKeyId='arn:aws:kms:eu-west-2:SXXXXXXXXXX:key/fabc4ee4-2c73-4c8d-a93e-ca572053a124',
            Name='Demo-Copy-AMI',
            SourceImageId=i.id,
            SourceRegion=target_region
        )
        return response["ImageId"]

def lambda_handler(event,context):
    #Get Main Session
    session = get_main_session()
    #Get Temp Cred
    temp_cred = get_temp_cred(session, role_on_target_account, target_account_id)
    #Get Temp Session
    temp_session = get_temp_session(temp_cred, target_region)
    #Add Launch permission for AMI
    ami_id = add_launch_permission(temp_session , target_region)
    print(ami_id)
    #Copy AMI
    image_id = copy_ami(session, source_region, target_region, ami_id)
    print(image_id)

标签: pythonamazon-web-servicesamazon-ec2aws-lambdaamazon-ami

解决方案


推荐阅读