如何在Windows Server 2019的Python S3上传脚本中自动获取最新AWS凭证
解决方案
1. 配置IAM权限
给运行脚本的Windows Server 2019对应的IAM实体(IAM用户或IAM Identity Center用户)配置两类最小权限:
- 针对目标AWS Secrets的读取权限(仅允许
secretsmanager:GetSecretValue操作) - 针对目标S3存储桶的上传权限(如
s3:PutObject、s3:ListBucket等必要操作)
2. 修改Python脚本,自动拉取最新凭证
移除从Windows Credential Manager(WCM)读取硬编码密钥的逻辑,改用boto3直接从AWS Secrets Manager获取最新凭证,再初始化S3客户端完成上传。示例代码如下:
import boto3 import json from botocore.exceptions import ClientError def fetch_latest_credentials(secret_name, region): # 初始化Secrets Manager客户端 sm_client = boto3.client("secretsmanager", region_name=region) try: secret_response = sm_client.get_secret_value(SecretId=secret_name) except ClientError as e: # 根据实际需求处理异常(如权限错误、Secret不存在等) raise RuntimeError(f"获取凭证失败: {e.response['Error']['Message']}") from e # 解析Secret内容(假设Secret为JSON格式,包含access_key和secret_key字段) secret_data = json.loads(secret_response["SecretString"]) return secret_data["access_key"], secret_data["secret_key"] def upload_file_to_s3(bucket, local_path, s3_key, access_key, secret_key): # 用最新凭证初始化S3客户端 s3_client = boto3.client( "s3", aws_access_key_id=access_key, aws_secret_access_key=secret_key ) s3_client.upload_file(local_path, bucket, s3_key) if __name__ == "__main__": # 替换为你的实际配置 SECRET_NAME = "your-secret-name" AWS_REGION = "us-east-1" S3_BUCKET = "your-target-bucket" LOCAL_FILE = "path/to/your/local/file" S3_OBJECT_KEY = "path/in/s3/file-name" # 获取最新凭证并上传 access_key, secret_key = fetch_latest_credentials(SECRET_NAME, AWS_REGION) upload_file_to_s3(S3_BUCKET, LOCAL_FILE, S3_OBJECT_KEY, access_key, secret_key)
3. 配置Windows Server的AWS基础访问
为让boto3正常访问Secrets Manager,给Windows Server配置持久化的AWS访问凭证(仅需配置一次):
- 推荐方案:IAM Identity Center(SSO)
安装AWS CLI后,运行aws configure sso,按照指引完成SSO登录。boto3会自动使用SSO缓存的凭证,且SSO凭证支持自动刷新,无需手动维护。 - 备选方案:专用IAM用户
创建仅拥有Secrets Manager读取权限的IAM用户,运行aws configure输入该用户的密钥。AWS CLI会自动将凭证存入WCM,boto3会自动读取,后续无需修改。
4. 验证自动生效逻辑
当AWS Secrets中的凭证更新后,脚本下次运行时会自动拉取最新值,完全无需手动操作。
额外优化
- 添加本地缓存:将获取到的凭证缓存到临时文件,设置59天的过期时间,减少Secrets Manager API调用次数。
- 增强错误处理:添加重试机制、日志记录或告警通知,避免因临时网络问题导致上传失败。
内容的提问来源于stack exchange,提问作者DealWithIt
相关产品推荐
相关产品推荐

