这个是PowerShell创建AWS高可用博客的第三部分,我们来看看后半截工作是怎么完成的。
-
创建EC2-S3的Role,这个Role是分配给EC2虚拟机的,这样他们创建之后自动就有权限访问S3的内容。
-
创建VPC网络
-
创建VPC的2个子网,位于不同的AZ
-
创建Internet网关
-
配置路由表
-
创建并配置EC2的Security Group,确保80和22端口可用
-
创建高可用的MariaDB数据库
-
配置数据库的Security Group,确保3306端口可用
-
创建S3 Bucket 并配置Policy
-
创建CloudFront分布点,绑定S3 Bucket
-
准备WordPress的配置文档
-
准备Virtualhost的配置文档
-
上传配置文档到S3 Bucket中
-
配置Bash Shell脚本,包括LAMP,WordPress,AWS,Crontab和S3同步等等
-
创建EC2虚拟机,指定14步创建的BootStrap命令
-
更新DNS记录,指向该虚拟机
-
确认无误之后生成镜像文件
-
配置ELB
-
更新DNS记录到ELB的地址
-
配置Launch Configuration
-
配置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
|
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
}
}
|
大概几分钟之后 就可以使用了。
下面这一部分代码可有可无,我是为了测试这个模板是否工作。他的主要作用其实就是更新一下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-EC2SecurityGroup
|
where-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
|
最后登录看看,成功
我的脚本目前只是简单的实现了上述的功能,全长大概500行左右,各种异常处理尚未添加。如果有感兴趣的,可以联系我看完整的源代码。