用于在单个RDS Mysql上创建4个ec2实例上的wordpress的Cloudformation模板

时间:2017-03-12 16:16:56

标签: database wordpress amazon-cloudformation rds elastic-load-balancer

目前我正在编写一个cloudformation模板,该模板在单个RDS MySql实例上的4个实例上安装wordpress。到目前为止,我编写的代码用于在一个单独的ec2实例和RDS实例上的数据库上启动完整的wordpress。我想为3个不同(或同样也会欺骗)数据库的3个实例做这个,但是在同一个单RDS实例上......我该怎么办?这里是启动1 ec2的代码,其上安装了wordpress的1个rds。代码是YAML语言。任何建议???我应该添加一个如何做到这一点...谢谢你。

CLOUDFORMATION TEMPLATE ...

AWSTemplateFormatVersion: "2010-09-09"
Description: "Wordpress: highly available and scalable, a cloudonaut.io     template"
Parameters:
  BlogID:
    Description: "A unique identifier for your blog. For internal use only."
    Type: String
    AllowedPattern: "[A-Za-z0-9\\-]+"
    ConstraintDescription: "Only letters, digits or dash allowed."
  BlogTitle:
    Description: "The title of the Wordpress blog."
    Type: String
    Default: "Just another Wordpress blog"
  BlogAdminUsername:
    Description: "A username for the Wordpress admin."
    Type: String
    Default: "admin"
  BlogAdminPassword:
    Description: "A password for the Wordpress admin."
    Type: String
    NoEcho: "true"
  BlogAdminEMail:
    Description: "The email address of the Wordpress admin."
    Type: String
  WebServerKeyName:
    Description: "The key pair to establish a SSH connection to the web     servers."
    Type: "AWS::EC2::KeyPair::KeyName"
  WebServerInstanceType:
    Description: "The instance type of web servers (e.g. t2.micro)."
    Type: String
    Default: "t2.micro"
  DBServerInstanceType:
    Description: "The instance type of database server (e.g. db.t2.micro)."
    Type: String
    Default: "db.t2.micro"

Mappings:
  EC2RegionMap:
ap-northeast-1: { AmazonLinuxAMIHVMEBSBacked64bit: "ami-cbf90ecb" }
ap-southeast-1: { AmazonLinuxAMIHVMEBSBacked64bit: "ami-68d8e93a" }
ap-southeast-2: { AmazonLinuxAMIHVMEBSBacked64bit: "ami-fd9cecc7" }
eu-central-1: { AmazonLinuxAMIHVMEBSBacked64bit: "ami-a8221fb5" }
eu-west-1: { AmazonLinuxAMIHVMEBSBacked64bit: "ami-a10897d6" }
sa-east-1: { AmazonLinuxAMIHVMEBSBacked64bit: "ami-b52890a8" }
us-east-1: { AmazonLinuxAMIHVMEBSBacked64bit: "ami-1ecae776" }
us-west-1: { AmazonLinuxAMIHVMEBSBacked64bit: "ami-d114f295" }
us-west-2: { AmazonLinuxAMIHVMEBSBacked64bit: "ami-e7527ed7" }

Resources:
  VPC:
Type: "AWS::EC2::VPC"
Properties:
  CidrBlock: "172.31.0.0/16"
  EnableDnsHostnames: "true"

  InternetGateway:
Type: "AWS::EC2::InternetGateway"
Properties: {}

  VPCGatewayAttachment:
Type: "AWS::EC2::VPCGatewayAttachment"
Properties:
  VpcId: {"Ref": "VPC"}
  InternetGatewayId: {"Ref": "InternetGateway"}

  SubnetA:
Type: "AWS::EC2::Subnet"
Properties:
  AvailabilityZone: {"Fn::Select": ["0", {"Fn::GetAZs": ""}]}
  CidrBlock: "172.31.38.0/24"
  VpcId: {"Ref": "VPC"}

  SubnetB:
Type: "AWS::EC2::Subnet"
Properties:
  AvailabilityZone: {"Fn::Select": ["1", {"Fn::GetAZs": ""}]}
  CidrBlock: "172.31.37.0/24"
  VpcId: {"Ref": "VPC"}

  RouteTable:
Type: "AWS::EC2::RouteTable"
Properties:
  VpcId: {"Ref": "VPC"}

  RouteTableAssociationA:
Type: "AWS::EC2::SubnetRouteTableAssociation"
Properties:
  SubnetId: {"Ref": "SubnetA"}
  RouteTableId: {"Ref": "RouteTable"}

  RouteTableAssociationB:
Type: "AWS::EC2::SubnetRouteTableAssociation"
Properties:
  SubnetId: {"Ref": "SubnetB"}
  RouteTableId: {"Ref": "RouteTable"}

  RoutePublicNATToInternet:
Type: "AWS::EC2::Route"
Properties:
  RouteTableId: {"Ref": "RouteTable"}
  DestinationCidrBlock: "0.0.0.0/0"
  GatewayId: {"Ref": "InternetGateway"}
DependsOn: "VPCGatewayAttachment"

  NetworkAcl:
Type: "AWS::EC2::NetworkAcl"
Properties:
  VpcId: {"Ref": "VPC"}

  SubnetNetworkAclAssociationA:
Type: "AWS::EC2::SubnetNetworkAclAssociation"
Properties:
  SubnetId: {"Ref": "SubnetA"}
  NetworkAclId: {"Ref": "NetworkAcl"}

  SubnetNetworkAclAssociationB:
Type: "AWS::EC2::SubnetNetworkAclAssociation"
Properties:
  SubnetId: {"Ref": "SubnetB"}
  NetworkAclId: {"Ref": "NetworkAcl"}

  NetworkAclEntryIngress:
Type: "AWS::EC2::NetworkAclEntry"
Properties:
  NetworkAclId: {"Ref": "NetworkAcl"}
  RuleNumber: "100"
  Protocol: "-1"
  RuleAction: "allow"
  Egress: "false"
  CidrBlock: "0.0.0.0/0"

  NetworkAclEntryEgress:
Type: "AWS::EC2::NetworkAclEntry"
Properties:
  NetworkAclId: {"Ref": "NetworkAcl"}
  RuleNumber: "100"
  Protocol: "-1"
  RuleAction: "allow"
  Egress: "true"
  CidrBlock: "0.0.0.0/0"

  LoadBalancer:
Type: "AWS::ElasticLoadBalancing::LoadBalancer"
Properties:
  Subnets: [{"Ref": "SubnetA"}, {"Ref": "SubnetB"}]
  LoadBalancerName: {"Ref": "BlogID"}
  Listeners:
    - InstancePort: "80"
      InstanceProtocol: "HTTP"
      LoadBalancerPort: "80"
      Protocol: "HTTP"
  HealthCheck:
    HealthyThreshold: "2"
    Interval: "5"
    Target: "TCP:80"
    Timeout: "3"
    UnhealthyThreshold: "2"
  SecurityGroups: [{"Ref": "LoadBalancerSecurityGroup"}]
  Scheme: "internet-facing"
  CrossZone: "true"

  LoadBalancerSecurityGroup:
Type: "AWS::EC2::SecurityGroup"
Properties:
  GroupDescription: "wordpress-elb"
  VpcId: {"Ref": "VPC"}
  SecurityGroupIngress:
    - CidrIp: "0.0.0.0/0"
      FromPort: 80
      IpProtocol: "tcp"
      ToPort: 80

  WebServerSecurityGroup:
Type: "AWS::EC2::SecurityGroup"
Properties:
  GroupDescription: "wordpress-ec2"
  VpcId: {"Ref": "VPC"}
  SecurityGroupIngress:
    - CidrIp: "0.0.0.0/0"
      FromPort: 22
      IpProtocol: "tcp"
      ToPort: 22

    - FromPort: 80
      IpProtocol: "tcp"
      SourceSecurityGroupId: {"Ref": "LoadBalancerSecurityGroup"}
      ToPort: 80

  DatabaseSecurityGroup:
Type: "AWS::EC2::SecurityGroup"
Properties:
  GroupDescription: "wordpress-rds"
  VpcId: {"Ref": "VPC"}
  SecurityGroupIngress:
    - IpProtocol: "tcp"
      FromPort: "3306"
      ToPort: "3306"
      SourceSecurityGroupId: {"Ref": "WebServerSecurityGroup"}

  Database:
Type: "AWS::RDS::DBInstance"
Properties:
  AllocatedStorage: "5"
  BackupRetentionPeriod: "0"
  DBInstanceClass: {"Ref": "DBServerInstanceType"}
  DBInstanceIdentifier: {"Ref": "BlogID"}
  DBName: "wordpress"
  Engine: "MySQL"
  MasterUsername: "wordpress"
  MasterUserPassword: "wordpress"
  VPCSecurityGroups: [{"Fn::GetAtt": ["DatabaseSecurityGroup", "GroupId"]}]
  DBSubnetGroupName: {"Ref": "DBSubnetGroup"}
  MultiAZ: "true"
  StorageType: "gp2"

  DBSubnetGroup:
Type: "AWS::RDS::DBSubnetGroup"
Properties:
  DBSubnetGroupDescription: "DB subnet group"
  SubnetIds: [{"Ref": "SubnetA"}, {"Ref": "SubnetB"}]

  S3Bucket:
Type: "AWS::S3::Bucket"
Properties:
  BucketName: {"Ref": "BlogID"}

  IAMUser:
Type: "AWS::IAM::User"
Properties:
  Path: "/"
  Policies:
    - PolicyName: "UploadToS3"
      PolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: "Allow"
            Action: ["s3:*"]
            Resource:
              - {"Fn::Join": ["", ["arn:aws:s3:::", {"Ref": "BlogID"}     ,"/*"]]}

  IAMAccessKey:
Type: "AWS::IAM::AccessKey"
Properties:
  UserName: {"Ref": "IAMUser"}

  LaunchConfiguration:
Type: "AWS::AutoScaling::LaunchConfiguration"
Metadata:
  "AWS::CloudFormation::Init":
    config:
      packages:
        yum:
          "php": []
          "php-mysql": []
          "mysql": []
          "httpd": []
      sources: {"/var/www/html": "https://wordpress.org/wordpress-4.2.4.tar.gz"}
      files:
        "/root/config.sh":
          content:
            "Fn::Join":
              - ""
              - [
                  "#!/bin/bash -ex\n",
                  "cp wp-config-sample.php wp-config.php\n",
                  "sed -i \"s/'database_name_here'/'wordpress'/g\" wp-config.php\n",
                  "sed -i \"s/'username_here'/'wordpress'/g\" wp-config.php\n",
                  "sed -i \"s/'password_here'/'wordpress'/g\" wp-config.php\n",
                  "sed -i \"s/'localhost'/'", {"Fn::GetAtt": ["Database", "Endpoint.Address"]}, "'/g\" wp-config.php\n",
                  "echo \"define('AWS_ACCESS_KEY_ID', '", {"Ref": "IAMAccessKey"},"'); \" >> wp-config.php \n",
                  "echo \"define('AWS_SECRET_ACCESS_KEY', '", {"Fn::GetAtt": ["IAMAccessKey", "SecretAccessKey"]},"'); \" >> wp-config.php \n",
                  "echo \"define( 'DISALLOW_FILE_MODS', true ); \" >> wp-config.php \n",
                  "echo \"define( 'WP_AUTO_UPDATE_CORE', false ); \" >> wp-config.php \n",
                  "chmod -R 777 wp-content/ \n",
                  "curl -O https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar \n",
                  "php wp-cli.phar core install --url=\"", {"Fn::GetAtt": ["LoadBalancer", "DNSName"]}, "\" --title=\"", {"Ref": "BlogTitle"}, "\" --admin_user=\"", {"Ref": "BlogAdminUsername"}, "\" --admin_password=\"", {"Ref": "BlogAdminPassword"}, "\" --admin_email=\"", {"Ref": "BlogAdminEMail"}, "\" \n",
                  "php wp-cli.phar plugin install --activate amazon-web-services \n",
                  "php wp-cli.phar plugin install --activate amazon-s3-and-cloudfront \n",
                  "CHARCOUNT=`printf \"",{"Ref": "BlogID"} ,"\" | wc -c` \n",
                  "php wp-cli.phar db query \"DELETE FROM wp_options WHERE option_name = 'tantan_wordpress_s3'; INSERT INTO wp_options (option_name, option_value, autoload) VALUES('tantan_wordpress_s3', 'a:15:{s:17:\\\"post_meta_version\\\";i:1;s:6:\\\"bucket\\\";s:", "$CHARCOUNT", ":\\\"", {"Ref": "BlogID"},"\\\";s:6:\\\"region\\\";s:0:\\\"\\\";s:6:\\\"domain\\\";s:9:\\\"subdomain\\\";s:7:\\\"expires\\\";s:1:\\\"0\\\";s:10:\\\"cloudfront\\\";s:0:\\\"\\\";s:13:\\\"object-prefix\\\";s:19:\\\"wp-content/uploads/\\\";s:10:\\\"copy-to-s3\\\";s:1:\\\"1\\\";s:13:\\\"serve-from-s3\\\";s:1:\\\"1\\\";s:17:\\\"remove-local-file\\\";s:1:\\\"0\\\";s:3:\\\"ssl\\\";s:7:\\\"request\\\";s:12:\\\"hidpi-images\\\";s:1:\\\"0\\\";s:17:\\\"object-versioning\\\";s:1:\\\"0\\\";s:21:\\\"use-yearmonth-folders\\\";s:1:\\\"1\\\";s:20:\\\"enable-object-prefix\\\";s:1:\\\"1\\\";}', 'yes');\" \n"
                ]
          mode: "000500"
          owner: "root"
          group: "root"

      commands:
        01_mv:
          command: "mv * ../"
          cwd: "/var/www/html/wordpress"
        02_config:
          command: "/root/config.sh"
          cwd: "/var/www/html"

      services:
        sysvinit:
          httpd:
            enabled: "true"
            ensureRunning: "true"

    Properties:
  ImageId: {"Fn::FindInMap": ["EC2RegionMap", {"Ref": "AWS::Region"}, "AmazonLinuxAMIHVMEBSBacked64bit"]}
  InstanceType: {"Ref": "WebServerInstanceType"}
  SecurityGroups: [{"Ref": "WebServerSecurityGroup"}]
  KeyName: {"Ref": "WebServerKeyName"}
  AssociatePublicIpAddress: "true"
  UserData:
    "Fn::Base64":
      "Fn::Join":
        - ""
        - [
            "#!/bin/bash -ex\n",
            "yum update -y aws-cfn-bootstrap\n",
            "/opt/aws/bin/cfn-init -v --stack ", {"Ref": "AWS::StackName"}, " --resource LaunchConfiguration --region ", {"Ref": "AWS::Region"}, "\n",
            "/opt/aws/bin/cfn-signal -e $? --stack ", {"Ref": "AWS::StackName"}, " --resource AutoScalingGroup --region ", {"Ref": "AWS::Region"}, "\n"
          ]
  InstanceMonitoring: "true"

  AutoScalingGroup:
Type: "AWS::AutoScaling::AutoScalingGroup"
Properties:
  LoadBalancerNames: [{"Ref": "LoadBalancer"}]
  LaunchConfigurationName: {"Ref": "LaunchConfiguration"}
  MinSize: "2"
  MaxSize: "4"
  DesiredCapacity: "2"
  Cooldown: "60"
  HealthCheckGracePeriod: "120"
  HealthCheckType: "ELB"
  VPCZoneIdentifier: [{"Ref": "SubnetA"}, {"Ref": "SubnetB"}]
  Tags:
    - PropagateAtLaunch: "true"
      Value: "wordpress"
      Key: "Name"
CreationPolicy:
  ResourceSignal:
    Timeout: "PT10M"

  ScalingUpPolicy:
Type: "AWS::AutoScaling::ScalingPolicy"
Properties:
  AdjustmentType: "PercentChangeInCapacity"
  MinAdjustmentStep: "1"
  AutoScalingGroupName: {"Ref": "AutoScalingGroup"}
  Cooldown: "300"
  ScalingAdjustment: "25"

  CPUHighAlarm:
Type: "AWS::CloudWatch::Alarm"
Properties:
  EvaluationPeriods: "1"
  Statistic: "Average"
  Threshold: "75"
  AlarmDescription: "Alarm if CPU load is high."
  Period: "60"
  AlarmActions: [{"Ref": "ScalingUpPolicy"}]
  Namespace: "AWS/EC2"
  Dimensions:
    - Name: "AutoScalingGroupName"
      Value: {"Ref": "AutoScalingGroup"}
  ComparisonOperator: "GreaterThanThreshold"
  MetricName: "CPUUtilization"

  ScalingDownPolicy:
Type: "AWS::AutoScaling::ScalingPolicy"
Properties:
  AdjustmentType: "PercentChangeInCapacity"
  MinAdjustmentStep: "1"
  AutoScalingGroupName: {"Ref": "AutoScalingGroup"}
  Cooldown: "300"
  ScalingAdjustment: "-25"

  CPULowAlarm:
Type: "AWS::CloudWatch::Alarm"
Properties:
  EvaluationPeriods: "1"
  Statistic: "Average"
  Threshold: "25"
  AlarmDescription: "Alarm if CPU load is low."
  Period: "60"
  AlarmActions: [{"Ref": "ScalingDownPolicy"}]
  Namespace: "AWS/EC2"
  Dimensions:
    - Name: "AutoScalingGroupName"
      Value: {"Ref": "AutoScalingGroup"}
  ComparisonOperator: "LessThanThreshold"
  MetricName: "CPUUtilization"


Outputs:
  URL:
   Value: {"Fn::Join": ["", ["http://", {"Fn::GetAtt": ["LoadBalancer", "DNSName"]}]]}
    Description: "URL to Wordpress"

1 个答案:

答案 0 :(得分:0)

您提供的模板(似乎来自cloudonaut)不会创建单个EC2实例,它会创建一个包含2-4个EC2实例的Auto Scaling组,以便提供高可用性和基于负载的扩展到Wordpress安装。

对于您需要的每个新Wordpress安装,您需要复制以下资源一次(例如,应使用LoadBalancerLoadBalancer2等新名称复制名为LoadBalancer3的资源。 ):

  • LoadBalancer
  • LaunchConfiguration
  • AutoScalingGroup
  • ScalingUpPolicy
  • CPUHighAlarm
  • ScalingDownPolicy
  • CPULowAlarm

您还需要在每个更新的LaunchConfiguration用户数据脚本中将对数据库的引用从wordpress更改为wordpress2wordpress3等,如下所示:

"sed -i \"s/'database_name_here'/'wordpress'/g\" wp-config.php\n",

这应该会为您提供一个工作模板,尽管它会在每个安装的资源上进行大量重复。您可以将重复的资源重构为嵌套堆栈,您可以在每个实例中重复使用,通过堆栈输出传递数据库引用,等等。