文档 AWS SDK 示例 GitHub 存储库中还有更多 S AWS DK 示例
本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。
将硬编码的密钥移动到 Secrets Manager
以下代码示例展示了如何:
创建 IAM 角色
在 Secrets Manager 中创建密钥
更新您的应用程序代码。
更新密钥
清理资源
- Bash
-
- AWS CLI 使用 Bash 脚本
-
注意
还有更多相关信息 GitHub。在 Sample developer tutorials
存储库中查找完整示例,了解如何进行设置和运行。 #!/bin/bash # Script to move hardcoded secrets to AWS Secrets Manager # This script demonstrates how to create IAM roles, store a secret in AWS Secrets Manager, # and set up appropriate permissions set -euo pipefail # Set up logging LOG_FILE="secrets_manager_tutorial.log" exec > >(tee -a "$LOG_FILE") 2>&1 echo "Starting AWS Secrets Manager tutorial script at $(date)" echo "======================================================" # Function to check for errors in command output check_error() { local output=$1 local cmd=$2 if echo "$output" | grep -qi "error"; then echo "ERROR: Command failed: $cmd" echo "$output" cleanup_resources exit 1 fi } # Function to generate a random identifier using secure method generate_random_id() { python3 -c "import secrets; print('sm' + secrets.token_hex(4))" } # Function to safely clean up resources cleanup_resources() { echo "" echo "===========================================" echo "RESOURCES CREATED" echo "===========================================" if [ -n "${SECRET_NAME:-}" ]; then echo "Secret: $SECRET_NAME" fi if [ -n "${RUNTIME_ROLE_NAME:-}" ]; then echo "IAM Role: $RUNTIME_ROLE_NAME" fi if [ -n "${ADMIN_ROLE_NAME:-}" ]; then echo "IAM Role: $ADMIN_ROLE_NAME" fi echo "" echo "===========================================" echo "CLEANUP CONFIRMATION" echo "===========================================" echo "Cleaning up all created resources..." # Delete secret if it exists if [ -n "${SECRET_NAME:-}" ]; then echo "Deleting secret: $SECRET_NAME" aws secretsmanager delete-secret --secret-id "$SECRET_NAME" --force-delete-without-recovery 2>/dev/null || true fi # Detach policies and delete runtime role if it exists if [ -n "${RUNTIME_ROLE_NAME:-}" ]; then echo "Deleting inline policies from runtime role: $RUNTIME_ROLE_NAME" for policy in $(aws iam list-role-policies --role-name "$RUNTIME_ROLE_NAME" --query 'PolicyNames[]' --output text 2>/dev/null || true); do aws iam delete-role-policy --role-name "$RUNTIME_ROLE_NAME" --policy-name "$policy" 2>/dev/null || true done echo "Deleting IAM role: $RUNTIME_ROLE_NAME" aws iam delete-role --role-name "$RUNTIME_ROLE_NAME" 2>/dev/null || true fi # Detach policies and delete admin role if it exists if [ -n "${ADMIN_ROLE_NAME:-}" ]; then echo "Detaching policy from role: $ADMIN_ROLE_NAME" aws iam detach-role-policy --role-name "$ADMIN_ROLE_NAME" --policy-arn "arn:aws:iam::aws:policy/SecretsManagerReadWrite" 2>/dev/null || true for policy in $(aws iam list-role-policies --role-name "$ADMIN_ROLE_NAME" --query 'PolicyNames[]' --output text 2>/dev/null || true); do aws iam delete-role-policy --role-name "$ADMIN_ROLE_NAME" --policy-name "$policy" 2>/dev/null || true done echo "Deleting IAM role: $ADMIN_ROLE_NAME" aws iam delete-role --role-name "$ADMIN_ROLE_NAME" 2>/dev/null || true fi echo "Cleanup completed." } # Trap to ensure cleanup on script exit trap 'echo "Script interrupted. Running cleanup..."; cleanup_resources' INT TERM EXIT # Generate random identifiers for resources ADMIN_ROLE_NAME="SecretsManagerAdmin-$(generate_random_id)" RUNTIME_ROLE_NAME="RoleToRetrieveSecretAtRuntime-$(generate_random_id)" SECRET_NAME="MyAPIKey-$(generate_random_id)" echo "Using the following resource names:" echo "Admin Role: $ADMIN_ROLE_NAME" echo "Runtime Role: $RUNTIME_ROLE_NAME" echo "Secret Name: $SECRET_NAME" echo "" # Step 1: Create IAM roles echo "Creating IAM roles..." # Create assume role policy document ASSUME_ROLE_POLICY=$(cat <<'EOF' { "Version":"2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Service": "ec2.amazonaws.com" }, "Action": "sts:AssumeRole" } ] } EOF ) # Create the SecretsManagerAdmin role echo "Creating admin role: $ADMIN_ROLE_NAME" ADMIN_ROLE_OUTPUT=$(aws iam create-role \ --role-name "$ADMIN_ROLE_NAME" \ --assume-role-policy-document "$ASSUME_ROLE_POLICY" 2>&1) check_error "$ADMIN_ROLE_OUTPUT" "create-role for admin" echo "$ADMIN_ROLE_OUTPUT" aws iam tag-role --role-name "$ADMIN_ROLE_NAME" --tags Key=project,Value=doc-smith Key=tutorial,Value=aws-secrets-manager-gs # Attach the SecretsManagerReadWrite policy to the admin role echo "Attaching SecretsManagerReadWrite policy to admin role" ATTACH_POLICY_OUTPUT=$(aws iam attach-role-policy \ --role-name "$ADMIN_ROLE_NAME" \ --policy-arn "arn:aws:iam::aws:policy/SecretsManagerReadWrite" 2>&1) check_error "$ATTACH_POLICY_OUTPUT" "attach-role-policy for admin" echo "Policy attached successfully" # Create the RoleToRetrieveSecretAtRuntime role echo "Creating runtime role: $RUNTIME_ROLE_NAME" RUNTIME_ROLE_OUTPUT=$(aws iam create-role \ --role-name "$RUNTIME_ROLE_NAME" \ --assume-role-policy-document "$ASSUME_ROLE_POLICY" 2>&1) check_error "$RUNTIME_ROLE_OUTPUT" "create-role for runtime" echo "$RUNTIME_ROLE_OUTPUT" aws iam tag-role --role-name "$RUNTIME_ROLE_NAME" --tags Key=project,Value=doc-smith Key=tutorial,Value=aws-secrets-manager-gs # Wait for roles to be fully created echo "Waiting for IAM roles to be fully created..." sleep 10 # Step 2: Create a secret in AWS Secrets Manager echo "Creating secret in AWS Secrets Manager..." # Generate secure secret value using environment variable or secure method # WARNING: In production, use secure methods to inject secrets (AWS CodeBuild, parameter store, etc.) if [ -z "${TUTORIAL_SECRET_VALUE:-}" ]; then SECRET_VALUE=$(python3 -c "import json; print(json.dumps({'ClientID':'my_client_id','ClientSecret':__import__('secrets').token_urlsafe(32)}))") else SECRET_VALUE="$TUTORIAL_SECRET_VALUE" fi CREATE_SECRET_OUTPUT=$(aws secretsmanager create-secret \ --name "$SECRET_NAME" \ --description "API key for my application" \ --secret-string "$SECRET_VALUE" \ --add-replica-regions 'Region=us-east-1' \ --tags Key=project,Value=doc-smith Key=tutorial,Value=aws-secrets-manager-gs 2>&1) check_error "$CREATE_SECRET_OUTPUT" "create-secret" echo "$CREATE_SECRET_OUTPUT" # Get AWS account ID echo "Getting AWS account ID..." ACCOUNT_ID=$(aws sts get-caller-identity --query "Account" --output text 2>&1) check_error "$ACCOUNT_ID" "get-caller-identity" echo "Account ID: $ACCOUNT_ID" # Get secret ARN for precise resource policy echo "Getting secret ARN..." SECRET_ARN=$(aws secretsmanager describe-secret \ --secret-id "$SECRET_NAME" \ --query 'ARN' \ --output text 2>&1) check_error "$SECRET_ARN" "describe-secret" # Add resource policy to the secret with least privilege echo "Adding resource policy to secret..." RESOURCE_POLICY=$(cat <<EOF { "Version":"2012-10-17", "Statement": [ { "Sid": "AllowRuntimeRoleReadSecret", "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::$ACCOUNT_ID:role/$RUNTIME_ROLE_NAME" }, "Action": "secretsmanager:GetSecretValue", "Resource": "$SECRET_ARN", "Condition": { "StringEquals": { "secretsmanager:VersionStage": "AWSCURRENT" } } } ] } EOF ) PUT_POLICY_OUTPUT=$(aws secretsmanager put-resource-policy \ --secret-id "$SECRET_NAME" \ --resource-policy "$RESOURCE_POLICY" \ --block-public-policy 2>&1) check_error "$PUT_POLICY_OUTPUT" "put-resource-policy" echo "Resource policy added successfully" # Enable rotation policy recommendation echo "Enabling secret metadata tags for rotation tracking..." aws secretsmanager tag-resource \ --secret-id "$SECRET_NAME" \ --tags Key=Purpose,Value=Tutorial Key=AutoRotation,Value=Recommended 2>/dev/null || true # Step 3: Demonstrate retrieving the secret echo "Retrieving the secret value (for demonstration purposes)..." GET_SECRET_OUTPUT=$(aws secretsmanager get-secret-value \ --secret-id "$SECRET_NAME" 2>&1) check_error "$GET_SECRET_OUTPUT" "get-secret-value" echo "Secret retrieved successfully. Secret metadata:" echo "$GET_SECRET_OUTPUT" | jq '{ARN: .ARN, Name: .Name, LastUpdatedDate: .LastUpdatedDate, VersionIdsToStages: .VersionIdsToStages}' 2>/dev/null || echo "Secret metadata retrieved (jq not available)" # Step 4: Update the secret with new values echo "Updating the secret with new values..." UPDATE_SECRET_VALUE=$(python3 -c "import json; print(json.dumps({'ClientID':'my_new_client_id','ClientSecret':__import__('secrets').token_urlsafe(32)}))") UPDATE_SECRET_OUTPUT=$(aws secretsmanager update-secret \ --secret-id "$SECRET_NAME" \ --secret-string "$UPDATE_SECRET_VALUE" 2>&1) check_error "$UPDATE_SECRET_OUTPUT" "update-secret" echo "Secret updated successfully" # Step 5: Verify the updated secret echo "Verifying the updated secret..." VERIFY_SECRET_OUTPUT=$(aws secretsmanager get-secret-value \ --secret-id "$SECRET_NAME" 2>&1) check_error "$VERIFY_SECRET_OUTPUT" "get-secret-value for verification" echo "Updated secret retrieved successfully. Secret metadata:" echo "$VERIFY_SECRET_OUTPUT" | jq '{ARN: .ARN, Name: .Name, LastUpdatedDate: .LastUpdatedDate, VersionIdsToStages: .VersionIdsToStages}' 2>/dev/null || echo "Secret metadata retrieved (jq not available)" # Step 6: Display rotation recommendations echo "" echo "Rotation Configuration Recommendations:" echo "========================================" DESCRIBE_OUTPUT=$(aws secretsmanager describe-secret --secret-id "$SECRET_NAME" 2>&1) if echo "$DESCRIBE_OUTPUT" | grep -q "RotationRules"; then echo "Current rotation configuration:" echo "$DESCRIBE_OUTPUT" | jq '.RotationRules' 2>/dev/null || echo "Rotation rules available" else echo "No automatic rotation configured. Consider enabling rotation with:" echo "aws secretsmanager rotate-secret --secret-id $SECRET_NAME --rotation-lambda-arn arn:aws:lambda:REGION:ACCOUNT:function:FUNCTION_NAME --rotation-rules AutomaticallyAfterDays=30" fi echo "" echo "======================================================" echo "Tutorial completed successfully!" echo "" echo "Summary of what we did:" echo "1. Created IAM roles for managing and retrieving secrets" echo "2. Created a secret in AWS Secrets Manager with secure generation" echo "3. Added a least-privilege resource policy to control access to the secret" echo "4. Retrieved the secret value (simulating application access)" echo "5. Updated the secret with cryptographically secure values" echo "6. Verified the updated secret" echo "" echo "Security best practices applied:" echo "- Used cryptographically secure random ID generation" echo "- Applied least-privilege resource policies with version stages" echo "- Tagged resources for rotation tracking" echo "- Blocked public access to secrets" echo "- Used ARN-specific permissions instead of wildcards" echo "" echo "Next steps you might want to consider:" echo "- Enable automatic secret rotation with AWS Lambda" echo "- Implement secret caching in your application" echo "- Set up CloudTrail logging for secret access auditing" echo "- Use AWS CodeGuru Reviewer to find hardcoded secrets in your code" echo "- For multi-region applications, replicate your secrets across regions" echo "- Configure VPC endpoints for private access to Secrets Manager" echo "" echo "Script completed at $(date)" exit 0-
有关 API 详细信息,请参阅《AWS CLI 命令参考》中的以下主题。
-
管理您的账户
权限策略允许 AWS Compute Optimizer Automation 应用建议的操作