Powershell AWS 自动化管理 (12) - 创建一个高可用的WordPress博客(下)

这个是PowerShell创建AWS高可用博客的第三部分,我们来看看后半截工作是怎么完成的。


  1. 创建EC2-S3的Role,这个Role是分配给EC2虚拟机的,这样他们创建之后自动就有权限访问S3的内容。

  2. 创建VPC网络

  3. 创建VPC的2个子网,位于不同的AZ

  4. 创建Internet网关

  5. 配置路由表

  6. 创建并配置EC2的Security Group,确保80和22端口可用

  7. 创建高可用的MariaDB数据库

  8. 配置数据库的Security Group,确保3306端口可用

  9. 创建S3 Bucket 并配置Policy

  10. 创建CloudFront分布点,绑定S3 Bucket

  11. 准备WordPress的配置文档

  12. 准备Virtualhost的配置文档

  13. 上传配置文档到S3 Bucket中

  14. 配置Bash Shell脚本,包括LAMP,WordPress,AWS,Crontab和S3同步等等

  15. 创建EC2虚拟机,指定14步创建的BootStrap命令

  16. 更新DNS记录,指向该虚拟机

  17. 确认无误之后生成镜像文件

  18. 配置ELB

  19. 更新DNS记录到ELB的地址

  20. 配置Launch Configuration

  21. 配置Auto Scaling



11. 首先来准备WordPress的配置文档。


下载WordPress 保存在对应的目录, 然后就可以修改wp-config.php的内容来绑定数据库了

