PowerShell变量替换AWS CLI CloudFormation参数值异常问题
问题
通过PowerShell结合变量部署AWS CloudFormation栈,配置AWS Config的公共RDS检测规则时,硬编码$topicname和$sns_message参数值能正常创建栈,但使用变量传递时,CLI调用中的参数被忽略。变量在控制台及CLI外部输出正常,权限及硬编码场景测试均无问题,仅变量传递时失效。
相关代码:
# Variables $default_region = 'eu-west-1' $aws_profile = Read-Host -Prompt 'Input AWS CLI profile name' if (!($aws_region = Read-Host "Enter Region [$default_region]")) { $aws_region = $default_region } if (!($environment = Read-Host "Enter Environment Name [$aws_profile]")) { $environment = $aws_profile } $topicname = "rds_instance_public_access_check_$($aws_region)" $sns_message = "Public RDS Detected in $($environment) - $($aws_region)" # Create the RDS Public Instance stack aws cloudformation create-stack --stack-name rds-instance-public-access-check-rules --template-body file://config_public_rds.yml --parameters ParameterKey=ViolationMessage,ParameterValue=$sns_message ParameterKey=TopicName,ParameterValue=$topicname --profile $aws_profile --region $aws_region
原因
PowerShell会将带空格的字符串自动拆分为多个独立参数,而AWS CLI要求每个ParameterKey=...,ParameterValue=...是一个完整的参数项。当$sns_message包含空格时,PowerShell会把参数值拆分成多个部分,导致AWS CLI无法正确解析完整的参数值,进而出现参数被忽略的情况。
解决方案
方法1:手动包裹并转义参数
给每个ParameterKey/ParameterValue键值对添加双引号,同时转义参数值内部的引号,确保PowerShell将整个键值对作为一个参数传递给AWS CLI:
# Variables $default_region = 'eu-west-1' $aws_profile = Read-Host -Prompt 'Input AWS CLI profile name' if (!($aws_region = Read-Host "Enter Region [$default_region]")) { $aws_region = $default_region } if (!($environment = Read-Host "Enter Environment Name [$aws_profile]")) { $environment = $aws_profile } $topicname = "rds_instance_public_access_check_$($aws_region)" $sns_message = "Public RDS Detected in $($environment) - $($aws_region)" # Create the RDS Public Instance stack with properly quoted parameters aws cloudformation create-stack ` --stack-name rds-instance-public-access-check-rules ` --template-body file://config_public_rds.yml ` --parameters "ParameterKey=ViolationMessage,ParameterValue=`"$sns_message`"" "ParameterKey=TopicName,ParameterValue=`"$topicname`"" ` --profile $aws_profile ` --region $aws_region
方法2:使用JSON格式传递参数(推荐)
将参数整理为JSON格式,避免引号转义的繁琐操作,同时确保参数传递的稳定性:
# Variables $default_region = 'eu-west-1' $aws_profile = Read-Host -Prompt 'Input AWS CLI profile name' if (!($aws_region = Read-Host "Enter Region [$default_region]")) { $aws_region = $default_region } if (!($environment = Read-Host "Enter Environment Name [$aws_profile]")) { $environment = $aws_profile } $topicname = "rds_instance_public_access_check_$($aws_region)" $sns_message = "Public RDS Detected in $($environment) - $($aws_region)" # Build parameters as JSON $paramsJson = @" [ { "ParameterKey": "ViolationMessage", "ParameterValue": "$sns_message" }, { "ParameterKey": "TopicName", "ParameterValue": "$topicname" } ] "@ # Create the RDS Public Instance stack with JSON parameters aws cloudformation create-stack ` --stack-name rds-instance-public-access-check-rules ` --template-body file://config_public_rds.yml ` --parameters $paramsJson ` --profile $aws_profile ` --region $aws_region
内容的提问来源于stack exchange,提问作者Gavin Doris
相关产品推荐
相关产品推荐

