【问题标题】:Attempting to Automate creation of Programmatic IAM User in AWS尝试在 AWS 中自动创建程序化 IAM 用户
【发布时间】:2021-05-11 12:00:39
【问题描述】:

我必须创建相当多的编程用户,以便工具访问我的 AWS 环境,我认为创建一个分配给每个帐户的函数会很有用。

目的是触发一次创建具有编程访问权限的 IAM 用户,并将密钥存储在 Secrets Manager 中,同时尽可能隐藏密钥(即函数中没有,日志中没有,以及没有在传输中),直到登陆 Secrets Manager。

我已为此特定函数设置了 lambda 权限,以拒绝生成 CloudWatch 或 CloudTrail 日志(通过测试似乎可以正常运行)。然而,秘密的创造给了我似乎无法解决的问题。以下是我的脚本:

import boto3, json
from botocore.exceptions import ClientError


def lambda_handler(event, context):
    iam_client = boto3.client('iam')

    user_name = 'tenable-cc-test'
    policy_arn = 'arn:aws:iam::aws:policy/ReadOnlyAccess'
    
    account_id = boto3.client("sts").get_caller_identity()["Account"]

    try:
        user = iam_client.create_user(
            UserName=user_name,
            Tags=[
                {
                    'Key': 'donotdelete',
                    'Value': 'yes'
                }
            ]
        )
    except ClientError as error:
        if error.response['Error']['Code'] == 'EntityAlreadyExists':
            return 'User {0} is already available'.format(user_name)
        else:
            return 'Unexpected error occurred... User {0} could not be created'.format(user_name)

    try:
        iam_client.attach_user_policy(
            UserName=user_name,
            PolicyArn=policy_arn
        )
    except ClientError as error:
        print('Unexpected error occurred while attaching policy... cleaning up', error)
        iam_client.delete_user(UserName=user_name)
        return 'User could not be created', error

    try:
        access_secrete_key = iam_client.create_access_key(
            UserName=user_name
        )
    except ClientError as error:
        print('Unexpected error occurred while creating access key... cleaning up')
        iam_client.detach_user_policy(
            UserName= user_name,
            PolicyArn= policy_arn
        )
        iam_client.delete_user(UserName=user_name)
        return 'User could not be created', error

    print('User {0} has been created successfully'.format(user_name))

    access_key = access_secrete_key['AccessKey']['AccessKeyId']
    secret_key = access_secrete_key['AccessKey']['SecretAccessKey']

    sm = boto3.client('secretsmanager')

    sm.create_secret(
        Name='tenable-cc-keys',
        #ClientRequestToken='string',
        Description='Keys for tenable-cc user.',
        #KmsKeyId='string',
        #SecretBinary=b'bytes',
        SecretString={
            'username': 'access_key',
            'password': 'secret_key'
        },
        Tags=[
            {
                'Key': 'donotdelete',
                'Value': 'yes'
            },
        ]
    )
    
    print('Account:', account_id)
    print('Access Key:', access_key)
    print('Secret Key:', secret_key)

我收到的错误是:

{
  "errorMessage": "Parameter validation failed:\nInvalid type for parameter SecretString, value: {'username': 'access_key', 'password': 'secret_key'}, type: <class 'dict'>, valid types: <class 'str'>",
  "errorType": "ParamValidationError",
  "stackTrace": [
    "  File \"/var/task/lambda_function.py\", line 72, in lambda_handler\n    'Value': 'yes'\n",
    "  File \"/var/runtime/botocore/client.py\", line 357, in _api_call\n    return self._make_api_call(operation_name, kwargs)\n",
    "  File \"/var/runtime/botocore/client.py\", line 649, in _make_api_call\n    api_params, operation_model, context=request_context)\n",
    "  File \"/var/runtime/botocore/client.py\", line 697, in _convert_to_request_dict\n    api_params, operation_model)\n",
    "  File \"/var/runtime/botocore/validate.py\", line 297, in serialize_to_request\n    raise ParamValidationError(report=report.generate_report())\n"
  ]
}

我已经尝试了各种我能想到的 SecretString 变体,删除了未使用的描述符,将它们注释掉,让它们可用。所有这些都导致我出现类似的错误。我已经倾注了以下文档,我相信我遗漏了一些非常简单的东西。此外,无论我尝试了什么,它都会继续告诉我,我的 Parameter 类在需要为“字符串”时是“dict”,我只是遵循 aws 文档中的格式。

https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/secretsmanager.html

任何人都可以提供一些建议吗?非常感谢任何帮助!

【问题讨论】:

    标签: amazon-web-services aws-lambda boto3 amazon-iam aws-secrets-manager


    【解决方案1】:

    SecretString 应该是 string,而不是字典。一种方法是使用 json.dumps 将您的 dict 转换为 json 字符串:

    SecretString=json.dumps({
                'username': 'access_key',
                'password': 'secret_key'
            }),
    

    【讨论】:

      【解决方案2】:

      以上答案有效!谢谢马辛。

      我还用下面的不同方法让它工作:

          sm= boto3.client('secretsmanager')
          
          sm.create_secret(
              Name='tenable-user-keys',
              #ClientRequestToken='string',
              Description='Tenable CC User keys.',
              #KmsKeyId='string',
              #SecretBinary=b'bytes',
              SecretString="{\"Access Key\":\" %s \",\"Secret Key\":\" %s \"}" % (access_key, secret_key),
              Tags=[
                  {
                      'Key': 'donotdelete',
                      'Value': 'yes'
                  },
              ]
          )
      

      对于任何好奇的人!

      【讨论】:

        猜你喜欢
        • 2021-11-12
        • 2021-10-15
        • 2020-07-12
        • 2019-11-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-12-24
        相关资源
        最近更新 更多