1
2
3
4
5
6
7
$content=get-content C:\Users\yli\Downloads\wordpress-4.5.3\wordpress\wp-config-sample.php
$content.Replace("define('DB_NAME', 'database_name_here')","define('DB_NAME', 'wordpress')").`
Replace("define('DB_USER', 'username_here')","define('DB_USER', 'wordpress')").`
Replace("define('DB_PASSWORD', 'password_here')","define('DB_PASSWORD', 'wordpress')").`
Replace("define('DB_HOST', 'localhost')","define('DB_HOST', '$adddress')") |
set-content C:\Users\yli\Downloads\wordpress-4.5.3\wordpress\wp-config.php
gc C:\Users\yli\Downloads\wordpress-4.5.3\wordpress\wp-config.php


12 接下来,需要配置apache的vhost文件,这里我指定了根目录,域名,已经很重要的一点,重定向本地图片路径到S3上去。


1
2
3
4
5
6
7
8
9
10
11
12
13
14
$vhost=@"
<VirtualHost *:80>
        
        ServerName blog.beanxyz.com
ServerAdmin webmaster@localhost
        DocumentRoot /var/www/wordpress
        ErrorLog ${APACHE_LOG_DIR}/error.log
        CustomLog ${APACHE_LOG_DIR}/access.log combined
        RewriteEngine on
        Rewritecond %{HTTP_HOST} !^$
        RewriteRule ^/wp-content/uploads(.*)$ http://$($cfd.domainname)/uploads$1 [R=302]
</VirtualHost>
"@
$vhost Set-Content C:\Users\yli\Downloads\wordpress-4.5.3\wordpress.conf


13. 最后上传到我到S3 Bucket中

1
2
3
Write-S3Object -BucketName yuanliwordpress -Folder C:\Users\yli\Downloads\wordpress-4.5.3\wordpress -KeyPrefix wordpress -Recurse
Write-S3Object -BucketName yuanliwordpress -Key wordpress_vhosts -File C:\users\yli\Downloads\wordpress-4.5.3\wordpress.conf
Get-S3Object -BucketName yuanliwordpress

Powershell AWS 自动化管理 (12) - 创建一个高可用的WordPress博客(下)


14-15 这2步是最麻烦的,我需要绑定Role,安装LAMP和WordPress的脚本,还得自动从S3拷贝配置文件,配置计划任务,每分钟同步一次,以及重定向。Shell脚本处理好以后,就可以生成一个EC2的实例了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
#Create AMI Image
#创建EC2实例
#绑定Role
New-IAMInstanceProfile -InstanceProfileName "WordPress" 
Add-IAMRoleToInstanceProfile -RoleName EC2-S3 -InstanceProfileName "WordPress"
$groupid=Get-EC2SecurityGroup Where-Object {$_.GroupName -eq "WordPress"} | select -ExpandProperty groupid
#配置LAMP和WordPress
$userdata=@"
#!/bin/bash
apt-get update
apt-get upgrade -y
apt-get install -y mysql-client libmysqlclient15-dev apache2 apache2-doc apache2-mpm-prefork apache2-utils libexpat1 ssl-cert libapache2-mod-php5 php5 php5-common php5-curl php5-dev php5-gd php5-idn php-pear php5-imagick php5-mcrypt php5-mysql php5-ps php5-pspell php5-recode php5-xsl python-pip && pip install awscli
aws s3 cp --recursive s3://yuanliwordpress/wordpress /var/www/wordpress/
chown -R www-data.www-data wordpress
chmod 755 /var/www/wordpress/
aws s3 cp s3://yuanliwordpress/wordpress_vhosts /etc/apache2/sites-available/wordpress.conf
cd /etc/apache2/sites-avaiable
a2ensite wordpress.conf
service apache2 restart
chmod 777 /var/www/wordpress/wp-contents
echo */1 * * * * root aws s3 sync /var/www/wordpress/wp-content/uploads s3://yuanliwordpress/uploads >> /etc/crontab
a2enmod rewrite
service apache2 restart
"@
$b=[System.Text.Encoding]::UTF8.GetBytes($userdata)
$a=[System.Convert]::ToBase64String($b)
$instance=New-EC2Instance -ImageId ami-6c14310f -InstanceType t2.micro -KeyName aws -SubnetId $subnet1 -SecurityGroupId $groupid -MinCount 1 -MaxCount 1 -InstanceProfile_Name "WordPress" -UserData $a
$instanceid=($instance| select -expand instances).instanceid
write-host "Initilizing EC2 Instance, Please wait ..." -ForegroundColor Cyan -NoNewline
$state=$false
while($state -eq $false){
  $name= (Get-EC2Instance -InstanceId $instanceid | select -ExpandProperty instances | select -ExpandProperty state).name
  if($name.Value -eq "running"){
  $state=$true
  }else{
   
  start-sleep -Seconds 2
  write-host "..." -ForegroundColor Cyan -NoNewline
  }
}


大概几分钟之后 就可以使用了。

Powershell AWS 自动化管理 (12) - 创建一个高可用的WordPress博客(下)


下面这一部分代码可有可无,我是为了测试这个模板是否工作。他的主要作用其实就是更新一下DNS指向我的模板EC2 的公共IP


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
$publicip=Get-EC2Instance -InstanceId $instanceid | select -ExpandProperty instances | select -ExpandProperty publicipaddress
#更新DNS记录
write-host "Updating DNS Record.." -ForegroundColor Cyan
$domain=Get-R53HostedZonesByName -DNSName beanxyz.com
$hostid=$domain.id.Split("/")[2]
$recordsets=Get-R53ResourceRecordSet -HostedZoneId $domain.id.Split("/")[2] 
$currentip=$recordsets | select -ExpandProperty resourceRecordSets | where-object {$_.name -eq "blog.beanxyz.com."} | select -ExpandProperty ResourceRecords | select -ExpandProperty value
$type=$recordsets | select -ExpandProperty resourceRecordSets | where-object {$_.name -eq "blog.beanxyz.com."} | select -ExpandProperty Type | select -ExpandProperty value
$change1 New-Object Amazon.Route53.Model.Change
$change1.Action = "DELETE"
$change1.ResourceRecordSet = New-Object Amazon.Route53.Model.ResourceRecordSet
$change1.ResourceRecordSet.Name = "blog.beanxyz.com"
$change1.ResourceRecordSet.Type = $type
$change1.ResourceRecordSet.TTL = 300
$change1.ResourceRecordSet.ResourceRecords.Add(@{Value=$currentip})
$change3 New-Object Amazon.Route53.Model.Change
$change3.Action = "CREATE"
$change3.ResourceRecordSet = New-Object Amazon.Route53.Model.ResourceRecordSet
$change3.ResourceRecordSet.Name = "blog.beanxyz.com"
$change3.ResourceRecordSet.Type = "A"
$change3.ResourceRecordSet.TTL = 300
$change3.ResourceRecordSet.ResourceRecords.Add(@{Value=$publicip})
$params = @{
    HostedZoneId=$hostid
ChangeBatch_Comment="Replace a record of blog.beanxyz.com from $currentip to $publicip"
ChangeBatch_Change=$change1,$change3
}
Edit-R53ResourceRecordSet @params 
$tagec2=new-object Amazon.EC2.Model.Tag -Property @{key="Name";value="wordpress"}
New-EC2Tag -Resource $instanceid -Tag $tagec2
write-host "The WordPress blog is ready. Please login to blog.beanxyz.com to finish the inital setup" -ForegroundColor Cyan
start-process http://blog.beanxyz.com


再往下就很容易了,配置镜像


1
2
3
#14.配置AMI镜像
New-EC2Image -Description TemplateWordPress -Name TemplateWordPress -InstanceId $instanceid
Get-EC2Image -Owner self | Unregister-EC2Image -PassThru


配置ELB,更新DNS记录


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#Create ELB and Auto Scaling
#15.配置ELB
#Create ELB
$HTTPListener New-Object -TypeName ‘Amazon.ElasticLoadBalancing.Model.Listener’
$HTTPListener.Protocol = ‘http’
$HTTPListener.InstancePort = 80
$HTTPListener.LoadBalancerPort = 80
$groupid=(Get-EC2SecurityGroupwhere-object {$_.GroupName -eq "wordpress"}).GroupId
$subnet1=(Get-EC2Subnet Where-Object {$_.CidrBlock -eq "10.2.1.0/24"}).SubnetId
$subnet2=(Get-EC2Subnet Where-Object {$_.CidrBlock -eq "10.2.2.0/24"}).SubnetId
$elb=New-ELBLoadBalancer -LoadBalancerName "MyLoadBalance" -Listener $HTTPListener -SecurityGroup $groupid -Subnet @($subnet1,$subnet2
#$elb=Get-ELBLoadBalancer
#Register-ELBInstanceWithLoadBalancer -LoadBalancerName "MyLoadBalance" -Instance @($instance2Id)
#更新DNS到LoadBalancer上
write-host "Updating DNS Record.." -ForegroundColor Cyan
$domain=Get-R53HostedZonesByName -DNSName beanxyz.com
$hostid=$domain.id.Split("/")[2]
$recordsets=Get-R53ResourceRecordSet -HostedZoneId $domain.id.Split("/")[2] 
$currentip=$recordsets | select -ExpandProperty resourceRecordSets | where-object {$_.name -eq "blog.beanxyz.com."} | select -ExpandProperty ResourceRecords | select -ExpandProperty value
$change1 New-Object Amazon.Route53.Model.Change
$change1.Action = "DELETE"
$change1.ResourceRecordSet = New-Object Amazon.Route53.Model.ResourceRecordSet
$change1.ResourceRecordSet.Name = "blog.beanxyz.com"
$change1.ResourceRecordSet.Type = "A"
$change1.ResourceRecordSet.TTL = 300
$change1.ResourceRecordSet.ResourceRecords.Add(@{Value=$currentip})
$change3 New-Object Amazon.Route53.Model.Change
$change3.Action = "CREATE"
$change3.ResourceRecordSet = New-Object Amazon.Route53.Model.ResourceRecordSet
$change3.ResourceRecordSet.Name = "blog.beanxyz.com"
$change3.ResourceRecordSet.Type = "CNAME"
$change3.ResourceRecordSet.TTL = 300
$change3.ResourceRecordSet.ResourceRecords.Add(@{Value=$elb})
$params = @{
    HostedZoneId=$hostid
ChangeBatch_Comment="Replace a record of blog.beanxyz.com from $currentip to $newname"
ChangeBatch_Change=$change1,$change3
}
Edit-R53ResourceRecordSet @params


最后配置Launch config文件和Auto Scaling Group就行了。别忘了配置CloudWatch,这样他可以自动根据负载进行添加或是删除实例

1
2
3
4
5
6
7
8
9
10
11
12
#配置 Launch Configuration- UserData(Bootstrap)
New-ASLaunchConfiguration -ImageId (Get-EC2Image -Owner self).imageid -LaunchConfigurationName "My-launchconfigurationfile" -InstanceType "t2.micro" -SecurityGroup $groupid -UserData $a -KeyName aws
New-ASAutoScalingGroup -AutoScalingGroupName "my-asg" -LaunchConfigurationName "My-launchconfigurationfile" -MinSize 1 -MaxSize 3 -LoadBalancerName "MyLoadBalance" `
-VPCZoneIdentifier $subnet1
Write-ASScalingPolicy -AutoScalingGroupName my-asg -AdjustmentType "ChangeInCapacity" -PolicyName "myScaleInPolicy" -ScalingAdjustment 1 
#Remove-ASAutoScalingGroup -AutoScalingGroupName "my-asg"
$stepadjustment=New-Object Amazon.AutoScaling.Model.StepAdjustment 
$stepadjustment.MetricIntervalLowerBound=20
$stepadjustment.ScalingAdjustment=-1
Write-ASScalingPolicy -AutoScalingGroupName my-asg -AdjustmentType "ChangeInCapacity" -PolicyName "myScaleInPolicy1" -PolicyType "StepScaling" -StepAdjustment $stepadjustment
Write-CWMetricAlarm -ActionsEnabled $true -Alarmname "testonly" -AlarmAction {arn:aws:autoscaling:ap-southeast-2:503646143282:scalingPolicy:fba2d6ec-1566-459a-a3d5-bb800e88f7ad:autoScalingGroupName/my-asg:policyName/myScaleInPolicy1} -Namespace "AWS/EC2" -Period 300 -Statistic "Average" -MetricName "CPUUtlilization" `
-ComparisonOperator "LessThanOrEqualToThreshold" -Threshold 60 -EvaluationPeriod 1
1
2
3
4
5
6
7
$stepadjustment=New-Object Amazon.AutoScaling.Model.StepAdjustment 
$stepadjustment.MetricIntervalLowerBound=20
$stepadjustment.ScalingAdjustment=-1
Write-ASScalingPolicy -AutoScalingGroupName my-asg -AdjustmentType "ChangeInCapacity" -PolicyName "myScaleInPolicy1" -PolicyType "StepScaling" -StepAdjustment $stepadjustment
Write-CWMetricAlarm -ActionsEnabled $true -Alarmname "testonly" -AlarmAction {arn:aws:autoscaling:ap-southeast-2:503646143282:scalingPolicy:4cb293a4-1e6f-4d3e-8c02-2baec06ee663:autoScalingGroupName/my-asg:policyName/myScaleInPolicy1
} -Namespace "AWS/EC2" -Period 300 -Statistic "Average" -MetricName "CPUUtlilization" `
-ComparisonOperator "LessThanOrEqualToThreshold" -Threshold 60 -EvaluationPeriod 1

最后登录看看,成功

Powershell AWS 自动化管理 (12) - 创建一个高可用的WordPress博客(下)



我的脚本目前只是简单的实现了上述的功能,全长大概500行左右,各种异常处理尚未添加。如果有感兴趣的,可以联系我看完整的源代码。






本文转自 beanxyz 51CTO博客,原文链接:http://blog.51cto.com/beanxyz/1828052,如需转载请自行联系原作者

上一篇:Windows Phone 7 使用数据模板DataTemplate进行数据绑定


下一篇:Visual Studio及TFS进行单元测试、负载测试、代码覆盖率、每日构建配置