簡體   English   中英

編寫 Boto3 過濾器以使用自定義標簽名稱的正確方法是什么?

[英]What is the correct ways to write Boto3 filters to use customise tag name?

我試圖列出不同標簽鍵的標簽值的實例例如>一個標簽鍵 - 環境,其他標簽鍵 - 角色。 我的代碼如下:

import argparse
import boto3

AWS_ACCESS_KEY_ID = '<Access Key>'
AWS_SECRET_ACCESS_KEY = '<Secret Key>'

def get_ec2_instances(Env,Role):
    ec2 = boto3.client("ec2", region)
    reservations = ec2.describe_instances(Filters={"tag:environment" :   Env, "tag:role" : Role})
    for reservation in reservations["Reservations"] :
        for instance in reservation["Instances"]:
             print  "%s" % (instance.tags['Name'])

if  __name__ == '__main__':

    regions = ['us-east-1','us-west-1','us-west-2','eu-west-1','sa-east-1',
               'ap-southeast-1','ap-southeast-2','ap-northeast-1']
    parser = argparse.ArgumentParser()
    parser.add_argument('Env', default="environment", help='value for   tag:environment');
    parser.add_argument('Role', default="role", help='value for tag:role');
    args = parser.parse_args()

    for region in regions: get_ec2_instances(args.Env, args.Role)

運行此腳本后:python script.py arg1 arg2

我收到以下錯誤

Traceback (most recent call last):
  File "script.py", line 27, in <module>
    for region in regions: get_ec2_instances(args.Env, args.Role)
  File "script.py", line 10, in get_ec2_instances
    reservations = ec2.describe_instances(Filters={"tag:environment" :  Env, "tag:role" : Role})
  File "/usr/local/lib/python2.7/dist-packages/botocore/client.py", line 258, in _api_call
    return self._make_api_call(operation_name, kwargs)
  File "/usr/local/lib/python2.7/dist-packages/botocore/client.py", line 524, in _make_api_call
    api_params, operation_model, context=request_context)
  File "/usr/local/lib/python2.7/dist-packages/botocore/client.py", line 577, in _convert_to_request_dict
    api_params, operation_model)
  File "/usr/local/lib/python2.7/dist-packages/botocore/validate.py", line 270, in serialize_to_request
    raise ParamValidationError(report=report.generate_report())
botocore.exceptions.ParamValidationError: Parameter validation failed:
Invalid type for parameter Filters, value: {'tag:role': 'arg1', 'tag:environment': 'arg2'}, type: <type 'dict'>, valid types: <type 'list'>, <type 'tuple'>

這看起來很熟悉,我有沒有在某個地方為某人修改過這個 ;-) 。 實際上,我編寫的代碼很匆忙,沒有經過適當的測試(我也懶得修改 % 字符串格式並將其替換為 str.format() )。 事實上,AWS 中沒有正確記錄使用 Filters 參數。

請參閱 Russell Ballestrini博客使用 Boto3 過濾 AWS 資源以了解有關正確 boto 過濾器方法的更多信息。

  1. 過濾器接受列表值,標簽內的信息應該是 dict。 因此 [{}]
  2. Boto3 文檔對於如何使用指定標簽名稱非常含糊。 當他們說您可以使用 tag:key 時,沒有示例會令人困惑。 很多人只會做[{"tag:keyname","Values": [""] }]而它不起作用。 (實際上,我假設開發人員知道過濾器的工作原理是原始代碼,所以我只是修改了結構)。
  3. 實際上,您必須明確指定“名稱”和“值”對。 所以指定標簽名稱的正確方法是[{"Name" :"tag:keyname", "Values":[""] }] 這很棘手。

因此,如果您想用於示例,則格式化過濾器的正確方法

filters = [{'Name':'tag:environment', 'Values':[Env]},
           {'Name':'tag:role', 'Values':[Role]}
          ]

(更新)並確保 argparse 使用字符串值,您只需強制參數使用字符串值

parser.add_argument('Env', type=str, default="environment",
                    help='value for   tag:environment');
parser.add_argument('Role', type=str,default="role",
                    help='value for tag:role');

雖然實際上不是您問題的答案,但不要永遠不要將您的 AWS 憑證硬編碼到您的腳本中。 憑借您的 AWS 憑證,任何人都可以使用您的賬戶。 有機器人在 github 和其他 git 存儲庫中尋找硬編碼的 AWS 憑證。

此外,在輪換憑據時,您的所有代碼都將被破壞,或者您將很難更新所有代碼。

一些替代方案改為硬編碼您的 AWS 憑證:

  1. 配置您的 ~/.aws/credentials 文件
  2. 使用 IAM 角色
  3. 使用 STS 來“承擔角色”

遵循此處描述的最佳實踐: 管理 AWS 訪問密鑰的最佳實踐

現在,為了回答您的問題,這里有一個關於如何按標簽過濾的示例:

argEnv = '<any_string_you_want_to_match_as_a_value_for_a_tag>'
ec2Client = boto3.client('ec2')
response = ec2Client.describe_instances(
    Filters=[
            {
                'Name': 'tag:Projeto',
                'Values': [argEnv]
        }
    ]
)

確保 'Value' 是一個列表而不是一個字符串。 例如,如果 'argEnv' 是一個字符串,請確保使用 '[]' 來封裝變量。

然后,如果您想查詢 Tag:Name 並獲取它的值(例如,您在控制台中為特定 EC2 實例設置的名稱):

for reservation in res['Reservations']:
    for instance in reservation['Instances']:
        for tag in instance['Tags']:
            if tag['Key'] == 'Name':
                consoleName = tag['Value']
print(consoleName)

輸出將是每個資源的名稱標簽的值。 如您所見,您必須遍歷結果才能獲得結果。 您可以在此處查看響應語法。

在我自己的 python 腳本中,我使用以下內容:

import boto3
ec2client = boto3.client('ec2','us-east-1')
response = ec2client.describe_instances(Filters=[{'Name' : 'instance-state-name','Values' : ['running']}])

修復 Env 和 Role,因為我不確定我的或沒有實際意義的答案是否有效,因為值數組需要字符串。

reservervations = ec2.describe_instances(
        Filters=[
           {'Name': 'tag:environment', 'Values': ['%s'], 'Name': 'tag:role', 'Values': ['%s']} % (Env, Role),
        ]]
    ).get(
        'Reservations', []
    )  

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM