Terjemahan disediakan oleh mesin penerjemah. Jika konten terjemahan yang diberikan bertentangan dengan versi bahasa Inggris aslinya, utamakan versi bahasa Inggris.
Bagian Rules
opsional memvalidasi parameter atau kombinasi parameter yang diteruskan ke templat selama pembuatan tumpukan atau pembaruan tumpukan. Untuk menggunakan aturan templat, secara eksplisit deklarasi Rules
dalam templat Anda diikuti oleh sebuah pernyataan. Gunakan bagian aturan untuk memvalidasi nilai parameter sebelum membuat atau memperbarui sumber daya.
Bekerja dengan aturan
Setiap aturan templat terdiri dari dua properti:
-
Kondisi aturan (opsional) - menentukan kapan aturan berlaku.
-
Pernyataan (wajib) — menjelaskan nilai apa yang dapat ditentukan pengguna untuk parameter tertentu.
Aturan dapat mencakup properti RuleCondition
dan harus mencakup properti Assertions
. Untuk setiap aturan, Anda hanya dapat menentukan satu syarat aturan. Anda dapat menentukan satu atau lebih pernyataan dalam properti Assertions
. Jika Anda tidak menentukan syarat aturan, pernyataan aturan selalu berlaku.
Fungsi intrinsik khusus aturan
Untuk menentukan syarat aturan dan pernyataan, gunakan fungsi intrinsik khusus aturan, yang merupakan fungsi yang hanya dapat digunakan dalam bagian Rules
dari templat. Anda dapat membuat nest fungsi, tetapi hasil akhir dari syarat aturan atau pernyataan harus benar atau salah.
Anda dapat menggunakan fungsi intrinsik khusus aturan berikut untuk menentukan syarat aturan dan pernyataan:
Fungsi intrinsik khusus aturan digunakan dalam syarat atau pernyataan aturan. Properti kondisi menentukan apakah CloudFormation berlaku pernyataan. Jika kondisi mengevaluasitrue
, CloudFormation mengevaluasi pernyataan untuk memverifikasi apakah nilai parameter valid ketika produk yang disediakan dibuat atau diperbarui. Jika nilai parameter tidak valid, CloudFormation tidak membuat atau memperbarui tumpukan. Jika kondisi dievaluasifalse
, CloudFormation tidak memeriksa nilai parameter dan melanjutkan operasi tumpukan.
Sintaks
JSON
Bagian Rules
dari templat terdiri dari nama kunci Rules
, diikuti oleh titik dua. Anda harus menggunakan tanda kurung untuk membungkus seluruh deklarasi aturan. Jika Anda mendeklarasikan beberapa aturan, mereka dibatasi dengan koma. Untuk setiap aturan, Anda mendeklarasi nama logis dalam tanda kutip diikuti oleh titik dua dan tanda kurung yang membungkus syarat dan pernyataan aturan.
{
"Rules": {
"Rule01": {
"RuleCondition": {
"rule-specific intrinsic function": "Value01"
},
"Assertions": [
{
"Assert": {
"rule-specific intrinsic function": "Value02"
},
"AssertDescription": "Information about this assert"
},
{
"Assert": {
"rule-specific intrinsic function": "Value03"
},
"AssertDescription": "Information about this assert"
}
]
},
"Rule02": {
"Assertions": [
{
"Assert": {
"rule-specific intrinsic function": "Value04"
},
"AssertDescription": "Information about this assert"
}
]
}
}
}
YAML
Rules:
Rule01:
RuleCondition:
rule-specific intrinsic function: Value01
Assertions:
- Assert:
rule-specific intrinsic function: Value02
AssertDescription: Information about this assert
- Assert:
rule-specific intrinsic function: Value03
AssertDescription: Information about this assert
Rule02:
Assertions:
- Assert:
rule-specific intrinsic function: Value04
AssertDescription: Information about this assert
Contoh
Memverifikasi nilai parameter secara bersyarat
Dalam contoh berikut, dua aturan tersebut memeriksa nilai parameter InstanceType
. Tergantung pada nilai parameter lingkungan (test
atau prod
), pengguna harus menentukan a1.medium
atau a1.large
untuk parameter InstanceType
. Parameter InstanceType
dan Environment
harus dideklarasikan dalam bagian Parameters
dari templat yang sama.
Contoh JSON
{
"Rules": {
"testInstanceType": {
"RuleCondition": {
"Fn::Equals": [
{
"Ref": "Environment"
},
"test"
]
},
"Assertions": [
{
"Assert": {
"Fn::Contains": [
[
"a1.medium"
],
{
"Ref": "InstanceType"
}
]
},
"AssertDescription": "For a test environment, the instance type must be a1.medium"
}
]
},
"prodInstanceType": {
"RuleCondition": {
"Fn::Equals": [
{
"Ref": "Environment"
},
"prod"
]
},
"Assertions": [
{
"Assert": {
"Fn::Contains": [
[
"a1.large"
],
{
"Ref": "InstanceType"
}
]
},
"AssertDescription": "For a production environment, the instance type must be a1.large"
}
]
}
}
}
Contoh YAML
Rules:
testInstanceType:
RuleCondition: !Equals
- !Ref Environment
- test
Assertions:
- Assert:
'Fn::Contains':
- - a1.medium
- !Ref InstanceType
AssertDescription: 'For a test environment, the instance type must be a1.medium'
prodInstanceType:
RuleCondition: !Equals
- !Ref Environment
- prod
Assertions:
- Assert:
'Fn::Contains':
- - a1.large
- !Ref InstanceType
AssertDescription: 'For a production environment, the instance type must be a1.large'
Validasi lintas parameter
Contoh template berikut, membuat contoh situs web yang menggunakan Amazon EC2 Auto Scaling dan Elastic Load Balancing dan dikonfigurasi untuk menggunakan beberapa Availability Zone. Template juga berisi CloudWatch alarm yang menjalankan kebijakan penskalaan untuk menambah atau menghapus instance dari grup Auto Scaling ketika ambang batas yang ditentukan terlampaui. Template ini membuat satu atau beberapa EC2 instance Amazon.
catatan
Anda akan ditagih untuk AWS sumber daya yang digunakan jika Anda membuat tumpukan dari template ini.
Contoh JSON
{
"AWSTemplateFormatVersion": "2010-09-09",
"Description": "AWS CloudFormation Sample Template for using Assertions: Create a load balanced, Auto Scaled sample website where the instances are locked down to only accept traffic from the load balancer. This example creates an Auto Scaling group behind a load balancer with a health check. The web site is available on port 80 or 443 based on the input.",
"Parameters": {
"VpcId": {
"Type": "AWS::EC2::VPC::Id",
"Description": "VpcId of your existing Virtual Private Cloud (VPC)",
"ConstraintDescription": "must be the VPC Id of an existing Virtual Private Cloud."
},
"Subnets": {
"Type": "List<AWS::EC2::Subnet::Id>",
"Description": "The list of SubnetIds in your Virtual Private Cloud (VPC)",
"ConstraintDescription": "must be a list of at least two existing subnets associated with at least two different availability zones. They should be residing in the selected Virtual Private Cloud."
},
"InstanceType": {
"Description": "WebServer EC2 instance type",
"Type": "String",
"Default": "t2.small",
"AllowedValues": [
"t2.nano",
"t2.micro",
"t2.small",
"t2.medium",
"t2.large",
"m4.large",
"m4.xlarge",
"m4.2xlarge",
"m4.4xlarge",
"m4.10xlarge",
"m3.medium",
"m3.large",
"m3.xlarge",
"m3.2xlarge",
"c4.large",
"c4.xlarge",
"c4.2xlarge",
"c4.4xlarge",
"c4.8xlarge",
"c3.large",
"c3.xlarge",
"c3.2xlarge",
"c3.4xlarge",
"c3.8xlarge",
"r3.large",
"r3.xlarge"
],
"ConstraintDescription": "must be a valid EC2 instance type."
},
"KeyName": {
"Description": "Name of an existing EC2 KeyPair to enable SSH access to the instances",
"Type": "AWS::EC2::KeyPair::KeyName",
"ConstraintDescription": "must be the name of an existing EC2 KeyPair."
},
"SSHLocation": {
"Description": "The IP address range that can be used to SSH to the EC2 instances",
"Type": "String",
"MinLength": "9",
"MaxLength": "18",
"Default": "0.0.0.0/0",
"AllowedPattern": "(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})/(\\d{1,2})",
"ConstraintDescription": "must be a valid IP CIDR range of the form x.x.x.x/x."
},
"UseSSL": {
"AllowedValues": [
"Yes",
"No"
],
"ConstraintDescription": "Select Yes to create a HTTPS Listener",
"Default": "No",
"Description": "Select \"Yes\" to implement SSL, \"No\" to skip (default).",
"Type": "String"
},
"ALBSSLCertificateARN": {
"Default": "",
"Description": "[Optional] The ARN of the SSL certificate to be used for the Application Load Balancer",
"Type": "String"
},
"HostedZoneName": {
"AllowedPattern": "^$|(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\\-]*[a-zA-Z0-9])\\.)*([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9\\-]*[A-Za-z0-9])$",
"Default": "",
"Description": "[Optional] The domain name of a valid Hosted Zone on AWS.",
"Type": "String"
}
},
"Conditions": {
"UseALBSSL": {
"Fn::Not": [
{
"Fn::Equals": [
{
"Ref": "UseSSL"
},
"Yes"
]
}
]
}
},
"Rules": {
"SubnetsInVPC": {
"Assertions": [
{
"Assert": {
"Fn::EachMemberEquals": [
{
"Fn::ValueOf": [
"Subnets",
"VpcId"
]
},
{
"Ref": "VpcId"
}
]
},
"AssertDescription": "All subnets must in the VPC"
}
]
},
"ValidateHostedZone": {
"RuleCondition": {
"Fn::Equals": [
{
"Ref": "UseSSL"
},
"Yes"
]
},
"Assertions": [
{
"Assert": {
"Fn::Not": [
{
"Fn::Equals": [
{
"Ref": "ALBSSLCertificateARN"
},
""
]
}
]
},
"AssertDescription": "ACM Certificate value cannot be empty if SSL is required"
},
{
"Assert": {
"Fn::Not": [
{
"Fn::Equals": [
{
"Ref": "HostedZoneName"
},
""
]
}
]
},
"AssertDescription": "Route53 Hosted Zone Name is mandatory when SSL is required"
}
]
}
},
"Mappings": {
"AWSAMIRegionMap": {
"AMI": {
"AMZNLINUXHVM": "amzn-ami-hvm-2017.09.1.20171120-x86_64-gp2"
},
"ap-northeast-1": {
"AMZNLINUXHVM": "ami-da9e2cbc"
},
"ap-northeast-2": {
"AMZNLINUXHVM": "ami-1196317f"
},
"ap-south-1": {
"AMZNLINUXHVM": "ami-d5c18eba"
},
"ap-southeast-1": {
"AMZNLINUXHVM": "ami-c63d6aa5"
},
"ap-southeast-2": {
"AMZNLINUXHVM": "ami-ff4ea59d"
},
"ca-central-1": {
"AMZNLINUXHVM": "ami-d29e25b6"
},
"eu-central-1": {
"AMZNLINUXHVM": "ami-bf2ba8d0"
},
"eu-west-1": {
"AMZNLINUXHVM": "ami-1a962263"
},
"eu-west-2": {
"AMZNLINUXHVM": "ami-e7d6c983"
},
"sa-east-1": {
"AMZNLINUXHVM": "ami-286f2a44"
},
"us-east-1": {
"AMZNLINUXHVM": "ami-55ef662f"
},
"us-east-2": {
"AMZNLINUXHVM": "ami-15e9c770"
},
"us-west-1": {
"AMZNLINUXHVM": "ami-a51f27c5"
},
"us-west-2": {
"AMZNLINUXHVM": "ami-bf4193c7"
}
}
},
"Resources": {
"WebServerGroup": {
"Type": "AWS::AutoScaling::AutoScalingGroup",
"Properties": {
"VPCZoneIdentifier": {
"Ref": "Subnets"
},
"LaunchConfigurationName": {
"Ref": "LaunchConfig"
},
"MinSize": "2",
"MaxSize": "2",
"TargetGroupARNs": [
{
"Ref": "ALBTargetGroup"
}
]
},
"CreationPolicy": {
"ResourceSignal": {
"Timeout": "PT15M"
}
},
"UpdatePolicy": {
"AutoScalingRollingUpdate": {
"MinInstancesInService": "1",
"MaxBatchSize": "1",
"PauseTime": "PT15M",
"WaitOnResourceSignals": "true"
}
}
},
"LaunchConfig": {
"Type": "AWS::AutoScaling::LaunchConfiguration",
"Metadata": {
"Comment": "Install a simple application",
"AWS::CloudFormation::Init": {
"config": {
"packages": {
"yum": {
"httpd": []
}
},
"files": {
"/var/www/html/index.html": {
"content": {
"Fn::Join": [
"\n",
[
"<h1>Congratulations, you have successfully launched the AWS CloudFormation sample.<h1>"
]
]
},
"mode": "000644",
"owner": "root",
"group": "root"
},
"/etc/cfn/cfn-hup.conf": {
"content": {
"Fn::Join": [
"",
[
"[main]\n",
"stack=",
{
"Ref": "AWS::StackId"
},
"\n",
"region=",
{
"Ref": "AWS::Region"
},
"\n"
]
]
},
"mode": "000400",
"owner": "root",
"group": "root"
},
"/etc/cfn/hooks.d/cfn-auto-reloader.conf": {
"content": {
"Fn::Join": [
"",
[
"[cfn-auto-reloader-hook]\n",
"triggers=post.update\n",
"path=Resources.LaunchConfig.Metadata.AWS::CloudFormation::Init\n",
"action=/opt/aws/bin/cfn-init -v ",
" --stack ",
{
"Ref": "AWS::StackName"
},
" --resource LaunchConfig ",
" --region ",
{
"Ref": "AWS::Region"
},
"\n",
"runas=root\n"
]
]
},
"mode": "000400",
"owner": "root",
"group": "root"
}
},
"services": {
"sysvinit": {
"httpd": {
"enabled": "true",
"ensureRunning": "true"
},
"cfn-hup": {
"enabled": "true",
"ensureRunning": "true",
"files": [
"/etc/cfn/cfn-hup.conf",
"/etc/cfn/hooks.d/cfn-auto-reloader.conf"
]
}
}
}
}
}
},
"Properties": {
"ImageId": {
"Fn::FindInMap": [
"AWSAMIRegionMap",
{
"Ref": "AWS::Region"
},
"AMZNLINUXHVM"
]
},
"SecurityGroups": [
{
"Ref": "InstanceSecurityGroup"
}
],
"InstanceType": {
"Ref": "InstanceType"
},
"KeyName": {
"Ref": "KeyName"
},
"UserData": {
"Fn::Base64": {
"Fn::Join": [
"",
[
"#!/bin/bash -xe\n",
"yum update -y aws-cfn-bootstrap\n",
"/opt/aws/bin/cfn-init -v ",
" --stack ",
{
"Ref": "AWS::StackName"
},
" --resource LaunchConfig ",
" --region ",
{
"Ref": "AWS::Region"
},
"\n",
"/opt/aws/bin/cfn-signal -e $? ",
" --stack ",
{
"Ref": "AWS::StackName"
},
" --resource WebServerGroup ",
" --region ",
{
"Ref": "AWS::Region"
},
"\n"
]
]
}
}
}
},
"ELBSecurityGroup": {
"Type": "AWS::EC2::SecurityGroup",
"Properties": {
"GroupDescription": "Allow access to the ELB",
"VpcId": {
"Ref": "VpcId"
},
"SecurityGroupIngress": [
{
"Fn::If": [
"UseALBSSL",
{
"IpProtocol": "tcp",
"FromPort": 443,
"ToPort": 443,
"CidrIp": "0.0.0.0/0"
},
{
"IpProtocol": "tcp",
"FromPort": 80,
"ToPort": 80,
"CidrIp": "0.0.0.0/0"
}
]
}
]
}
},
"ApplicationLoadBalancer": {
"Type": "AWS::ElasticLoadBalancingV2::LoadBalancer",
"Properties": {
"Subnets": {
"Ref": "Subnets"
},
"SecurityGroups": [
{
"Ref": "ELBSecurityGroup"
}
]
}
},
"ALBListener": {
"Type": "AWS::ElasticLoadBalancingV2::Listener",
"Properties": {
"DefaultActions": [
{
"Type": "forward",
"TargetGroupArn": {
"Ref": "ALBTargetGroup"
}
}
],
"LoadBalancerArn": {
"Ref": "ApplicationLoadBalancer"
},
"Port": {
"Fn::If": [
"UseALBSSL",
443,
80
]
},
"Protocol": {
"Fn::If": [
"UseALBSSL",
"HTTPS",
"HTTP"
]
},
"Certificates": [
{
"Fn::If": [
"UseALBSSL",
{
"CertificateArn": {
"Ref": "ALBSSLCertificateARN"
}
},
{
"Ref": "AWS::NoValue"
}
]
}
]
}
},
"ALBTargetGroup": {
"Type": "AWS::ElasticLoadBalancingV2::TargetGroup",
"Properties": {
"HealthCheckIntervalSeconds": 30,
"HealthCheckTimeoutSeconds": 5,
"HealthyThresholdCount": 3,
"Port": 80,
"Protocol": "HTTP",
"UnhealthyThresholdCount": 5,
"VpcId": {
"Ref": "VpcId"
}
}
},
"InstanceSecurityGroup": {
"Type": "AWS::EC2::SecurityGroup",
"Properties": {
"GroupDescription": "Enable SSH access and HTTP access on the inbound port",
"SecurityGroupIngress": [
{
"IpProtocol": "tcp",
"FromPort": 80,
"ToPort": 80,
"SourceSecurityGroupId": {
"Fn::Select": [
0,
{
"Fn::GetAtt": [
"ApplicationLoadBalancer",
"SecurityGroups"
]
}
]
}
},
{
"IpProtocol": "tcp",
"FromPort": 22,
"ToPort": 22,
"CidrIp": {
"Ref": "SSHLocation"
}
}
],
"VpcId": {
"Ref": "VpcId"
}
}
},
"RecordSet": {
"Type": "AWS::Route53::RecordSetGroup",
"Condition": "UseALBSSL",
"Properties": {
"HostedZoneName": {
"Fn::Join": [
"",
[
{
"Ref": "HostedZoneName"
},
"."
]
]
},
"RecordSets": [
{
"Name": {
"Fn::Join": [
"",
[
{
"Fn::Select": [
"0",
{
"Fn::Split": [
".",
{
"Fn::GetAtt": [
"ApplicationLoadBalancer",
"DNSName"
]
}
]
}
]
},
".",
{
"Ref": "HostedZoneName"
},
"."
]
]
},
"Type": "A",
"AliasTarget": {
"DNSName": {
"Fn::GetAtt": [
"ApplicationLoadBalancer",
"DNSName"
]
},
"EvaluateTargetHealth": true,
"HostedZoneId": {
"Fn::GetAtt": [
"ApplicationLoadBalancer",
"CanonicalHostedZoneID"
]
}
}
}
]
}
}
},
"Outputs": {
"URL": {
"Description": "URL of the website",
"Value": {
"Fn::Join": [
"",
[
{
"Fn::If": [
"UseALBSSL",
{
"Fn::Join": [
"",
[
"https://",
{
"Fn::Join": [
"",
[
{
"Fn::Select": [
"0",
{
"Fn::Split": [
".",
{
"Fn::GetAtt": [
"ApplicationLoadBalancer",
"DNSName"
]
}
]
}
]
},
".",
{
"Ref": "HostedZoneName"
},
"."
]
]
}
]
]
},
{
"Fn::Join": [
"",
[
"http://",
{
"Fn::GetAtt": [
"ApplicationLoadBalancer",
"DNSName"
]
}
]
]
}
]
}
]
]
}
}
}
}
Contoh YAML
AWSTemplateFormatVersion: 2010-09-09
Description: >-
AWS CloudFormation Sample Template for using Assertions: Create a load balanced,
Auto Scaled sample website where the instances are locked down to only accept
traffic from the load balancer. This example creates an Auto Scaling group
behind a load balancer with a health check. The web site is available on port
80 or 443 based on the input.
Parameters:
VpcId:
Type: 'AWS::EC2::VPC::Id'
Description: VpcId of your existing Virtual Private Cloud (VPC)
ConstraintDescription: must be the VPC Id of an existing Virtual Private Cloud.
Subnets:
Type: 'List<AWS::EC2::Subnet::Id>'
Description: The list of SubnetIds in your Virtual Private Cloud (VPC)
ConstraintDescription: >-
must be a list of at least two existing subnets associated with at least
two different availability zones. They should be residing in the selected
Virtual Private Cloud.
InstanceType:
Description: WebServer EC2 instance type
Type: String
Default: t2.small
AllowedValues:
- t2.nano
- t2.micro
- t2.small
- t2.medium
- t2.large
- m4.large
- m4.xlarge
- m4.2xlarge
- m4.4xlarge
- m4.10xlarge
- m3.medium
- m3.large
- m3.xlarge
- m3.2xlarge
- c4.large
- c4.xlarge
- c4.2xlarge
- c4.4xlarge
- c4.8xlarge
- c3.large
- c3.xlarge
- c3.2xlarge
- c3.4xlarge
- c3.8xlarge
- r3.large
- r3.xlarge
ConstraintDescription: must be a valid EC2 instance type.
KeyName:
Description: Name of an existing EC2 KeyPair to enable SSH access to the instances
Type: 'AWS::EC2::KeyPair::KeyName'
ConstraintDescription: must be the name of an existing EC2 KeyPair.
SSHLocation:
Description: The IP address range that can be used to SSH to the EC2 instances
Type: String
MinLength: '9'
MaxLength: '18'
Default: 0.0.0.0/0
AllowedPattern: '(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})/(\d{1,2})'
ConstraintDescription: must be a valid IP CIDR range of the form x.x.x.x/x.
UseSSL:
AllowedValues:
- 'Yes'
- 'No'
ConstraintDescription: Select Yes to create a HTTPS Listener
Default: 'No'
Description: 'Select "Yes" to implement SSL, "No" to skip (default).'
Type: String
ALBSSLCertificateARN:
Default: ''
Description: >-
[Optional] The ARN of the SSL certificate to be used for the Application
Load Balancer
Type: String
HostedZoneName:
AllowedPattern: >-
^$|(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9])\.)*([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9\-]*[A-Za-z0-9])$
Default: ''
Description: '[Optional] The domain name of a valid Hosted Zone on AWS.'
Type: String
Conditions:
UseALBSSL: !Not
- !Equals
- !Ref UseSSL
- 'Yes'
Rules:
SubnetsInVPC:
Assertions:
- Assert:
'Fn::EachMemberEquals':
- 'Fn::ValueOf':
- Subnets
- VpcId
- Ref: VpcId
AssertDescription: All subnets must in the VPC
ValidateHostedZone:
RuleCondition: !Equals
- !Ref UseSSL
- 'Yes'
Assertions:
- Assert: !Not
- !Equals
- !Ref ALBSSLCertificateARN
- ''
AssertDescription: ACM Certificate value cannot be empty if SSL is required
- Assert: !Not
- !Equals
- !Ref HostedZoneName
- ''
AssertDescription: Route53 Hosted Zone Name is mandatory when SSL is required
Mappings:
AWSAMIRegionMap:
AMI:
AMZNLINUXHVM: amzn-ami-hvm-2017.09.1.20171120-x86_64-gp2
ap-northeast-1:
AMZNLINUXHVM: ami-da9e2cbc
ap-northeast-2:
AMZNLINUXHVM: ami-1196317f
ap-south-1:
AMZNLINUXHVM: ami-d5c18eba
ap-southeast-1:
AMZNLINUXHVM: ami-c63d6aa5
ap-southeast-2:
AMZNLINUXHVM: ami-ff4ea59d
ca-central-1:
AMZNLINUXHVM: ami-d29e25b6
eu-central-1:
AMZNLINUXHVM: ami-bf2ba8d0
eu-west-1:
AMZNLINUXHVM: ami-1a962263
eu-west-2:
AMZNLINUXHVM: ami-e7d6c983
sa-east-1:
AMZNLINUXHVM: ami-286f2a44
us-east-1:
AMZNLINUXHVM: ami-55ef662f
us-east-2:
AMZNLINUXHVM: ami-15e9c770
us-west-1:
AMZNLINUXHVM: ami-a51f27c5
us-west-2:
AMZNLINUXHVM: ami-bf4193c7
Resources:
WebServerGroup:
Type: 'AWS::AutoScaling::AutoScalingGroup'
Properties:
VPCZoneIdentifier: !Ref Subnets
LaunchConfigurationName: !Ref LaunchConfig
MinSize: '2'
MaxSize: '2'
TargetGroupARNs:
- !Ref ALBTargetGroup
CreationPolicy:
ResourceSignal:
Timeout: PT15M
UpdatePolicy:
AutoScalingRollingUpdate:
MinInstancesInService: '1'
MaxBatchSize: '1'
PauseTime: PT15M
WaitOnResourceSignals: 'true'
LaunchConfig:
Type: 'AWS::AutoScaling::LaunchConfiguration'
Metadata:
Comment: Install a simple application
'AWS::CloudFormation::Init':
config:
packages:
yum:
httpd: []
files:
/var/www/html/index.html:
content: !Join
- |+
- - >-
<h1>Congratulations, you have successfully launched the AWS
CloudFormation sample.<h1>
mode: '000644'
owner: root
group: root
/etc/cfn/cfn-hup.conf:
content: !Join
- ''
- - |
[main]
- stack=
- !Ref 'AWS::StackId'
- |+
- region=
- !Ref 'AWS::Region'
- |+
mode: '000400'
owner: root
group: root
/etc/cfn/hooks.d/cfn-auto-reloader.conf:
content: !Join
- ''
- - |
[cfn-auto-reloader-hook]
- |
triggers=post.update
- >
path=Resources.LaunchConfig.Metadata.AWS::CloudFormation::Init
- 'action=/opt/aws/bin/cfn-init -v '
- ' --stack '
- !Ref 'AWS::StackName'
- ' --resource LaunchConfig '
- ' --region '
- !Ref 'AWS::Region'
- |+
- |
runas=root
mode: '000400'
owner: root
group: root
services:
sysvinit:
httpd:
enabled: 'true'
ensureRunning: 'true'
cfn-hup:
enabled: 'true'
ensureRunning: 'true'
files:
- /etc/cfn/cfn-hup.conf
- /etc/cfn/hooks.d/cfn-auto-reloader.conf
Properties:
ImageId: !FindInMap
- AWSAMIRegionMap
- !Ref 'AWS::Region'
- AMZNLINUXHVM
SecurityGroups:
- !Ref InstanceSecurityGroup
InstanceType: !Ref InstanceType
KeyName: !Ref KeyName
UserData: !Base64
'Fn::Join':
- ''
- - |
#!/bin/bash -xe
- |
yum update -y aws-cfn-bootstrap
- '/opt/aws/bin/cfn-init -v '
- ' --stack '
- !Ref 'AWS::StackName'
- ' --resource LaunchConfig '
- ' --region '
- !Ref 'AWS::Region'
- |+
- '/opt/aws/bin/cfn-signal -e $? '
- ' --stack '
- !Ref 'AWS::StackName'
- ' --resource WebServerGroup '
- ' --region '
- !Ref 'AWS::Region'
- |+
ELBSecurityGroup:
Type: 'AWS::EC2::SecurityGroup'
Properties:
GroupDescription: Allow access to the ELB
VpcId: !Ref VpcId
SecurityGroupIngress:
- !If
- UseALBSSL
- IpProtocol: tcp
FromPort: 443
ToPort: 443
CidrIp: 0.0.0.0/0
- IpProtocol: tcp
FromPort: 80
ToPort: 80
CidrIp: 0.0.0.0/0
ApplicationLoadBalancer:
Type: 'AWS::ElasticLoadBalancingV2::LoadBalancer'
Properties:
Subnets: !Ref Subnets
SecurityGroups:
- !Ref ELBSecurityGroup
ALBListener:
Type: 'AWS::ElasticLoadBalancingV2::Listener'
Properties:
DefaultActions:
- Type: forward
TargetGroupArn: !Ref ALBTargetGroup
LoadBalancerArn: !Ref ApplicationLoadBalancer
Port: !If
- UseALBSSL
- 443
- 80
Protocol: !If
- UseALBSSL
- HTTPS
- HTTP
Certificates:
- !If
- UseALBSSL
- CertificateArn: !Ref ALBSSLCertificateARN
- !Ref 'AWS::NoValue'
ALBTargetGroup:
Type: 'AWS::ElasticLoadBalancingV2::TargetGroup'
Properties:
HealthCheckIntervalSeconds: 30
HealthCheckTimeoutSeconds: 5
HealthyThresholdCount: 3
Port: 80
Protocol: HTTP
UnhealthyThresholdCount: 5
VpcId: !Ref VpcId
InstanceSecurityGroup:
Type: 'AWS::EC2::SecurityGroup'
Properties:
GroupDescription: Enable SSH access and HTTP access on the inbound port
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: 80
ToPort: 80
SourceSecurityGroupId: !Select
- 0
- !GetAtt
- ApplicationLoadBalancer
- SecurityGroups
- IpProtocol: tcp
FromPort: 22
ToPort: 22
CidrIp: !Ref SSHLocation
VpcId: !Ref VpcId
RecordSet:
Type: 'AWS::Route53::RecordSetGroup'
Condition: UseALBSSL
Properties:
HostedZoneName: !Join
- ''
- - !Ref HostedZoneName
- .
RecordSets:
- Name: !Join
- ''
- - !Select
- '0'
- !Split
- .
- !GetAtt
- ApplicationLoadBalancer
- DNSName
- .
- !Ref HostedZoneName
- .
Type: A
AliasTarget:
DNSName: !GetAtt
- ApplicationLoadBalancer
- DNSName
EvaluateTargetHealth: true
HostedZoneId: !GetAtt
- ApplicationLoadBalancer
- CanonicalHostedZoneID
Outputs:
URL:
Description: URL of the website
Value: !Join
- ''
- - !If
- UseALBSSL
- !Join
- ''
- - 'https://'
- !Join
- ''
- - !Select
- '0'
- !Split
- .
- !GetAtt
- ApplicationLoadBalancer
- DNSName
- .
- !Ref HostedZoneName
- .
- !Join
- ''
- - 'http://'
- !GetAtt
- ApplicationLoadBalancer
- DNSName