Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/359.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Amazon web services 由于CFN-INIT脚本问题,AWS CloudFormation堆栈创建失败_Amazon Web Services_Amazon Cloudformation_Autoscaling_Aws Load Balancer - Fatal编程技术网

Amazon web services 由于CFN-INIT脚本问题,AWS CloudFormation堆栈创建失败

Amazon web services 由于CFN-INIT脚本问题,AWS CloudFormation堆栈创建失败,amazon-web-services,amazon-cloudformation,autoscaling,aws-load-balancer,Amazon Web Services,Amazon Cloudformation,Autoscaling,Aws Load Balancer,我创建了两个模板——一个用于创建VPC和相关项目,另一个用于使用第一个模板中导出的资源创建两层web应用程序。我正在使用自动缩放组在专用子网中创建实例,并连接到公用子网中面向web的负载平衡器。公共子网中连接了一个网络网关 VPC模板运行良好,所有资源都按其应有的方式创建和导出。 但是,应用程序创建堆栈失败。在下面的日志中,我已经禁用了在创建失败和登录到实例时终止资源- Complete! + /opt/aws/bin/cfn-init -v --stack Two-Tier --resourc

我创建了两个模板——一个用于创建VPC和相关项目,另一个用于使用第一个模板中导出的资源创建两层web应用程序。我正在使用自动缩放组在专用子网中创建实例,并连接到公用子网中面向web的负载平衡器。公共子网中连接了一个网络网关

VPC模板运行良好,所有资源都按其应有的方式创建和导出。 但是,应用程序创建堆栈失败。在下面的日志中,我已经禁用了在创建失败和登录到实例时终止资源-

Complete!
+ /opt/aws/bin/cfn-init -v --stack Two-Tier --resource LaunchConfig -- 
configsets All --region us-east-1
+ /opt/aws/bin/cfn-signal -e 0 --stack Two-Tier --resource ExtAutoScaGrp --region us-east-1
ValidationError: Stack arn:aws:cloudformation:us-east-1:321777534159:stack/Two-Tier/13d87cf0-589f-11e9-aeab-1204ddd846a2 is in CREATE_FAILED state and cannot be signaled
Apr 06 19:23:06 cloud-init[2829]: util.py[WARNING]: Failed running /var/lib/cloud/instance/scripts/part-001 [1]
Apr 06 19:23:06 cloud-init[2829]: cc_scripts_user.py[WARNING]: Failed to run module scripts-user (scripts in /var/lib/cloud/instance/scripts)
Apr 06 19:23:06 cloud-init[2829]: util.py[WARNING]: Running module scripts-user (<module 'cloudinit.config.cc_scripts_user' from '/usr/lib/python2.7/dist-packages/cloudinit/config/cc_scripts_user.pyc'>) failed
Cloud-init v. 0.7.6 finished at Sat, 06 Apr 2019 19:23:06 +0000. Datasource DataSourceEc2.  Up 39.42 seconds

[root@ip-10-10-20-172 log]# cat /var/lib/cloud/instance/scripts/part-001
#!/bin/bash -ex
 yum update -y aws-cfn-bootstrap
/opt/aws/bin/cfn-init -v --stack Two-Tier --resource LaunchConfig --configsets All --region us-east-1
# Signal the status from cfn-init (via $?)
/opt/aws/bin/cfn-signal -e $? --stack Two-Tier --resource ExtAutoScaGrp --region us-east-1
我的应用程序模板是-

