Как определить отключенные регионы в AWS? - PullRequest
0 голосов
/ 17 мая 2019

AWS регулярно добавляет новые регионы.В то время как «старые» регионы включены по умолчанию для каждой учетной записи AWS, новые регионы отключены по умолчанию 1 .

Я пытаюсь сканировать определенный ресурс ввсе доступные регионы, использующие следующий код Python (псевдо):

regions = boto3_session.get_available_regions('rds')
for region in regions:
    boto_rds_client = boto3_session.client('rds', region_name=region)
    r_paginator = boto_rds_client.get_paginator('describe_db_instances')
    for rdses in r_paginator.paginate():
        for rds in rdses['DBInstances']:
            do_stuff(rds)

Однако это происходит с загадочным An error occurred (InvalidClientTokenId) when calling the DescribeDBInstances operation: The security token included in the request is invalid при доступе к «новому» региону.

Другие службы не работают с другимиошибки: например, лямбда не работает с An error occurred (UnrecognizedClientException) when calling the ListFunctions operation: The security token included in the request is invalid

Как я могу определить, включен регион или нет?Похоже, что для этого нет вызова API ...

Ответы [ 2 ]

1 голос
/ 17 мая 2019

Я обнаружил крайний случай API, который можно (ab) использовать для идентификации включенных областей: вызов API ec2: DescribeRegions (и, возможно, другие также не пытались) демонстрирует немного другой режим сбоя в отключенных областях:

  • Либо вызов выполнен успешно, и вы знаете, что регион включен

  • Вызов не выполнен с ошибкой UnauthorizedOperation.Это означает, что у вас нет разрешений IAM, но регион включен

  • Вызов не выполняется с AuthFailure.Это означает, что регион отключен

Следующий код успешно фильтрует регионы в моих тестовых случаях:

def get_enabled_regions(boto3_session: boto3.Session, service: str) -> typing.Set[str]:
    regions = boto3_session.get_available_regions(service)
    enabled_regions = set()
    for region in regions:
        ec2_client = boto3_session.client('ec2', region_name=region)
        try:
            ec2_client.describe_regions()
        except botocore.exceptions.ClientError as e:
            if e.response['Error']['Code'] == "AuthFailure":
                print(f"region {region} seems disabled, skipping")
                continue  # Account is disabled
            elif e.response['Error']['Code'] == "UnauthorizedOperation":
                print(f"region {region} seems enabled (but not sure)")
                pass  # Access denied is good: we have access to the region, just not to the ec2:DescribeRegions call
            else:
                raise
        enabled_regions.add(region)
    return enabled_regions
0 голосов
/ 17 мая 2019

Я немного больше поработал над этой проблемой и нашел способ, который меньше полагается на поведение пограничного случая: использование вызова sts:GetCallerIdentity.

Это имеет несколько преимуществ перед ec2:DescribeRegions в том, что APIвсегда включен (не может быть ограничен IAM).Вы можете отключить STS для региона, но даже в этом случае GetCallerIdentity по-прежнему работает (отключено только выдача временных учетных данных 1 ).

def get_enabled_regions(boto3_session: boto3.Session, service: str) -> typing.Set[str]:
    regions = boto3_session.get_available_regions(service)
    enabled_regions = set()
    for region in regions:
        sts_client = boto3_session.client('sts', region_name=region)
        try:
            sts_client.get_caller_identity()
            enabled_regions.add(region)
        except botocore.exceptions.ClientError as e:
            if e.response['Error']['Code'] == "InvalidClientTokenId":
                # error code received when region is disabled
                print(f"region {region} is disabled")
                pass
            else:
                raise
    return enabled_regions
...