如何将值归因于在模板中的堆栈中创建的参数?
How do I attribute values to parameters created within stacks in a template?
部署 CloudFormation 模板时出现以下错误。
✖ Failed to create the stack.
An error occurred (ValidationError) when calling the CreateStack operation: Parameters: [ClusterArn, TaskRoleArn, Env, Subnets, ExecRoleArn, ClusterLogGroup, ContainerSG] must have values
我不知道如何将值归因于指定的参数,因为它们是在堆栈中创建的。例如 ContainerSG 和 LogGroup :
Parameters:
ContainerSG:
Description: The container security group
Type: String
ClusterLogGroup:
Description: The cluster log group
Type: String
Resources
LogGroup:
Type: AWS::Logs::LogGroup
Properties:
LogGroupName: !Join [ '/', ['/aws', 'ecs', !Ref Env]]
ContainerSecurityGroup:
Type : AWS::EC2::SecurityGroup
Properties :
GroupDescription : "ECS Containers Security Group"
VpcId : '{{resolve:ssm:/ca/config/network/vpc_id:1}}'
GroupName: security-group-cmr
SecurityGroupIngress :
- IpProtocol : tcp
FromPort : 8080
ToPort : 8080
CidrIp : 10.49.63.0/24
- IpProtocol : tcp
FromPort : 8080
ToPort : 8080
CidrIp : 10.93.0.0/16
- IpProtocol : tcp
FromPort : 8080
ToPort : 8080
CidrIp : 10.97.0.0/16
- IpProtocol : tcp
FromPort : 8080
ToPort : 8080
CidrIp : 10.50.128.0/21
- IpProtocol : tcp
FromPort : 8080
ToPort : 8080
CidrIp : 10.50.144.0/24
- IpProtocol : tcp
FromPort : 8080
ToPort : 8080
CidrIp : 172.25.0.0/16
最重要的问题是,我如何将值归因于与 CloudFormation 模板中的堆栈一起创建的参数?
非常感谢有人对此提供帮助。谢谢。
编辑:这是完整的 cloudformation 文件,一些参数(内存、版本号等)在管道中指定,因此它们不需要在模板中赋予它们任何值:
Description: "Generic Research Template for Application ECS Cluster with an ECS Service"
Parameters:
Env:
Description: the runtime environment
Type: String
AllowedValues:
- dev
- uat
- prod
ServiceName:
Description: The service name
Type: String
BuildNumber:
Description: The bitbucket build number
Type: String
AppCode:
Description: The application's app code
Type: String
Subnets:
Description: Choose which db subnets for the instance
Type: List<AWS::EC2::Subnet::Id>
ContainerPort:
Description: The container port
Type: String
Default: 8080
DesiredCount:
Description: The number of desired tasks for this service
Type: Number
Default: 1
ClusterLogGroup:
Description: The cluster log group
Type: String
Cpu:
Description: allocated cpu credits
Type: Number
Default: 1024
Memory:
Description: hard cap for memory
Type: String
Default: 2048
ClusterArn:
Description: The ECS Cluster ARN
Type: String
ExecRoleArn:
Description: The ARN of the cluster execution role
Type: String
TaskRoleArn:
Description: The ARN of the cluster task role
Type: String
ContainerSG:
Description: The container security group
Type: String
ExcludeTaskDef:
Description: Flag indiciating that the task definition resource should not be created as part of this stack
Type: Number
AllowedValues:
- 0
- 1
Default: 0
Conditions:
IncludeTaskDef: !Equals [!Ref ExcludeTaskDef, 0]
Resources:
ECSService:
Type: AWS::ECS::Service
Properties:
ServiceName: !Sub ${Env}-${AppCode}-${ServiceName}-service
Cluster: !Ref ClusterArn
TaskDefinition: !Ref TaskDefinition
DeploymentConfiguration:
MinimumHealthyPercent: 0
MaximumPercent: 100
DesiredCount: !Ref DesiredCount
LaunchType: FARGATE
NetworkConfiguration:
AwsvpcConfiguration:
AssignPublicIp: DISABLED
Subnets:
- !Select [0, !Ref Subnets ]
- !Select [1, !Ref Subnets ]
SecurityGroups:
- !Ref ContainerSG
TaskDefinition:
Type: AWS::ECS::TaskDefinition
Condition: IncludeTaskDef
Properties:
Family: !Sub ${Env}-${AppCode}-${ServiceName}
NetworkMode: awsvpc
RequiresCompatibilities:
- FARGATE
Cpu: !Ref Cpu
Memory: !Ref Memory
ExecutionRoleArn: !Ref ExecRoleArn
TaskRoleArn: !Ref TaskRoleArn
ContainerDefinitions:
- Name: !Sub ${Env}-${AppCode}-${ServiceName}
Image: !Sub 558043318296.dkr.ecr.us-east-1.amazonaws.com/com.cambridge.gir/${AppCode}-${ServiceName}:${BuildNumber}
Essential: True
PortMappings:
- ContainerPort: !Ref ContainerPort
LogConfiguration:
LogDriver: awslogs
Options:
awslogs-group: !Ref ClusterLogGroup
awslogs-region: us-east-1
awslogs-stream-prefix: !Ref ServiceName
Environment:
- Name: Environment
Value: !Ref Env
- Name: Timezone
Value: "-Duser.timezone=America/New_York"
ClusterKmsKey:
Type: AWS::KMS::Key
Properties:
Description: "Encrypts secrets for apps in the cluster"
KeyPolicy:
Version: '2012-10-17'
Id: !Sub ${Env}-${AppCode}-kms-key
Statement:
- Sid: 'Enable IAM User Permission'
Effect: 'Allow'
Principal:
AWS: !Sub 'arn:aws:iam::${AWS::AccountId}:root'
Action:
- kms:*
Resource: '*'
- Sid: 'Allow ECS Tasks to use the key'
Effect: 'Allow'
Principal:
Service: 'ecs-tasks.amazonaws.com'
Action:
- 'kms:GenerateDataKey'
- 'kms:Encrypt'
- 'kms:Decrypt'
Resource: '*'
- Sid: 'Allow SNS to use the key'
Effect: 'Allow'
Principal:
Service: 'sns.amazonaws.com'
Action:
- 'kms:GenerateDataKey'
- 'kms:Encrypt'
- 'kms:Decrypt'
Resource: '*'
- Sid: 'Allow SQS to use the key'
Effect: 'Allow'
Principal:
Service: 'sqs.amazonaws.com'
Action:
- 'kms:GenerateDataKey'
- 'kms:Encrypt'
- 'kms:Decrypt'
Resource: '*'
- Sid: 'Allow ES to use the key'
Effect: 'Allow'
Principal:
Service: 'es.amazonaws.com'
Action:
- 'kms:GenerateDataKey'
- 'kms:Encrypt'
- 'kms:Decrypt'
Resource: '*'
EcsCluster:
Type: AWS::ECS::Cluster
Properties:
ClusterName: !Sub ${Env}-${AppCode}-ecs-cluster
LogGroup:
Type: AWS::Logs::LogGroup
Properties:
LogGroupName: !Join [ '/', ['/aws', 'ecs', !Ref Env, !Ref AppCode]]
ContainerSecurityGroup:
Type : AWS::EC2::SecurityGroup
Properties :
GroupDescription : "ECS Containers Security Group"
VpcId : '{{resolve:ssm:/ca/config/network/vpc_id:1}}'
GroupName : !Sub ${Env}-${ServiceName}-sg
SecurityGroupIngress :
- IpProtocol : tcp
FromPort : 8080
ToPort : 8080
CidrIp : 10.49.63.0/24
- IpProtocol : tcp
FromPort : 8080
ToPort : 8080
CidrIp : 10.93.0.0/16
- IpProtocol : tcp
FromPort : 8080
ToPort : 8080
CidrIp : 10.97.0.0/16
- IpProtocol : tcp
FromPort : 8080
ToPort : 8080
CidrIp : 10.50.128.0/21
- IpProtocol : tcp
FromPort : 8080
ToPort : 8080
CidrIp : 10.50.144.0/24
- IpProtocol : tcp
FromPort : 8080
ToPort : 8080
CidrIp : 172.25.0.0/16
ClusterExecutionRole:
Type: AWS::IAM::Role
Properties:
RoleName: !Sub ${Env}-${AppCode}-execution-role
AssumeRolePolicyDocument:
Statement:
- Effect: Allow
Principal:
Service: ecs-tasks.amazonaws.com
Action: 'sts:AssumeRole'
ManagedPolicyArns:
- 'arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy'
- 'arn:aws:iam::aws:policy/AmazonSSMFullAccess'
- 'arn:aws:iam::aws:policy/SecretsManagerReadWrite'
Policies:
- PolicyName: !Sub ${Env}-${AppCode}-execution-role-policy
PolicyDocument:
Version: "2012-10-17"
Statement:
- Sid: AllowSecretsAccessForContainers
Effect: Allow
Action:
- 'kms:Decrypt'
- 'ssm:GetParameters'
Resource:
- !Sub "arn:aws:ssm:*:*:parameter/${Env}/${AppCode}/*"
- !GetAtt ClusterKmsKey.Arn
- Sid: AllowECRPull
Effect: Allow
Action:
- "ecr:GetAuthorizationToken"
- "ecr:BatchCheckLayerAvailability"
- "ecr:GetDownloadUrlForLayer"
- "ecr:BatchGetImage"
Resource:
- "*"
FargateTaskRole:
Type: AWS::IAM::Role
Properties:
RoleName: !Sub ${Env}-${AppCode}-fargate-task-role
AssumeRolePolicyDocument:
Statement:
- Effect: Allow
Principal:
Service: ecs-tasks.amazonaws.com
Action: 'sts:AssumeRole'
如果全部在一个文件中,则不需要任何参数。
您始终可以转到 CloudFormation 文档中所有资源的 return 部分。在这种情况下,我们可以看到一个 LogGroup returns it's name when you use the Ref function. Sometimes you can use the Ref function, sometimes you need to use the Fn:GetAtt 函数,如果你想获得一些更奇特的资源属性。
这个 cheat sheet 也非常有助于了解何时使用 Ref 或何时使用 GetAtt。
在您的情况下,您可以使用 !Ref LogGroup
获取日志组的名称或使用 !Ref ContainerSecurityGroup
获取安全组的名称。
部署 CloudFormation 模板时出现以下错误。
✖ Failed to create the stack.
An error occurred (ValidationError) when calling the CreateStack operation: Parameters: [ClusterArn, TaskRoleArn, Env, Subnets, ExecRoleArn, ClusterLogGroup, ContainerSG] must have values
我不知道如何将值归因于指定的参数,因为它们是在堆栈中创建的。例如 ContainerSG 和 LogGroup :
Parameters:
ContainerSG:
Description: The container security group
Type: String
ClusterLogGroup:
Description: The cluster log group
Type: String
Resources
LogGroup:
Type: AWS::Logs::LogGroup
Properties:
LogGroupName: !Join [ '/', ['/aws', 'ecs', !Ref Env]]
ContainerSecurityGroup:
Type : AWS::EC2::SecurityGroup
Properties :
GroupDescription : "ECS Containers Security Group"
VpcId : '{{resolve:ssm:/ca/config/network/vpc_id:1}}'
GroupName: security-group-cmr
SecurityGroupIngress :
- IpProtocol : tcp
FromPort : 8080
ToPort : 8080
CidrIp : 10.49.63.0/24
- IpProtocol : tcp
FromPort : 8080
ToPort : 8080
CidrIp : 10.93.0.0/16
- IpProtocol : tcp
FromPort : 8080
ToPort : 8080
CidrIp : 10.97.0.0/16
- IpProtocol : tcp
FromPort : 8080
ToPort : 8080
CidrIp : 10.50.128.0/21
- IpProtocol : tcp
FromPort : 8080
ToPort : 8080
CidrIp : 10.50.144.0/24
- IpProtocol : tcp
FromPort : 8080
ToPort : 8080
CidrIp : 172.25.0.0/16
最重要的问题是,我如何将值归因于与 CloudFormation 模板中的堆栈一起创建的参数?
非常感谢有人对此提供帮助。谢谢。
编辑:这是完整的 cloudformation 文件,一些参数(内存、版本号等)在管道中指定,因此它们不需要在模板中赋予它们任何值:
Description: "Generic Research Template for Application ECS Cluster with an ECS Service"
Parameters:
Env:
Description: the runtime environment
Type: String
AllowedValues:
- dev
- uat
- prod
ServiceName:
Description: The service name
Type: String
BuildNumber:
Description: The bitbucket build number
Type: String
AppCode:
Description: The application's app code
Type: String
Subnets:
Description: Choose which db subnets for the instance
Type: List<AWS::EC2::Subnet::Id>
ContainerPort:
Description: The container port
Type: String
Default: 8080
DesiredCount:
Description: The number of desired tasks for this service
Type: Number
Default: 1
ClusterLogGroup:
Description: The cluster log group
Type: String
Cpu:
Description: allocated cpu credits
Type: Number
Default: 1024
Memory:
Description: hard cap for memory
Type: String
Default: 2048
ClusterArn:
Description: The ECS Cluster ARN
Type: String
ExecRoleArn:
Description: The ARN of the cluster execution role
Type: String
TaskRoleArn:
Description: The ARN of the cluster task role
Type: String
ContainerSG:
Description: The container security group
Type: String
ExcludeTaskDef:
Description: Flag indiciating that the task definition resource should not be created as part of this stack
Type: Number
AllowedValues:
- 0
- 1
Default: 0
Conditions:
IncludeTaskDef: !Equals [!Ref ExcludeTaskDef, 0]
Resources:
ECSService:
Type: AWS::ECS::Service
Properties:
ServiceName: !Sub ${Env}-${AppCode}-${ServiceName}-service
Cluster: !Ref ClusterArn
TaskDefinition: !Ref TaskDefinition
DeploymentConfiguration:
MinimumHealthyPercent: 0
MaximumPercent: 100
DesiredCount: !Ref DesiredCount
LaunchType: FARGATE
NetworkConfiguration:
AwsvpcConfiguration:
AssignPublicIp: DISABLED
Subnets:
- !Select [0, !Ref Subnets ]
- !Select [1, !Ref Subnets ]
SecurityGroups:
- !Ref ContainerSG
TaskDefinition:
Type: AWS::ECS::TaskDefinition
Condition: IncludeTaskDef
Properties:
Family: !Sub ${Env}-${AppCode}-${ServiceName}
NetworkMode: awsvpc
RequiresCompatibilities:
- FARGATE
Cpu: !Ref Cpu
Memory: !Ref Memory
ExecutionRoleArn: !Ref ExecRoleArn
TaskRoleArn: !Ref TaskRoleArn
ContainerDefinitions:
- Name: !Sub ${Env}-${AppCode}-${ServiceName}
Image: !Sub 558043318296.dkr.ecr.us-east-1.amazonaws.com/com.cambridge.gir/${AppCode}-${ServiceName}:${BuildNumber}
Essential: True
PortMappings:
- ContainerPort: !Ref ContainerPort
LogConfiguration:
LogDriver: awslogs
Options:
awslogs-group: !Ref ClusterLogGroup
awslogs-region: us-east-1
awslogs-stream-prefix: !Ref ServiceName
Environment:
- Name: Environment
Value: !Ref Env
- Name: Timezone
Value: "-Duser.timezone=America/New_York"
ClusterKmsKey:
Type: AWS::KMS::Key
Properties:
Description: "Encrypts secrets for apps in the cluster"
KeyPolicy:
Version: '2012-10-17'
Id: !Sub ${Env}-${AppCode}-kms-key
Statement:
- Sid: 'Enable IAM User Permission'
Effect: 'Allow'
Principal:
AWS: !Sub 'arn:aws:iam::${AWS::AccountId}:root'
Action:
- kms:*
Resource: '*'
- Sid: 'Allow ECS Tasks to use the key'
Effect: 'Allow'
Principal:
Service: 'ecs-tasks.amazonaws.com'
Action:
- 'kms:GenerateDataKey'
- 'kms:Encrypt'
- 'kms:Decrypt'
Resource: '*'
- Sid: 'Allow SNS to use the key'
Effect: 'Allow'
Principal:
Service: 'sns.amazonaws.com'
Action:
- 'kms:GenerateDataKey'
- 'kms:Encrypt'
- 'kms:Decrypt'
Resource: '*'
- Sid: 'Allow SQS to use the key'
Effect: 'Allow'
Principal:
Service: 'sqs.amazonaws.com'
Action:
- 'kms:GenerateDataKey'
- 'kms:Encrypt'
- 'kms:Decrypt'
Resource: '*'
- Sid: 'Allow ES to use the key'
Effect: 'Allow'
Principal:
Service: 'es.amazonaws.com'
Action:
- 'kms:GenerateDataKey'
- 'kms:Encrypt'
- 'kms:Decrypt'
Resource: '*'
EcsCluster:
Type: AWS::ECS::Cluster
Properties:
ClusterName: !Sub ${Env}-${AppCode}-ecs-cluster
LogGroup:
Type: AWS::Logs::LogGroup
Properties:
LogGroupName: !Join [ '/', ['/aws', 'ecs', !Ref Env, !Ref AppCode]]
ContainerSecurityGroup:
Type : AWS::EC2::SecurityGroup
Properties :
GroupDescription : "ECS Containers Security Group"
VpcId : '{{resolve:ssm:/ca/config/network/vpc_id:1}}'
GroupName : !Sub ${Env}-${ServiceName}-sg
SecurityGroupIngress :
- IpProtocol : tcp
FromPort : 8080
ToPort : 8080
CidrIp : 10.49.63.0/24
- IpProtocol : tcp
FromPort : 8080
ToPort : 8080
CidrIp : 10.93.0.0/16
- IpProtocol : tcp
FromPort : 8080
ToPort : 8080
CidrIp : 10.97.0.0/16
- IpProtocol : tcp
FromPort : 8080
ToPort : 8080
CidrIp : 10.50.128.0/21
- IpProtocol : tcp
FromPort : 8080
ToPort : 8080
CidrIp : 10.50.144.0/24
- IpProtocol : tcp
FromPort : 8080
ToPort : 8080
CidrIp : 172.25.0.0/16
ClusterExecutionRole:
Type: AWS::IAM::Role
Properties:
RoleName: !Sub ${Env}-${AppCode}-execution-role
AssumeRolePolicyDocument:
Statement:
- Effect: Allow
Principal:
Service: ecs-tasks.amazonaws.com
Action: 'sts:AssumeRole'
ManagedPolicyArns:
- 'arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy'
- 'arn:aws:iam::aws:policy/AmazonSSMFullAccess'
- 'arn:aws:iam::aws:policy/SecretsManagerReadWrite'
Policies:
- PolicyName: !Sub ${Env}-${AppCode}-execution-role-policy
PolicyDocument:
Version: "2012-10-17"
Statement:
- Sid: AllowSecretsAccessForContainers
Effect: Allow
Action:
- 'kms:Decrypt'
- 'ssm:GetParameters'
Resource:
- !Sub "arn:aws:ssm:*:*:parameter/${Env}/${AppCode}/*"
- !GetAtt ClusterKmsKey.Arn
- Sid: AllowECRPull
Effect: Allow
Action:
- "ecr:GetAuthorizationToken"
- "ecr:BatchCheckLayerAvailability"
- "ecr:GetDownloadUrlForLayer"
- "ecr:BatchGetImage"
Resource:
- "*"
FargateTaskRole:
Type: AWS::IAM::Role
Properties:
RoleName: !Sub ${Env}-${AppCode}-fargate-task-role
AssumeRolePolicyDocument:
Statement:
- Effect: Allow
Principal:
Service: ecs-tasks.amazonaws.com
Action: 'sts:AssumeRole'
如果全部在一个文件中,则不需要任何参数。
您始终可以转到 CloudFormation 文档中所有资源的 return 部分。在这种情况下,我们可以看到一个 LogGroup returns it's name when you use the Ref function. Sometimes you can use the Ref function, sometimes you need to use the Fn:GetAtt 函数,如果你想获得一些更奇特的资源属性。
这个 cheat sheet 也非常有助于了解何时使用 Ref 或何时使用 GetAtt。
在您的情况下,您可以使用 !Ref LogGroup
获取日志组的名称或使用 !Ref ContainerSecurityGroup
获取安全组的名称。