---
# This template will create a two tier deployment of LAMP stack by refering to an 
# exisitn VPC resource - ar3vpcresource
#
#
AWSTemplateFormatVersion: 2010-09-09
Description: 2 tier deployment of LAMP Stack.
Parameters:
#  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.
  NetworkStackName:
    Description: >-
      Name of an active CloudFormation stack that contains the networking
      resources, such as the subnet and security group, that will be used in
      this stack.
    Type: String
    MinLength: 1
    MaxLength: 255
    AllowedPattern: '^[a-zA-Z][-a-zA-Z0-9]*$'
    Default: Demo-Vpc
  DBName:
    Default: AR3Db
    Description: MySQL database name
    Type: String
    MinLength: '1'
    MaxLength: '64'
    AllowedPattern: '[a-zA-Z][a-zA-Z0-9]*'
    ConstraintDescription: must begin with a letter and contain only alphanumeric characters.
  DBUser:
    Default: dotsphere
    Description: Username for MySQL database access
    Type: String
    MinLength: '1'
    MaxLength: '16'
    AllowedPattern: '[a-zA-Z][a-zA-Z0-9]*'
    ConstraintDescription: must begin with a letter and contain only alphanumeric characters.
  DBPassword:
    NoEcho: 'true'
    Description: Password for MySQL database access
    Type: String
    MinLength: '1'
    MaxLength: '41'
    AllowedPattern: '[a-zA-Z0-9]*'
    ConstraintDescription: must contain only alphanumeric characters.
  DBRootPassword:
    NoEcho: 'true'
    Description: Root password for MySQL
    Type: String
    MinLength: '1'
    MaxLength: '41'
    AllowedPattern: '[a-zA-Z0-9]*'
    ConstraintDescription: must contain only alphanumeric characters.  
  InstanceType:
    Description: EC2 Instance Type
    Type: String
    Default: t2.micro
    AllowedValues:
      - t1.micro
      - t2.nano
      - t2.micro
      - t2.small
      - t2.medium
      - t2.large
      - m1.small
      - m1.medium
      - m1.large
      - m1.xlarge
      - m2.xlarge
      - m2.2xlarge
      - m2.4xlarge
      - m3.medium
      - m3.large
      - m3.xlarge
      - m3.2xlarge
      - m4.large
      - m4.xlarge
      - m4.2xlarge
      - m4.4xlarge
      - m4.10xlarge
      - c1.medium
      - c1.xlarge
      - c3.large
      - c3.xlarge
      - c3.2xlarge
      - c3.4xlarge
      - c3.8xlarge
      - c4.large
      - c4.xlarge
      - c4.2xlarge
      - c4.4xlarge
      - c4.8xlarge
      - g2.2xlarge
      - g2.8xlarge
      - r3.large
      - r3.xlarge
      - r3.2xlarge
      - r3.4xlarge
      - r3.8xlarge
      - i2.xlarge
      - i2.2xlarge
      - i2.4xlarge
      - i2.8xlarge
      - d2.xlarge
      - d2.2xlarge
      - d2.4xlarge
      - d2.8xlarge
      - hi1.4xlarge
      - hs1.8xlarge
      - cr1.8xlarge
      - cc2.8xlarge
      - cg1.4xlarge
    ConstraintDescription: Must be a valid Instance type.
  WebServerCapacity:
    Default: '2'
    Description: The initial number of WebServer instances
    Type: Number
    MinValue: '1'
    MaxValue: '2'
    ConstraintDescription: must be between 1 and 2 EC2 instances.  
  KeyName:
    Description: Existing KeyPair name
    Type: AWS::EC2::KeyPair::KeyName
    ConstraintDescription: Must be an existing KeyPair from the region where instance is being created.

  ModuleName:
    Description: The name of the JavaScript file that will be used for amilookup
    Type: String
    Default: amilookup
  S3Bucket:
    Description: The name of the bucket that contains your packaged source
    Type: String
    Default: ar3resource
  S3Key:
    Description: The name of the ZIP package
    Type: String
    Default: amilookup.zip
Mappings:    
  AWSInstanceType2Arch:
    t1.micro:
      Arch: HVM64
    t2.nano:
      Arch: HVM64
    t2.micro:
      Arch: HVM64
    t2.small:
      Arch: HVM64
    t2.medium:
      Arch: HVM64
    t2.large:
      Arch: HVM64
    m1.small:
      Arch: HVM64
    m1.medium:
      Arch: HVM64
    m1.large:
      Arch: HVM64
    m1.xlarge:
      Arch: HVM64
    m2.xlarge:
      Arch: HVM64
    m2.2xlarge:
      Arch: HVM64
    m2.4xlarge:
      Arch: HVM64
    m3.medium:
      Arch: HVM64
    m3.large:
      Arch: HVM64
    m3.xlarge:
      Arch: HVM64
    m3.2xlarge:
      Arch: HVM64
    m4.large:
      Arch: HVM64
    m4.xlarge:
      Arch: HVM64
    m4.2xlarge:
      Arch: HVM64
    m4.4xlarge:
      Arch: HVM64
    m4.10xlarge:
      Arch: HVM64
    c1.medium:
      Arch: HVM64
    c1.xlarge:
      Arch: HVM64
    c3.large:
      Arch: HVM64
    c3.xlarge:
      Arch: HVM64
    c3.2xlarge:
      Arch: HVM64
    c3.4xlarge:
      Arch: HVM64
    c3.8xlarge:
      Arch: HVM64
    c4.large:
      Arch: HVM64
    c4.xlarge:
      Arch: HVM64
    c4.2xlarge:
      Arch: HVM64
    c4.4xlarge:
      Arch: HVM64
    c4.8xlarge:
      Arch: HVM64
    g2.2xlarge:
      Arch: HVMG2
    g2.8xlarge:
      Arch: HVMG2
    r3.large:
      Arch: HVM64
    r3.xlarge:
      Arch: HVM64
    r3.2xlarge:
      Arch: HVM64
    r3.4xlarge:
      Arch: HVM64
    r3.8xlarge:
      Arch: HVM64
    i2.xlarge:
      Arch: HVM64
    i2.2xlarge:
      Arch: HVM64
    i2.4xlarge:
      Arch: HVM64
    i2.8xlarge:
      Arch: HVM64
    d2.xlarge:
      Arch: HVM64
    d2.2xlarge:
      Arch: HVM64
    d2.4xlarge:
      Arch: HVM64
    d2.8xlarge:
      Arch: HVM64
    hi1.4xlarge:
      Arch: HVM64
    hs1.8xlarge:
      Arch: HVM64
    cr1.8xlarge:
      Arch: HVM64
    cc2.8xlarge:
      Arch: HVM64

