只能使用 Boto3 将 CloudFormation 模板部署到 us-east-1
Only able to deploy CloudFormation template to us-east-1 using Boto3
我正在尝试将我的 CloudFormation 模板部署到其他区域进行测试。我的模板通过 Boto3 在 us-east-1 上运行良好,但如果它尝试另一个区域,我不会得到任何错误输出。
在尝试不同地区时,我意外地收到一封电子邮件,说加拿大地区已通过验证,但自从通过 Boto3 尝试以来,一直没有成功。 (计费控制台显示所有区域现已激活)
我是来自 Lambda(无 VPC)的 运行 Boto3,已使用 Zappa 部署到 us-east-1。它具有未指定特定区域的 IAM 策略。
Python:
cf_client = boto3.client(
'cloudformation', region_name=request.POST['region'])
cf_client.create_stack(
StackName=stack_name,
TemplateURL='https://s3.amazonaws.com/#######/build_instance.yaml',
Parameters=[
{"ParameterKey": "FQDN",
"ParameterValue": instance_domain},
{"ParameterKey": "BucketName",
"ParameterValue": bucket_name},
{"ParameterKey": "CreateSubdomain",
"ParameterValue": create_subdomain},
{"ParameterKey": "CustomerEmail",
"ParameterValue": request.user.email},
{"ParameterKey": "Region",
"ParameterValue": request.POST['region']},
],
Capabilities=['CAPABILITY_NAMED_IAM'],
Tags=[
{
'Key': 'Name',
'Value': instance_domain
},
{
'Key': 'env',
'Value': "prod"
}, ],
EnableTerminationProtection=True
)
CF:
---
AWSTemplateFormatVersion: "2010-09-09"
Description: ""
Parameters:
FQDN:
Type: String
Description: Instance FQDN
BucketName:
Type: String
Description: Name of S3 bucket
CreateSubdomain:
Type: String
Default: false
AllowedValues: [true, false]
Description: Does the customer want to use our sub-domain?
CustomerEmail:
Type: String
Description: Customer email to deliver credentials
Region:
Type: String
Description: Customer region
Mappings:
RegionMap:
us-east-1:
AMI: "ami-0affd4508a5d2481b"
us-west-1:
AMI: "ami-03ba3948f6c37a4b0"
ca-central-1:
AMI: "ami-0d0eaed20348a3389"
eu-west-2:
AMI: " ami-006a0174c6c25ac06"
Conditions:
ShouldCreateSubDomain: !Equals [true, !Ref CreateSubdomain]
Resources:
Bucket:
Type: AWS::S3::Bucket
Properties:
BucketName: !Ref BucketName
BucketEncryption:
ServerSideEncryptionConfiguration:
- ServerSideEncryptionByDefault:
SSEAlgorithm: AES256
MetricsConfigurations:
- Id: EntireBucket
LifecycleConfiguration:
Rules:
- Id: IntelligentTieringTransition
Status: Enabled
Transitions:
- TransitionInDays: 30
StorageClass: INTELLIGENT_TIERING
PublicAccessBlockConfiguration:
BlockPublicAcls: true
IgnorePublicAcls: false
BlockPublicPolicy: true
RestrictPublicBuckets: true
User:
Type: AWS::IAM::User
Properties:
UserName:
Ref: FQDN
Groups: ["Customers"]
DependsOn: Bucket
Key:
Type: AWS::IAM::AccessKey
Properties:
UserName:
Ref: User
DependsOn: User
BucketPolicy:
Type: "AWS::S3::BucketPolicy"
Properties:
Bucket: !Ref BucketName
PolicyDocument:
Version: "2012-10-17"
Statement:
- Principal:
AWS: !GetAtt User.Arn
Action: "s3:*"
Effect: Allow
Resource:
- !GetAtt Bucket.Arn
- !Sub "${Bucket.Arn}/*"
DependsOn: Key
EC2Instance:
Type: AWS::EC2::Instance
Properties:
ImageId: !FindInMap [RegionMap, !Ref "AWS::Region", AMI]
KeyName: aws-master
InstanceType: t3.micro
DisableApiTermination: true
SecurityGroups: ["nextcloud-security"]
BlockDeviceMappings:
- DeviceName: /dev/sda1
Ebs:
VolumeSize: 10
DeleteOnTermination: false
Tags:
- Key: "Name"
Value: !Ref FQDN
- Key: "env"
Value: "prod"
UserData:
Fn::Base64: !Sub |
#!/bin/bash -xe
exec > >(tee /var/log/user-data.log|logger -t user-data -s 2>/dev/console) 2>&1
curl -s ####### | /bin/bash
git clone #######
cd nextcloud
sed -i 's/# fqdn = nc.example.org/fqdn = ${FQDN}/g' inventory
sed -i "s/ssl_certificate_type = 'selfsigned'/#ssl_certificate_type = 'selfsigned'/g" inventory
sed -i "s/# ssl_certificate_type = 'letsencrypt'/ssl_certificate_type = 'letsencrypt'/g" inventory
sed -i 's/# cert_email = nc@example.org/cert_email = ####/g' inventory
sed -i "s/# nc_db_type = 'mysql'/nc_db_type = 'mysql'/g" inventory
sed -i "s/nc_db_type = 'pgsql'/#nc_db_type = 'pgsql'/g" inventory
sed -i 's/nc_configure_mail = false/nc_configure_mail = true/g' inventory
sed -i 's/nc_mail_from =/nc_mail_from = contact/g' inventory
sed -i 's/nc_mail_domain =/nc_mail_domain = ######/g' inventory
sed -i 's/nc_mail_smtpname =/nc_mail_smtpname = #######/g' inventory
sed -i 's/nc_mail_smtphost =/nc_mail_smtphost = smtp.gmail.com/g' inventory
sed -i 's/nc_mail_smtppwd =/nc_mail_smtppwd = #####/g' inventory
sed -i 's/s3_key =/s3_key = ${Key}/g' inventory
sed -i 's|s3_secret =|s3_secret = ${Key.SecretAccessKey}|g' inventory
sed -i 's/s3_bucket =/s3_bucket = ${BucketName}/g' inventory
sed -i 's/s3_region =/s3_region = ${Region}/g' inventory
sed -i 's/talk_install = false/talk_install = true/g' inventory
./nextcloud.yml
IPAddress:
Type: AWS::EC2::EIP
Properties:
Tags:
- Key: "Name"
Value: !Ref FQDN
- Key: "env"
Value: "prod"
IPAssoc:
Type: AWS::EC2::EIPAssociation
Properties:
InstanceId: !Ref "EC2Instance"
EIP: !Ref "IPAddress"
Route53Record:
Type: AWS::Route53::RecordSet
Properties:
HostedZoneName: "########"
Name: !Join ["", [!Ref FQDN, "."]]
Type: A
TTL: "300"
ResourceRecords:
- !Ref "IPAddress"
Condition: ShouldCreateSubDomain
Outputs:
InstanceId:
Description: InstanceId of the newly created EC2 instance
Value: !Ref "EC2Instance"
InstanceIPAddress:
Description: IP address of the newly created EC2 instance
Value: !Ref "IPAddress"
IAM:
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": [
"ec2:DescribeImages",
"ec2:DescribeInstances",
"ec2:DescribeAddresses",
"ec2:DescribeTags",
"ec2:CreateTags",
"ec2:RunInstances",
"ec2:DescribeKeyPairs",
"ec2:AssociateAddress",
"ec2:AllocateAddress"
],
"Resource": "*"
},
{
"Sid": "VisualEditor1",
"Effect": "Allow",
"Action": [
"iam:AddUserToGroup",
"cloudformation:CreateStack",
"route53:ChangeResourceRecordSets",
"iam:GetUser",
"iam:CreateUser",
"iam:CreateAccessKey"
],
"Resource": [
"arn:aws:iam::*:user/*",
"arn:aws:iam::#######:group/Customers",
"arn:aws:cloudformation:*:*:stack/*/*",
"arn:aws:route53:::hostedzone/#####"
]
}
]
}
来自Selecting a Stack Template - AWS CloudFormation:
Amazon S3 URL: The URL must point to a template with a maximum size of 460,800 bytes that is stored in an S3 bucket that you have read permissions to and that is located in the same region as the stack.
我怀疑您的堆栈出现故障,因为模板位于 Amazon S3 存储桶中,而该存储桶与启动堆栈的区域不同。您需要将模板复制到同一区域的存储桶中,然后在 create_stack()
命令中提供它。
您可以使用 AWS 控制台启动模板来对此进行测试,而不必通过 boto3。
我正在尝试将我的 CloudFormation 模板部署到其他区域进行测试。我的模板通过 Boto3 在 us-east-1 上运行良好,但如果它尝试另一个区域,我不会得到任何错误输出。
在尝试不同地区时,我意外地收到一封电子邮件,说加拿大地区已通过验证,但自从通过 Boto3 尝试以来,一直没有成功。 (计费控制台显示所有区域现已激活)
我是来自 Lambda(无 VPC)的 运行 Boto3,已使用 Zappa 部署到 us-east-1。它具有未指定特定区域的 IAM 策略。
Python:
cf_client = boto3.client(
'cloudformation', region_name=request.POST['region'])
cf_client.create_stack(
StackName=stack_name,
TemplateURL='https://s3.amazonaws.com/#######/build_instance.yaml',
Parameters=[
{"ParameterKey": "FQDN",
"ParameterValue": instance_domain},
{"ParameterKey": "BucketName",
"ParameterValue": bucket_name},
{"ParameterKey": "CreateSubdomain",
"ParameterValue": create_subdomain},
{"ParameterKey": "CustomerEmail",
"ParameterValue": request.user.email},
{"ParameterKey": "Region",
"ParameterValue": request.POST['region']},
],
Capabilities=['CAPABILITY_NAMED_IAM'],
Tags=[
{
'Key': 'Name',
'Value': instance_domain
},
{
'Key': 'env',
'Value': "prod"
}, ],
EnableTerminationProtection=True
)
CF:
---
AWSTemplateFormatVersion: "2010-09-09"
Description: ""
Parameters:
FQDN:
Type: String
Description: Instance FQDN
BucketName:
Type: String
Description: Name of S3 bucket
CreateSubdomain:
Type: String
Default: false
AllowedValues: [true, false]
Description: Does the customer want to use our sub-domain?
CustomerEmail:
Type: String
Description: Customer email to deliver credentials
Region:
Type: String
Description: Customer region
Mappings:
RegionMap:
us-east-1:
AMI: "ami-0affd4508a5d2481b"
us-west-1:
AMI: "ami-03ba3948f6c37a4b0"
ca-central-1:
AMI: "ami-0d0eaed20348a3389"
eu-west-2:
AMI: " ami-006a0174c6c25ac06"
Conditions:
ShouldCreateSubDomain: !Equals [true, !Ref CreateSubdomain]
Resources:
Bucket:
Type: AWS::S3::Bucket
Properties:
BucketName: !Ref BucketName
BucketEncryption:
ServerSideEncryptionConfiguration:
- ServerSideEncryptionByDefault:
SSEAlgorithm: AES256
MetricsConfigurations:
- Id: EntireBucket
LifecycleConfiguration:
Rules:
- Id: IntelligentTieringTransition
Status: Enabled
Transitions:
- TransitionInDays: 30
StorageClass: INTELLIGENT_TIERING
PublicAccessBlockConfiguration:
BlockPublicAcls: true
IgnorePublicAcls: false
BlockPublicPolicy: true
RestrictPublicBuckets: true
User:
Type: AWS::IAM::User
Properties:
UserName:
Ref: FQDN
Groups: ["Customers"]
DependsOn: Bucket
Key:
Type: AWS::IAM::AccessKey
Properties:
UserName:
Ref: User
DependsOn: User
BucketPolicy:
Type: "AWS::S3::BucketPolicy"
Properties:
Bucket: !Ref BucketName
PolicyDocument:
Version: "2012-10-17"
Statement:
- Principal:
AWS: !GetAtt User.Arn
Action: "s3:*"
Effect: Allow
Resource:
- !GetAtt Bucket.Arn
- !Sub "${Bucket.Arn}/*"
DependsOn: Key
EC2Instance:
Type: AWS::EC2::Instance
Properties:
ImageId: !FindInMap [RegionMap, !Ref "AWS::Region", AMI]
KeyName: aws-master
InstanceType: t3.micro
DisableApiTermination: true
SecurityGroups: ["nextcloud-security"]
BlockDeviceMappings:
- DeviceName: /dev/sda1
Ebs:
VolumeSize: 10
DeleteOnTermination: false
Tags:
- Key: "Name"
Value: !Ref FQDN
- Key: "env"
Value: "prod"
UserData:
Fn::Base64: !Sub |
#!/bin/bash -xe
exec > >(tee /var/log/user-data.log|logger -t user-data -s 2>/dev/console) 2>&1
curl -s ####### | /bin/bash
git clone #######
cd nextcloud
sed -i 's/# fqdn = nc.example.org/fqdn = ${FQDN}/g' inventory
sed -i "s/ssl_certificate_type = 'selfsigned'/#ssl_certificate_type = 'selfsigned'/g" inventory
sed -i "s/# ssl_certificate_type = 'letsencrypt'/ssl_certificate_type = 'letsencrypt'/g" inventory
sed -i 's/# cert_email = nc@example.org/cert_email = ####/g' inventory
sed -i "s/# nc_db_type = 'mysql'/nc_db_type = 'mysql'/g" inventory
sed -i "s/nc_db_type = 'pgsql'/#nc_db_type = 'pgsql'/g" inventory
sed -i 's/nc_configure_mail = false/nc_configure_mail = true/g' inventory
sed -i 's/nc_mail_from =/nc_mail_from = contact/g' inventory
sed -i 's/nc_mail_domain =/nc_mail_domain = ######/g' inventory
sed -i 's/nc_mail_smtpname =/nc_mail_smtpname = #######/g' inventory
sed -i 's/nc_mail_smtphost =/nc_mail_smtphost = smtp.gmail.com/g' inventory
sed -i 's/nc_mail_smtppwd =/nc_mail_smtppwd = #####/g' inventory
sed -i 's/s3_key =/s3_key = ${Key}/g' inventory
sed -i 's|s3_secret =|s3_secret = ${Key.SecretAccessKey}|g' inventory
sed -i 's/s3_bucket =/s3_bucket = ${BucketName}/g' inventory
sed -i 's/s3_region =/s3_region = ${Region}/g' inventory
sed -i 's/talk_install = false/talk_install = true/g' inventory
./nextcloud.yml
IPAddress:
Type: AWS::EC2::EIP
Properties:
Tags:
- Key: "Name"
Value: !Ref FQDN
- Key: "env"
Value: "prod"
IPAssoc:
Type: AWS::EC2::EIPAssociation
Properties:
InstanceId: !Ref "EC2Instance"
EIP: !Ref "IPAddress"
Route53Record:
Type: AWS::Route53::RecordSet
Properties:
HostedZoneName: "########"
Name: !Join ["", [!Ref FQDN, "."]]
Type: A
TTL: "300"
ResourceRecords:
- !Ref "IPAddress"
Condition: ShouldCreateSubDomain
Outputs:
InstanceId:
Description: InstanceId of the newly created EC2 instance
Value: !Ref "EC2Instance"
InstanceIPAddress:
Description: IP address of the newly created EC2 instance
Value: !Ref "IPAddress"
IAM:
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": [
"ec2:DescribeImages",
"ec2:DescribeInstances",
"ec2:DescribeAddresses",
"ec2:DescribeTags",
"ec2:CreateTags",
"ec2:RunInstances",
"ec2:DescribeKeyPairs",
"ec2:AssociateAddress",
"ec2:AllocateAddress"
],
"Resource": "*"
},
{
"Sid": "VisualEditor1",
"Effect": "Allow",
"Action": [
"iam:AddUserToGroup",
"cloudformation:CreateStack",
"route53:ChangeResourceRecordSets",
"iam:GetUser",
"iam:CreateUser",
"iam:CreateAccessKey"
],
"Resource": [
"arn:aws:iam::*:user/*",
"arn:aws:iam::#######:group/Customers",
"arn:aws:cloudformation:*:*:stack/*/*",
"arn:aws:route53:::hostedzone/#####"
]
}
]
}
来自Selecting a Stack Template - AWS CloudFormation:
Amazon S3 URL: The URL must point to a template with a maximum size of 460,800 bytes that is stored in an S3 bucket that you have read permissions to and that is located in the same region as the stack.
我怀疑您的堆栈出现故障,因为模板位于 Amazon S3 存储桶中,而该存储桶与启动堆栈的区域不同。您需要将模板复制到同一区域的存储桶中,然后在 create_stack()
命令中提供它。
您可以使用 AWS 控制台启动模板来对此进行测试,而不必通过 boto3。