我的用例是我们已经有一个由 AWS Cloudformation 创建的堆栈。
现在我想更新该堆栈,我的要求是我想删除已创建的资源并添加新的修改资源,但我想确保删除发生在创建部分之前。
我探索了dependsOn,但这有助于我设置资源创建的顺序。它无助于确保删除和创建顺序(或者至少我找不到任何东西)
在进行 cloudform 更新时,如何确保资源删除发生在资源创建之前
我的情况是这样的:
我正在尝试通过 AWS Cognito 使用类似 UNIX 的主目录来控制对 S3 存储桶的访问。这些主目录应该可由用户组而不是每个单独的用户访问。IE:
s3-bucket/home/group1
s3-bucket/home/group2
s3-bucket/home/group3
Run Code Online (Sandbox Code Playgroud)
当使用组信息(当前用作通配符的目录名称的一部分)单独创建角色时,类似于此链接,它可以工作。但是,我不想为每个组创建单独的 IAM 角色。
在使用增强流程之前,我可以通过 STS 调用使用进一步的策略来限制角色assumeRoleWithWebIdentity。然而,当仅使用 cognito 时,它期望只应用一个角色。
我不想直接将策略应用于 ID 令牌的主题(例如${cognito-identity.amazonaws.com:sub}),而是希望它使用组(例如 from ${cognito-identity.amazonaws.com:cognito:groups}),这样我就不必为每个新组创建角色,并且变量其本身将有助于定义资源范围。
有人对此很幸运吗?或者通常在 IAM 资源定义中使用字符串数组/集?我试图做类似的事情
{"Fn::Select": [0, "${cognito-identity.amazonaws.com:cognito:groups}"]}
但cloudformation抱怨
Template error: Fn::Select requires a list argument with two elements: an integer index and a list。
谢谢!
PS我看到这个页面,其中指出没有特定于服务的密钥用于策略中的认知,但这似乎并不正确,因为我看到人们sub aud amr在网络上其他示例的策略中使用等,尽管这是一个明确的指南似乎没有很好的记录。
我有一个 lambda,它有一个日志组,例如 LG-1,其保留设置为永不过期(默认)。我需要将永不过期更改为 1 个月。我正在使用 CloudFormation 执行此操作。由于日志组已经存在,当我尝试使用模板中的更改再次部署 lambda 时:
LambdaFunctionLogGroup:
Type: 'AWS::Logs::LogGroup'
DependsOn: MyLambda
Properties:
RetentionInDays: 30
LogGroupName: !Join
- ''
- - /aws/lambda/
- !Ref MyLambda
Run Code Online (Sandbox Code Playgroud)
更新失败并出现错误:
[日志组名称] 已存在。
一种可能的解决方案是删除日志组,然后使用新的更改再次创建它,如上所示,效果非常好。
但我需要在不删除日志组的情况下执行此操作,因为这将导致删除我以前拥有的所有日志。
有没有可能的解决方法?
当您在同一区域内运行多个 CloudFormation 堆栈时,您可以使用CloudFormation 输出跨堆栈共享引用
但是,正如该文档所强调的那样,输出不能用于跨区域引用。
您不能跨区域创建跨堆栈引用。您可以使用内部函数 Fn::ImportValue 仅导入已在同一区域内导出的值。
您如何在 CloudFormation 中跨区域引用值?
作为要遵循的示例,我有一个Route 53 托管区域部署在us-east-1. 但是,我有一个后端,us-west-2因为我想创建一个经过DNS 验证的 ACM 证书,该证书需要对托管区域的引用,以便能够创建适当的 CNAME 来证明所有权。
我将如何引用us-east-1从内部创建的托管区域 ID us-west-2?
amazon-web-services aws-cloudformation aws-cloudformation-custom-resource
我们正在调整我们的应用程序CloudFormation模板以使用VPC.在此模板中,我们需要以编程方式生成用于VPC子网的CIDR块,以确保它们不会在CloudFormation堆栈之间发生冲突.
我最初的计划是通过将字符串连接在一起来生成CIDR,例如:
"ProxyLoadBalancerSubnetA" : {
"Type" : "AWS::EC2::Subnet",
"Properties" : {
"VpcId" : { "Ref" : "Vpc" },
"AvailabilityZone" : "eu-west-1a",
"CidrBlock" : { "Fn::Join" : [ ".", [ { "Ref" : "VpcCidrPrefix" }, "0.0/24" ] ] }
}
},
Run Code Online (Sandbox Code Playgroud)
然而,在进一步考虑之后,我们需要使用单个VPC,而不是为每个堆栈使用VPC.
AWS限制VPC使用最大的/16CIDR块(我们已经要求提高此限制,但显然不可能).这意味着我们不再可能使用此连接方法,因为我们的每个堆栈都需要总共超过255个地址的子网.
我想在运行中生成CIDR块,而不必将它们定义为CloudFormation模板的参数,
我有一个想法是每个堆栈都有一个"基本整数",并为每个子网的CIDR块添加.
例如:
"CidrBlock" : { "Fn::Join" : [ ".", [ { "Ref" : "VpcCidrPrefix" }, { "Fn::Sum", [ { "Ref" : "VpcCidrStart" }, 3 ] }, "0/24 ] ] }
Run Code Online (Sandbox Code Playgroud)
其中VpcCidrStart是一个整数,用于设置第三个CIDR八位字节应在脚本中开始的值,并且3是子网号. …
我正在尝试设置一个云形式模板,该模板将启动一个干净的实例或一个来自快照的实例.我希望能够使用if/else类型语句,以便看起来像
pseudo code:
if InputSnapshotId:
"SnapshotId" : {"Ref" : "InputSnapshotId"},
else:
"Size" : 20,
Run Code Online (Sandbox Code Playgroud)
在cloudformation中,我尝试了很多类似的东西:
"WebserverInstanceDataVolume" : {
"Type" : "AWS::EC2::Volume",
"Properties" : {
"Fn::If" : [
{"Ref" : "FromSnapshot"},
{"SnapshotId" : { "Ref" : "InputSnapshotId" }},
{"Size" : "20"}
],
"VolumeType" : "standard",
"AvailabilityZone" : { "Fn::GetAtt" : [ "WebserverInstance", "AvailabilityZone" ]},
"Tags" : [
{"Key" : "Role", "Value": "data" },
]
},
"DeletionPolicy" : "Delete"
},
Run Code Online (Sandbox Code Playgroud)
或者在{}中包装Fn :: If:
{"Fn::If" : [
{"Ref" : "FromSnapshot"},
{"SnapshotId" : { …Run Code Online (Sandbox Code Playgroud) 我需要在AWS自动扩展组中的所有实例配置(已知)静态IP.我将在稍后的邮件服务器中将所有这些IP列入白名单(这就是为什么需要所有这些IP都是静态的).是否可以使用常规的云形式方法?可能是分配第二个NIC并从静态IP范围为其分配IP?有任何想法吗?
是否有可能在Cloudformation json模板中执行某种数学运算?
我遇到了两个有用的区域:1.设置IOPS,它需要是磁盘大小的比率.2.为RDS免费存储空间设置Cloud Watch警报.将其设置为磁盘大小的百分比将是有用的.
我正在使用平台条件来控制在AWS上运行的环境类型.有很多共享资源,但我需要某些EC2实例与预先制作的AMI,具体取决于数量条件.
"Parameters": {
"Platform": {
"Description": "Select platform type - linux or windows",
"Default": "linux",
"Type": "String",
"AllowedValues": [ "linux", "windows", "both" ],
"ConstraintDescription": "Must enter either linux, windows, or both"
},
Run Code Online (Sandbox Code Playgroud)
然后我设置了conditions.
"Conditions" : {
"LinuxPlatform" : {"Fn::Equals" : [{"Ref" : "Platform"}, "linux"]},
"WindowsPlatform" : {"Fn::Equals" : [{"Ref" : "Platform"}, "windows"]},
"BothPlatform" : {"Fn::Equals" : [{"Ref" : "Platform"}, "both"]}
},
Run Code Online (Sandbox Code Playgroud)
在资源中,我想使用linux或windows来触发Windows或Linux Ec2创建,或者使用它们来部署所声明的每个ec2资源.
我fn:or在几个方面尝试了以下使用方法.
"Fn::Or": [{"Condition": "LinuxPlatform"}, {"Condition": "BothPlatform" }],
和...
"Condition" : {
"Fn::Or" : …Run Code Online (Sandbox Code Playgroud) 我正在尝试在特定区域(us-west-2)创建一个s3存储桶.使用Cloudformation模板似乎无法做到这一点.有任何想法吗?我没有运气使用我读到的service-region-hash约定明确地命名它.
Template:
{
"AWSTemplateFormatVersion": "2010-09-09",
"Resources": {
"S3Bucket": {
"Type": "AWS::S3::Bucket",
"Properties": {
"AccessControl": "PublicReadWrite",
}
}
},
"Outputs": {
"BucketName": {
"Value": {
"Ref": "S3Bucket"
},
"Description": "Name of the sample Amazon S3 bucket with a lifecycle configuration."
}
}
}
Run Code Online (Sandbox Code Playgroud) amazon-ec2 ×1
amazon-s3 ×1
amazon-vpc ×1
aws-cloudformation-custom-resource ×1
chef-infra ×1
cidr ×1
math ×1