Resources:
  AR3NATGateway:
    Type: 'AWS::EC2::NatGateway'
    Properties:
      AllocationId: !GetAtt
        - GatewayElasticIp
        - AllocationId
      SubnetId:   
        !ImportValue 
        'Fn::Sub': '${NetworkStackName}-PubSubnetID1'
  GatewayElasticIp:
    Type: 'AWS::EC2::EIP'
    Properties:
      Domain: vpc
  PrivateRouteToInternet:
    Type: 'AWS::EC2::Route'
    Properties:
      RouteTableId:
        !ImportValue 
        'Fn::Sub': '${NetworkStackName}-PrivRoute'
      DestinationCidrBlock: 0.0.0.0/0
      NatGatewayId: !Ref AR3NATGateway    
  ExternalALB:
    Type: 'AWS::ElasticLoadBalancingV2::LoadBalancer'
    Properties:
      Subnets: 
      - !ImportValue 
        'Fn::Sub': '${NetworkStackName}-PubSubnetID1'
      - !ImportValue 
        'Fn::Sub': '${NetworkStackName}-PubSubnetID2'  
      SecurityGroups: 
      - !ImportValue 
        'Fn::Sub': '${NetworkStackName}-WebSecurityGroup'
  ExternalALBListener:
    Type: 'AWS::ElasticLoadBalancingV2::Listener'
    Properties:
      DefaultActions:
        - Type: forward
          TargetGroupArn: !Ref ExtALBTargetGroup
      LoadBalancerArn: !Ref ExternalALB
      Port: '80'
      Protocol: HTTP
  ExtALBTargetGroup:
    Type: 'AWS::ElasticLoadBalancingV2::TargetGroup'
    Properties:
      HealthCheckIntervalSeconds: '10'
      HealthCheckTimeoutSeconds: '5'
      HealthyThresholdCount: '2'
      Port: '80'
      Protocol: HTTP
      UnhealthyThresholdCount: '5'
      VpcId: !ImportValue 
        'Fn::Sub': '${NetworkStackName}-VPCID'
      TargetGroupAttributes:
        - Key: stickiness.enabled
          Value: 'true'
        - Key: stickiness.type
          Value: lb_cookie
        - Key: stickiness.lb_cookie.duration_seconds
          Value: '30'
  ExtAutoScaGrp:
    Type: 'AWS::AutoScaling::AutoScalingGroup'
    Properties:
      VPCZoneIdentifier:
      - !ImportValue 
        'Fn::Sub': '${NetworkStackName}-PrivSubnetID1'
      - !ImportValue 
        'Fn::Sub': '${NetworkStackName}-PrivSubnetID2'
      LaunchConfigurationName: !Ref LaunchConfig
      MinSize: '1'
      MaxSize: '2'
      DesiredCapacity: !Ref WebServerCapacity
      TargetGroupARNs:
        - !Ref ExtALBTargetGroup
    CreationPolicy:
      ResourceSignal:
        Timeout: PT5M
        Count: !Ref WebServerCapacity
    UpdatePolicy:
      AutoScalingRollingUpdate:
        MinInstancesInService: '1'
        MaxBatchSize: '1'
        PauseTime: PT15M
        WaitOnResourceSignals: 'true'
  LaunchConfig:
    Type: 'AWS::AutoScaling::LaunchConfiguration'
    Metadata:
      'AWS::CloudFormation::Init':
        configSets:
          All:
            - ConfigureSvr
        ConfigureSvr:    
          packages:
            yum:
              httpd: []
              mysql-server: []
              mysql-libs: []
              php: []
              php-mysql: []
          files:
            /var/www/html/index.html:
              content: !Sub |
                <html>
                  <body>
                    <h1>AR3 Web </h1>
                    <h2>This is a test web page!!</h2>
                    Created from Stack - ${AWS::StackName}
                  </body
                </html>
              mode: '000644'
              owner: root
              group: root
            /etc/cfn/cfn-hup.conf:
              content: !Sub |
                [main]
                stack=${AWS::StackId}
                region=${AWS::Region}
                interval=1
              mode: '000400'
              owner: root
              group: root
            /etc/cfn/hooks.d/cfn-auto-reloader.conf:
              content: !Sub |
                [cfn-auto-reloader-hook]
                triggers=post.update
                path=Resources.LaunchConfig.Metadata.AWS::CloudFormation::Init
                action=/opt/aws/bin/cfn-init -v --stack ${AWS::StackName} --resource LaunchConfig --region ${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:
      InstanceType: !Ref InstanceType
      ImageId: !GetAtt
        - AMIInfo
        - Id      
      KeyName: !Ref KeyName
      SecurityGroups:
        - !ImportValue
          'Fn::Sub': '${NetworkStackName}-PrivateSecurityGroup'
      UserData:
        'Fn::Base64': !Sub |
          #!/bin/bash -ex
           yum update -y aws-cfn-bootstrap
          /opt/aws/bin/cfn-init -v --stack ${AWS::StackName} --resource LaunchConfig --configsets All --region ${AWS::Region}
          # Signal the status from cfn-init (via $?)
          /opt/aws/bin/cfn-signal -e $? --stack ${AWS::StackName} --resource ExtAutoScaGrp --region ${AWS::Region}
  AMIInfo:
    Type: 'Custom::AMIInfo'
    Properties:
      ServiceToken: !GetAtt
        - AMIInfoFunction
        - Arn
      Region: !Ref 'AWS::Region'
      Architecture: !FindInMap [ AWSInstanceType2Arch, !Ref InstanceType, Arch ]
  AMIInfoFunction:
    Type: 'AWS::Lambda::Function'
    Properties:
      Code:
        S3Bucket: !Ref S3Bucket
        S3Key: !Ref S3Key
      Handler: !Join
        - ''
        - - !Ref ModuleName
          - .handler
      Role: !GetAtt     
        - LambdaExecutionRole
        - Arn
      Runtime: nodejs8.10
      Timeout: '30'  
  LambdaExecutionRole:
    Type: 'AWS::IAM::Role'
    Properties:
      AssumeRolePolicyDocument:
        Version: 2012-10-17
        Statement:
          - Effect: Allow
            Principal:
              Service:
                - lambda.amazonaws.com
            Action:
              - 'sts:AssumeRole'
      Path: /
      Policies:
        - PolicyName: root
          PolicyDocument:
            Version: '2012-10-17'
            Statement:
              - Effect: Allow
                Action:
                  - 'logs:CreateLogGroup'
                  - 'logs:CreateLogStream'
                  - 'logs:PutLogEvents'
                Resource: 'arn:aws:logs:*:*:*'
              - Effect: Allow
                Action:
                  - 'ec2:DescribeImages'
                Resource: '*'
Outputs:
  WebsiteURL:
    Description: URL for newly created Webserver stack
    Value: !Join 
      - ''
      - - 'http://'
        - !GetAtt 
          - ExternalALB
          - DNSName                        

---
#此模板将通过引用
#现有VPC资源-AR3VPC资源
#
#
AWST模板格式版本:2010-09-09
说明:灯组的2层展开。
参数:
#子网:
#键入:“列表”
#描述:虚拟私有云(VPC)中的子网列表
#约束描述:>-
#必须是至少两个现有子网的列表,这些子网至少与
#两个不同的可用性区域。他们应居住在选定的区域内
#虚拟私有云。
NetworkStackName:
说明:>-
包含网络的活动CloudFormation堆栈的名称
将在中使用的资源,如子网和安全组
这一堆。
类型:字符串
最小长度:1
最大长度:255
允许模式:“^[a-zA-Z][a-zA-Z0-9]*$”
默认值:演示Vpc
数据库名:
默认值:AR3Db
Description:MySQL数据库名称
类型:字符串
MinLength:'1'
MaxLength:'64'
允许模式:'[a-zA-Z][a-zA-Z0-9]*'
ConstraintDescription:必须以字母开头,并且仅包含字母数字字符。
数据库用户:
默认值:点域
Description:用于MySQL数据库访问的用户名
类型:字符串
MinLength:'1'
MaxLength:'16'
允许模式:'[a-zA-Z][a-zA-Z0-9]*'
ConstraintDescription:必须以字母开头,并且仅包含字母数字字符。
数据库密码:
诺埃乔:“真的”
Description:MySQL数据库访问密码
类型:字符串
MinLength:'1'
MaxLength:'41'
允许模式:'[a-zA-Z0-9]*'
ConstraintDescription:只能包含字母数字字符。
DBRootPassword:
诺埃乔:“真的”
Description:MySQL的Root密码
类型:字符串
MinLength:'1'
MaxLength:'41'
允许模式:'[a-zA-Z0-9]*'
ConstraintDescription:只能包含字母数字字符。
实例类型:
Description:EC2实例类型
类型:字符串
默认值:t2.micro
允许值:
-t1.micro
-t2.nano
-t2.micro
-t2.小
-t2.中等
-t2.大
-m1.小型
-m1.中等
-m1.大
-m1.xlarge
-m2.xlarge
-m2.2x大
-m2.4XL
-m3.中等
-m3.1大
-m3.xlarge
-m3.2xL
-m4.5大
-m4.xlarge
-m4.2x大
-m4.4XL
-m4.10xlarge
-c1.中等
-c1.xlarge
-c3.大型
-c3.xlarge
-c3.2xL
-c3.4XL
-c3.8XL
-c4.大型
-c4.xlarge
-c4.2x大
-c4.4XL
-c4.8XL
-g2.2xL
-g2.8XL
-大的
-r3.xlarge
-r3.2xL
-r3.4XL
-r3.8XL
-i2.xlarge
-i2.2x大
-i2.4XL
-i2.8XL
-d2.xlarge
-d2.2xL
-d2.4XL
-d2.8XL
-hi1.4XL
-hs1.8XL
-cr1.8XL
-cc2.8XL
-cg1.4XL
ConstraintDescription:必须是有效的实例类型。
网络服务器容量:
默认值:“2”
Description:Web服务器实例的初始数量
类型:编号
MinValue:'1'
最大值:“2”
ConstraintDescription:必须介于1到2个EC2实例之间。
关键字名称:
描述:现有密钥对名称
类型:AWS::EC2::KeyPair::KeyName
ConstraintDescription:必须是创建实例所在区域的现有密钥对。
模块名称:
Description:将用于AMI查找的JavaScript文件的名称
类型:字符串
默认值:amilookup
S3Bucket:
描述:包含打包源的bucket的名称
类型:字符串
默认值:ar3resource
S3键:
描述:ZIP包的名称
类型:字符串
默认值:amilookup.zip
映射:
AWSInstanceType2Arch:
t1.micro:
拱门:HVM64
t2.nano:
拱门:HVM64
t2.micro:
拱门:HVM64
t2.小型:
拱门:HVM64
t2.中等:
拱门:HVM64
t2.大:
拱门:HVM64
m1.小型:
拱门:HVM64
m1.中等:
拱门:HVM64
m1.大型:
拱门:HVM64
m1.xlarge:
拱门:HVM64
m2.xlarge:
拱门:HVM64
m2.2x大:
拱门:HVM64
m2.4xL:
拱门:HVM64
m3.中等:
拱门:HVM64
m3.1大型:
拱门:HVM64
m3.xlarge:
拱门:HVM64
m3.2x大:
拱门:HVM64
m4.1大:
拱门:HVM64
m4.xlarge:
拱门:HVM64
m4.2x大:
拱门:HVM64
m4.4XL:
拱门:HVM64
m4.10xlarge:
拱门:HVM64
c1.中等:
拱门:HVM64
c1.xlarge:
拱门:HVM64
c3.1.大型:
拱门:HVM64
c3.xlarge:
拱门:HVM64
c3.2x大:
拱门:HVM64
c3.4XL:
拱门:HVM64
c3.8XL:
拱门:HVM64
c4.大型:
拱门:HVM64
c4.xlarge:
拱门:HVM64
c4.2x大:
拱门:HVM64
c4.4XL:
拱门:HVM64
c4.8XL:
拱门:HVM64
g2.2xlarge:
拱门:HVMG2
g2.8XL:
拱门:HVMG2
r3.1大:
拱门:HVM64
r3.xlarge:
拱门:HVM64
r3.2x大:
拱门:HVM64
r3.4XL:
拱门:HVM64
r3.8XL:
拱门:HVM64
i2.xlarge:
拱门:HVM64
i2.2xlar
---
# This template will create a two tier deployment of LAMP stack by refering to an 
# exisitn VPC resource - ar3vpcresource
#
#
AWSTemplateFormatVersion: 2010-09-09
Description: 2 tier deployment of LAMP Stack.
Parameters:
#  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.
  NetworkStackName:
    Description: >-
      Name of an active CloudFormation stack that contains the networking
      resources, such as the subnet and security group, that will be used in
      this stack.
    Type: String
    MinLength: 1
    MaxLength: 255
    AllowedPattern: '^[a-zA-Z][-a-zA-Z0-9]*$'
    Default: Demo-Vpc
  DBName:
    Default: AR3Db
    Description: MySQL database name
    Type: String
    MinLength: '1'
    MaxLength: '64'
    AllowedPattern: '[a-zA-Z][a-zA-Z0-9]*'
    ConstraintDescription: must begin with a letter and contain only alphanumeric characters.
  DBUser:
    Default: dotsphere
    Description: Username for MySQL database access
    Type: String
    MinLength: '1'
    MaxLength: '16'
    AllowedPattern: '[a-zA-Z][a-zA-Z0-9]*'
    ConstraintDescription: must begin with a letter and contain only alphanumeric characters.
  DBPassword:
    NoEcho: 'true'
    Description: Password for MySQL database access
    Type: String
    MinLength: '1'
    MaxLength: '41'
    AllowedPattern: '[a-zA-Z0-9]*'
    ConstraintDescription: must contain only alphanumeric characters.
  DBRootPassword:
    NoEcho: 'true'
    Description: Root password for MySQL
    Type: String
    MinLength: '1'
    MaxLength: '41'
    AllowedPattern: '[a-zA-Z0-9]*'
    ConstraintDescription: must contain only alphanumeric characters.  
  InstanceType:
    Description: EC2 Instance Type
    Type: String
    Default: t2.micro
    AllowedValues:
      - t1.micro
      - t2.nano
      - t2.micro
      - t2.small
      - t2.medium
      - t2.large
      - m1.small
      - m1.medium
      - m1.large
      - m1.xlarge
      - m2.xlarge
      - m2.2xlarge
      - m2.4xlarge
      - m3.medium
      - m3.large
      - m3.xlarge
      - m3.2xlarge
      - m4.large
      - m4.xlarge
      - m4.2xlarge
      - m4.4xlarge
      - m4.10xlarge
      - c1.medium
      - c1.xlarge
      - c3.large
      - c3.xlarge
      - c3.2xlarge
      - c3.4xlarge
      - c3.8xlarge
      - c4.large
      - c4.xlarge
      - c4.2xlarge
      - c4.4xlarge
      - c4.8xlarge
      - g2.2xlarge
      - g2.8xlarge
      - r3.large
      - r3.xlarge
      - r3.2xlarge
      - r3.4xlarge
      - r3.8xlarge
      - i2.xlarge
      - i2.2xlarge
      - i2.4xlarge
      - i2.8xlarge
      - d2.xlarge
      - d2.2xlarge
      - d2.4xlarge
      - d2.8xlarge
      - hi1.4xlarge
      - hs1.8xlarge
      - cr1.8xlarge
      - cc2.8xlarge
      - cg1.4xlarge
    ConstraintDescription: Must be a valid Instance type.
  WebServerCapacity:
    Default: '2'
    Description: The initial number of WebServer instances
    Type: Number
    MinValue: '1'
    MaxValue: '2'
    ConstraintDescription: must be between 1 and 2 EC2 instances.  
  KeyName:
    Description: Existing KeyPair name
    Type: AWS::EC2::KeyPair::KeyName
    ConstraintDescription: Must be an existing KeyPair from the region where instance is being created.

  ModuleName:
    Description: The name of the JavaScript file that will be used for amilookup
    Type: String
    Default: amilookup
  S3Bucket:
    Description: The name of the bucket that contains your packaged source
    Type: String
    Default: ar3resource
  S3Key:
    Description: The name of the ZIP package
    Type: String
    Default: amilookup.zip
Mappings:    
  AWSInstanceType2Arch:
    t1.micro:
      Arch: HVM64
    t2.nano:
      Arch: HVM64
    t2.micro:
      Arch: HVM64
    t2.small:
      Arch: HVM64
    t2.medium:
      Arch: HVM64
    t2.large:
      Arch: HVM64
    m1.small:
      Arch: HVM64
    m1.medium:
      Arch: HVM64
    m1.large:
      Arch: HVM64
    m1.xlarge:
      Arch: HVM64
    m2.xlarge:
      Arch: HVM64
    m2.2xlarge:
      Arch: HVM64
    m2.4xlarge:
      Arch: HVM64
    m3.medium:
      Arch: HVM64
    m3.large:
      Arch: HVM64
    m3.xlarge:
      Arch: HVM64
    m3.2xlarge:
      Arch: HVM64
    m4.large:
      Arch: HVM64
    m4.xlarge:
      Arch: HVM64
    m4.2xlarge:
      Arch: HVM64
    m4.4xlarge:
      Arch: HVM64
    m4.10xlarge:
      Arch: HVM64
    c1.medium:
      Arch: HVM64
    c1.xlarge:
      Arch: HVM64
    c3.large:
      Arch: HVM64
    c3.xlarge:
      Arch: HVM64
    c3.2xlarge:
      Arch: HVM64
    c3.4xlarge:
      Arch: HVM64
    c3.8xlarge:
      Arch: HVM64
    c4.large:
      Arch: HVM64
    c4.xlarge:
      Arch: HVM64
    c4.2xlarge:
      Arch: HVM64
    c4.4xlarge:
      Arch: HVM64
    c4.8xlarge:
      Arch: HVM64
    g2.2xlarge:
      Arch: HVMG2
    g2.8xlarge:
      Arch: HVMG2
    r3.large:
      Arch: HVM64
    r3.xlarge:
      Arch: HVM64
    r3.2xlarge:
      Arch: HVM64
    r3.4xlarge:
      Arch: HVM64
    r3.8xlarge:
      Arch: HVM64
    i2.xlarge:
      Arch: HVM64
    i2.2xlarge:
      Arch: HVM64
    i2.4xlarge:
      Arch: HVM64
    i2.8xlarge:
      Arch: HVM64
    d2.xlarge:
      Arch: HVM64
    d2.2xlarge:
      Arch: HVM64
    d2.4xlarge:
      Arch: HVM64
    d2.8xlarge:
      Arch: HVM64
    hi1.4xlarge:
      Arch: HVM64
    hs1.8xlarge:
      Arch: HVM64
    cr1.8xlarge:
      Arch: HVM64
    cc2.8xlarge:
      Arch: HVM64

Resources:
  AR3NATGateway:
    Type: 'AWS::EC2::NatGateway'
    Properties:
      AllocationId: !GetAtt
        - GatewayElasticIp
        - AllocationId
      SubnetId:   
        !ImportValue 
        'Fn::Sub': '${NetworkStackName}-PubSubnetID1'
  GatewayElasticIp:
    Type: 'AWS::EC2::EIP'
    Properties:
      Domain: vpc
  PrivateRouteToInternet:
    Type: 'AWS::EC2::Route'
    Properties:
      RouteTableId:
        !ImportValue 
        'Fn::Sub': '${NetworkStackName}-PrivRoute'
      DestinationCidrBlock: 0.0.0.0/0
      NatGatewayId: !Ref AR3NATGateway    
  ExternalALB:
    Type: 'AWS::ElasticLoadBalancingV2::LoadBalancer'
    Properties:
      Subnets: 
      - !ImportValue 
        'Fn::Sub': '${NetworkStackName}-PubSubnetID1'
      - !ImportValue 
        'Fn::Sub': '${NetworkStackName}-PubSubnetID2'  
      SecurityGroups: 
      - !ImportValue 
        'Fn::Sub': '${NetworkStackName}-WebSecurityGroup'
  ExternalALBListener:
    Type: 'AWS::ElasticLoadBalancingV2::Listener'
    Properties:
      DefaultActions:
        - Type: forward
          TargetGroupArn: !Ref ExtALBTargetGroup
      LoadBalancerArn: !Ref ExternalALB
      Port: '80'
      Protocol: HTTP
  ExtALBTargetGroup:
    Type: 'AWS::ElasticLoadBalancingV2::TargetGroup'
    Properties:
      HealthCheckIntervalSeconds: '10'
      HealthCheckTimeoutSeconds: '5'
      HealthyThresholdCount: '2'
      Port: '80'
      Protocol: HTTP
      UnhealthyThresholdCount: '5'
      VpcId: !ImportValue 
        'Fn::Sub': '${NetworkStackName}-VPCID'
      TargetGroupAttributes:
        - Key: stickiness.enabled
          Value: 'true'
        - Key: stickiness.type
          Value: lb_cookie
        - Key: stickiness.lb_cookie.duration_seconds
          Value: '30'
  ExtAutoScaGrp:
    Type: 'AWS::AutoScaling::AutoScalingGroup'
    Properties:
      VPCZoneIdentifier:
      - !ImportValue 
        'Fn::Sub': '${NetworkStackName}-PrivSubnetID1'
      - !ImportValue 
        'Fn::Sub': '${NetworkStackName}-PrivSubnetID2'
      LaunchConfigurationName: !Ref LaunchConfig
      MinSize: '1'
      MaxSize: '2'
      DesiredCapacity: !Ref WebServerCapacity
      TargetGroupARNs:
        - !Ref ExtALBTargetGroup
    CreationPolicy:
      ResourceSignal:
        Timeout: PT5M
        Count: !Ref WebServerCapacity
    UpdatePolicy:
      AutoScalingRollingUpdate:
        MinInstancesInService: '1'
        MaxBatchSize: '1'
        PauseTime: PT15M
        WaitOnResourceSignals: 'true'
  LaunchConfig:
    Type: 'AWS::AutoScaling::LaunchConfiguration'
    Metadata:
      'AWS::CloudFormation::Init':
        configSets:
          All:
            - ConfigureSvr
        ConfigureSvr:    
          packages:
            yum:
              httpd: []
              mysql-server: []
              mysql-libs: []
              php: []
              php-mysql: []
          files:
            /var/www/html/index.html:
              content: !Sub |
                <html>
                  <body>
                    <h1>AR3 Web </h1>
                    <h2>This is a test web page!!</h2>
                    Created from Stack - ${AWS::StackName}
                  </body
                </html>
              mode: '000644'
              owner: root
              group: root
            /etc/cfn/cfn-hup.conf:
              content: !Sub |
                [main]
                stack=${AWS::StackId}
                region=${AWS::Region}
                interval=1
              mode: '000400'
              owner: root
              group: root
            /etc/cfn/hooks.d/cfn-auto-reloader.conf:
              content: !Sub |
                [cfn-auto-reloader-hook]
                triggers=post.update
                path=Resources.LaunchConfig.Metadata.AWS::CloudFormation::Init
                action=/opt/aws/bin/cfn-init -v --stack ${AWS::StackName} --resource LaunchConfig --region ${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:
      InstanceType: !Ref InstanceType
      ImageId: !GetAtt
        - AMIInfo
        - Id      
      KeyName: !Ref KeyName
      SecurityGroups:
        - !ImportValue
          'Fn::Sub': '${NetworkStackName}-PrivateSecurityGroup'
      UserData:
        'Fn::Base64': !Sub |
          #!/bin/bash -ex
           yum update -y aws-cfn-bootstrap
          /opt/aws/bin/cfn-init -v --stack ${AWS::StackName} --resource LaunchConfig --configsets All --region ${AWS::Region}
          # Signal the status from cfn-init (via $?)
          /opt/aws/bin/cfn-signal -e $? --stack ${AWS::StackName} --resource ExtAutoScaGrp --region ${AWS::Region}
  AMIInfo:
    Type: 'Custom::AMIInfo'
    Properties:
      ServiceToken: !GetAtt
        - AMIInfoFunction
        - Arn
      Region: !Ref 'AWS::Region'
      Architecture: !FindInMap [ AWSInstanceType2Arch, !Ref InstanceType, Arch ]
  AMIInfoFunction:
    Type: 'AWS::Lambda::Function'
    Properties:
      Code:
        S3Bucket: !Ref S3Bucket
        S3Key: !Ref S3Key
      Handler: !Join
        - ''
        - - !Ref ModuleName
          - .handler
      Role: !GetAtt     
        - LambdaExecutionRole
        - Arn
      Runtime: nodejs8.10
      Timeout: '30'  
  LambdaExecutionRole:
    Type: 'AWS::IAM::Role'
    Properties:
      AssumeRolePolicyDocument:
        Version: 2012-10-17
        Statement:
          - Effect: Allow
            Principal:
              Service:
                - lambda.amazonaws.com
            Action:
              - 'sts:AssumeRole'
      Path: /
      Policies:
        - PolicyName: root
          PolicyDocument:
            Version: '2012-10-17'
            Statement:
              - Effect: Allow
                Action:
                  - 'logs:CreateLogGroup'
                  - 'logs:CreateLogStream'
                  - 'logs:PutLogEvents'
                Resource: 'arn:aws:logs:*:*:*'
              - Effect: Allow
                Action:
                  - 'ec2:DescribeImages'
                Resource: '*'
Outputs:
  WebsiteURL:
    Description: URL for newly created Webserver stack
    Value: !Join 
      - ''
      - - 'http://'
        - !GetAtt 
          - ExternalALB
          - DNSName