Какую роль IAM следует назначить лямбда-функции aws, чтобы она могла получить статус кластера emr - PullRequest
1 голос
/ 12 июля 2019

Я подготовил простую лямбда-функцию в AWS для завершения длительно работающих кластеров EMR после достижения определенного порога. Этот фрагмент кода протестирован локально и работает отлично. Теперь я поместил его в лямбду, позаботился о зависимостях библиотеки, так что это тоже хорошо Эта лямбда запускается из правила CloudWatch, которое является простым расписанием cron. Я использую существующее правило IAM, к которому прикреплены эти 7 политик.

  • SecretsManagerReadWrite
  • AmazonSQSFullAccess
  • AmazonS3FullAccess
  • CloudWatchFullAccess
  • AWSGlueServiceRole
  • AmazonSESFullAccess
  • AWSLambdaRole

Я настроил лямбду в той же группе vpc и security, что и в emr. Тем не менее я получаю эту ошибку последовательно:

An error occurred (AccessDeniedException) when calling the ListClusters operation: User: arn:aws:sts::xyz:assumed-role/dev-lambda-role/terminate_inactive_dev_emr_clusters is not authorized to perform: elasticmapreduce:ListClusters on resource: *: ClientError
Traceback (most recent call last):
File "/var/task/terminate_dev_emr.py", line 24, in terminator
ClusterStates=['STARTING', 'BOOTSTRAPPING', 'RUNNING', 'WAITING']
File "/var/runtime/botocore/client.py", line 314, in _api_call
return self._make_api_call(operation_name, kwargs)
File "/var/runtime/botocore/client.py", line 612, in _make_api_call
raise error_class(parsed_response, operation_name)
botocore.exceptions.ClientError: An error occurred (AccessDeniedException) when calling the ListClusters operation: User: arn:aws:sts::xyz:assumed-role/dev-lambda-role/terminate_inactive_dev_emr_clusters is not authorized to perform: elasticmapreduce:ListClusters on resource: *

Моя лямбда-функция выглядит примерно так:

import pytz
import boto3
from datetime import datetime, timedelta

def terminator(event, context):
    ''' cluster lifetime limit in hours '''
    LIMIT = 7
    TIMEZONE = 'Asia/Kolkata'
    AWS_REGION = 'eu-west-1'

    print('Start cluster check')

    emr = boto3.client('emr', region_name=AWS_REGION)

    local_tz = pytz.timezone(TIMEZONE)
    today = local_tz.localize(datetime.today(), is_dst=None)
    lifetimelimit = today - timedelta(hours=LIMIT)

    clusters = emr.list_clusters(
        CreatedBefore=lifetimelimit,
        ClusterStates=['STARTING', 'BOOTSTRAPPING', 'RUNNING', 'WAITING']
    )

    if clusters['Clusters'] is not None:
        for cluster in clusters['Clusters']:
            description = emr.describe_cluster(ClusterId=cluster['Id'])
            if(len(description['Cluster']['Tags']) == 1 
                and description['Cluster']['Tags'][0]['Key'] == 'dev.ephemeral'):
                print('Terminating Cluster: [{id}] with name [{name}]. It was active since: [{time}]'.format(id=cluster['Id'], name=cluster['Name'], time=cluster['Status']['Timeline']['CreationDateTime'].strftime('%Y-%m-%d %H:%M:%S')))
                emr.terminate_job_flows(JobFlowIds=[cluster['Id']])

    print('cluster check done')

    return

Любая помощь приветствуется.

1 Ответ

1 голос
/ 12 июля 2019

Как указывает сообщение об ошибке, лямбда не имеет разрешений для вызова ListClusters на EMR.Поскольку вы работаете с кластерами EMR, а также хотите завершить работу кластеров, вы должны назначить лямбда-функции надлежащую роль IAM, обладающую такой способностью для этого.Создайте новую политику IAM из консоли AWS (скажем, EMRFullAccess).Вот как это выглядит

 {
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": "elasticmapreduce:*",
            "Resource": "*"
        }
    ]
}

После создания политики создайте новую роль из консоли AWS с лямбда-выражением в качестве службы и присоедините новую созданную политику выше.После этого прикрепите эту роль к вашей лямбда-функции.Это должно решить проблему: -)

...