尝试在 AWS 中自动创建程序化 IAM 用户

Attempting to Automate creation of Programmatic IAM User in AWS

我必须创建一些编程用户来访问我的 AWS 环境,我认为创建一个函数来分发到每个账户会很有用。

目的是触发一次性创建具有编程访问权限的 IAM 用户,并将密钥存储在 Secrets Manager 中,同时尽可能隐藏密钥(即函数中的 none ,none 在记录中,none 在传输中)直到登陆 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 变体,删除了未使用的描述符,将它们注释掉,让它们可用。所有这些都让我犯了类似的错误。我已经阅读了以下文档,但我相信我遗漏了一些非常简单的东西。此外,无论我尝试过什么,它都会继续告诉我我的参数 class 是 'dict' 而它需要是 'string',我只是遵循 aws 文档中的格式。

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

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

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

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

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

我还通过以下不同的方法得到了它:

    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'
            },
        ]
    )

对于任何好奇的人!