boto3 client NoRegionError: You must specify a region error only sometimes

boto3 client NoRegionError: You must specify a region error only sometimes

我有一个 boto3 客户端:

boto3.client('kms')

但它发生在新机器上,它们动态打开和关闭。

    if endpoint is None:
        if region_name is None:
            # Raise a more specific error message that will give
            # better guidance to the user what needs to happen.
            raise NoRegionError()

为什么会这样?为什么只有一部分时间?

不管怎样,您必须告诉 boto3 您希望在哪个区域创建 kms 客户端。这可以使用 region_name 参数显式完成,如:

kms = boto3.client('kms', region_name='us-west-2')

或者您可以在 ~/.aws/config 文件中设置与您的个人资料关联的默认区域,如:

[default]
region=us-west-2

或者您可以使用环境变量,如:

export AWS_DEFAULT_REGION=us-west-2

但您需要告诉 boto3 使用哪个区域。

我相信,默认情况下,boto 会选择在 aws cli 中设置的区域。您可以 运行 命令 #aws configure 并按回车键(它显示您在 aws cli 中设置的带有区域的凭据)两次以确认您的区域。

你也可以在脚本本身设置环境变量,而不是传递region_name参数

os.environ['AWS_DEFAULT_REGION'] = 'your_region_name'

区分大小写可能很重要。

os.environ['AWS_DEFAULT_REGION'] = 'your_region_name'

对我来说,敏感度很重要。

对于 Python 2 我发现如果该区域是在不同的配置文件中定义的,则 boto3 库不会从 ~/.aws/config 中获取该区域。 所以你必须在会话创建中定义它。

session = boto3.Session(
    profile_name='NotDefault',
    region_name='ap-southeast-2'
)

print(session.available_profiles)

client = session.client(
    'ec2'
)

我的 ~/.aws/config 文件如下所示:

[default]
region=ap-southeast-2

[NotDefault]
region=ap-southeast-2

我这样做是因为我对 AWS、个人和工作的不同登录使用不同的配置文件。

对于那些使用 CloudFormation 模板的人。您可以使用 UserData 和 AWS::Region 设置 AWS_DEFAULT_REGION 环境变量。例如,

MyInstance1:
    Type: AWS::EC2::Instance                
    Properties:                           
        ImageId: ami-04b9e92b5572fa0d1 #ubuntu
        InstanceType: t2.micro
        UserData: 
            Fn::Base64: !Sub |
                    #!/bin/bash -x

                    echo "export AWS_DEFAULT_REGION=${AWS::Region}" >> /etc/profile

或者您可以 运行 以下 (aws cli)

aws configure --profile $PROFILE_NAME

它会提示您选择区域。

注意 ~/.aws/config 是:

[default]
region = ap-southeast-1
output = json

[profile prod]
region = ap-southeast-1
output = json

[个人资料个人资料名称]中括号

如果您使用的是 lambda,那么您可能希望使用部署了 lambda 的区域。 您可以使用以下

import boto3
import json
import os

def lambda_handler(event, context):
    region = os.environ['AWS_REGION']
    print('Lambda region: ', region)
    kms = boto3.client('kms', region_name=region)

我们将配置的区域存储在我们的 ~/.aws/config 文件中。这是一种纯粹的 python 方法,可以根据配置文件名称从此文件中读取正确的区域:

def get_aws_region(profile_name: str) -> str:
  config = configparser.ConfigParser()
  config.read(f"{os.environ['HOME']}/.aws/config")
  profile_section = config[f"profile {profile_name}"]
  return profile_section["region"]

regions = [
            'eu-north-1', 'ap-south-1', 'eu-west-3', 'eu-west-2',
            'eu-west-1', 'ap-northeast-3', 'ap-northeast-2'
            'ap-northeast-1', 'sa-east-1', 'ca-central-1', 
            'ap-southeast-2', 'eu-central-1', 'us-east-1', 'us-east-2',
            'us-west-1', 'us-west-2']
for r in regions:
   kms = boto3.client('kms', region_name= r)

如果您使用 AWS Lambda,您的代码将在您部署时运行, 因为Lambda部署在特定区域。