OpsWorksがWindows Serverをサポートしたので、AWS CLIで試してみた
公式ドキュメントの手順を参考にしています。
Getting Started with Windows Stacks
ここでは、
- IISのインストール
- 静的なWebページを配置
を行っています
前提条件
- AdministratorAccessの権限で実行しました。
- 東京リージョンで実行します。(ただし、OpsWorksのエンドポイントはus-east-1のみであるため、aws opsworksコマンドはリージョンを指定して実行しています。)
- VPC、Subnet、SSH Keyは事前に作成したものを使用します。
- Service RoleおよびInstance Profile(IAM Role)を事前に作成します。
- CookbookおよびRecipeを事前にS3へアップロードします。
- IISにアップロードする静的なWebページもS3へアップロードします。
リージョンの指定
export AWS_DEFAULT_REGION="ap-northeast-1"
VPCおよびDefault Subnetの指定
VPC_ID="(vpc_id)"
SUBNET_ID="(subnet_id)"
KEY_PAIR_NAME="OpsWorks-for-Windows"
Service Roleの作成
SERVICE_ROLE_NAME="OpsWorks-for-Windows"
ASSUME_ROLE_POLICY_DOCUMENT="assume-role-policy-document.json"
cat << EOF > ${ASSUME_ROLE_POLICY_DOCUMENT}
{
"Version": "2008-10-17",
"Statement": [
{
"Sid": "",
"Effect": "Allow",
"Principal": {
"Service": "opsworks.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
EOF
aws iam create-role --role-name "${SERVICE_ROLE_NAME}" --assume-role-policy-document file://${ASSUME_ROLE_POLICY_DOCUMENT}
AWS_ACCOUNT_ID="(aws-account)"
SERVICE_POLICY_NAME="opsworks-service-policy"
SERVICE_POLICY_ARN="arn:aws:iam::"${AWS_ACCOUNT_ID}":policy/"${SERVICE_POLICY_NAME}
OPSWORKS_SERVICE_POLICY_DOCUMENT="opsworks-service-policy-document.json"
cat << EOF > ${OPSWORKS_SERVICE_POLICY_DOCUMENT}
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"ec2:*",
"elasticloadbalancing:*",
"rds:*",
"cloudwatch:GetMetricStatistics",
"cloudwatch:DescribeAlarms",
"iam:PassRole"
],
"Resource": "*"
}
]
}
EOF
aws iam create-policy --policy-name "${SERVICE_POLICY_NAME}" --policy-document file://${OPSWORKS_SERVICE_POLICY_DOCUMENT}
aws iam attach-role-policy --role-name "${SERVICE_ROLE_NAME}" --policy-arn ${SERVICE_POLICY_ARN}
Instance Roleの作成
(CokbookおよびRecipeをS3に配置するため、読み取り権限を付与)
INSTANCE_ROLE_NAME="OpsWorks-for-Windows-Instance"
ASSUME_ROLE_POLICY_DOCUMENT_FOR_INSTANCE="assume-role-policy-document-for-instance.json"
cat << EOF > ${ASSUME_ROLE_POLICY_DOCUMENT_FOR_INSTANCE}
{
"Version": "2008-10-17",
"Statement": [
{
"Sid": "",
"Effect": "Allow",
"Principal": {
"Service": "ec2.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
EOF
aws iam create-role --role-name "${INSTANCE_ROLE_NAME}" --assume-role-policy-document file://${ASSUME_ROLE_POLICY_DOCUMENT_FOR_INSTANCE}
AWS_ACCOUNT_ID="(aws-account)"
INSTANCE_POLICY_NAME="opsworks-instance-policy"
INSTANCE_POLICY_ARN="arn:aws:iam::"${AWS_ACCOUNT_ID}":policy/"${INSTANCE_POLICY_NAME}
OPSWORKS_INSTANCE_POLICY_DOCUMENT="opsworks-instance-policy-document.json"
cat << EOF > ${OPSWORKS_INSTANCE_POLICY_DOCUMENT}
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:Get*",
"s3:List*"
],
"Resource": "*"
}
]
}
EOF
aws iam create-policy --policy-name "${INSTANCE_POLICY_NAME}" --policy-document file://${OPSWORKS_INSTANCE_POLICY_DOCUMENT}
aws iam attach-role-policy --role-name "${INSTANCE_ROLE_NAME}" --policy-arn ${INSTANCE_POLICY_ARN}
INSTANCE_PROFILE_NAME="${INSTANCE_ROLE_NAME}"
aws iam create-instance-profile --instance-profile-name ${INSTANCE_PROFILE_NAME}
aws iam add-role-to-instance-profile \
--instance-profile-name ${INSTANCE_PROFILE_NAME} \
--role-name ${INSTANCE_ROLE_NAME}
COOKBOOK
metadata.rb
name "iis-cookbook"
version "0.1.0"
Setup用Recipe
install.rb
powershell_script 'Install IIS' do
code 'Add-WindowsFeature Web-Server'
not_if "(Get-WindowsFeature -Name Web-Server).Installed"
end
service 'w3svc' do
action [:start, :enable]
end
Deploy用Recipes
deploy.rb
chef_gem "aws-sdk" do
compile_time false
action :install
end
ruby_block "download-object" do
block do
require 'aws-sdk'
#1
Aws.config[:ssl_ca_bundle] = 'C:\ProgramData\Git\bin\curl-ca-bundle.crt'
#2
query = Chef::Search::Query.new
app = query.search(:aws_opsworks_app, "type:other").first
s3region = app[0][:environment][:S3REGION]
s3bucket = app[0][:environment][:BUCKET]
s3filename = app[0][:environment][:FILENAME]
#3
s3_client = Aws::S3::Client.new(region: s3region)
s3_client.get_object(bucket: s3bucket,
key: s3filename,
response_target: 'C:\inetpub\wwwroot\default.htm')
end
action :run
end
静的なWebページ(default.htm)
<!DOCTYPE html>
<html>
<head>
<title>IIS Example</title>
</head>
<body>
<h1>Hello World!</h1>
</body>
</html>
Stackの作成
STACK_NAME="WindowsStack"
DEFAULT_OS="Microsoft Windows Server 2012 R2 Base"
SERVICE_ROLE_ARN="arn:aws:iam::"${AWS_ACCOUNT_ID}":role/"${SERVICE_ROLE_NAME}
DEFAULT_ROOT_DEVICE_TYPE="ebs"
INSTANCE_PROFILE_ARN="arn:aws:iam::"${AWS_ACCOUNT_ID}":instance-profile/"${INSTANCE_PROFILE_NAME}
CUSTOM_COOKBOOKS_SOURCE="opsworks-custom-coockbooks-source.json"
cat << EOF > ${CUSTOM_COOKBOOKS_SOURCE}
{
"Type": "s3",
"Url": "https://s3-ap-northeast-1.amazonaws.com/opsworks-${AWS_ACCOUNT_ID}-cookbook/iis-cookbook.zip"
}
EOF
CONFIGURATION_MANAGER="configuration-manager.json"
cat << EOF > ${CONFIGURATION_MANAGER}
{
"Name": "Chef",
"Version": "12.2"
}
EOF
aws opsworks create-stack \
--name "${STACK_NAME}" \
--stack-region ${AWS_DEFAULT_REGION} \
--service-role-arn ${SERVICE_ROLE_ARN} \
--default-instance-profile-arn ${INSTANCE_PROFILE_ARN} \
--vpc-id ${VPC_ID} \
--default-os "${DEFAULT_OS}" \
--default-subnet-id ${SUBNET_ID} \
--configuration-manager file://${CONFIGURATION_MANAGER} \
--use-custom-cookbooks \
--custom-cookbooks-source file://${CUSTOM_COOKBOOKS_SOURCE} \
--use-opsworks-security-groups \
--default-ssh-key-name "${KEY_PAIR_NAME}" \
--default-root-device-type "${DEFAULT_ROOT_DEVICE_TYPE}" \
--region "us-east-1"
Security Groupの変更
自動的に作成されるSecurity Group AWS-OpsWorks-RDP-Server にRDPでアクセスできる権限を付与します。
(スクリプトは割愛)
ユーザの作成
MANAGER_USER_NAME="ops-mngr"
MANAGER_USER_PASSWORD="**********"
MANAGER_USER_POLICY_ARN="arn:aws:iam::aws:policy/service-role/AWSOpsWorksRole"
aws iam create-user --user-name ${MANAGER_USER_NAME}
aws iam create-login-profile \
--user-name ${MANAGER_USER_NAME} \
--password ${MANAGER_USER_PASSWORD} \
--no-password-reset-required
aws iam attach-user-policy --user-name ${MANAGER_USER_NAME} --policy-arn ${MANAGER_USER_POLICY_ARN}
IAMユーザへの権限の付与
STACK_ID="********-****-****-****-************"
MANAGER_USER_ARN="arn:aws:iam::${AWS_ACCOUNT_ID}:user/${MANAGER_USER_NAME}"
PERMISSION_LEVEL="iam_only"
aws opsworks create-user-profile --iam-user-arn ${MANAGER_USER_ARN} --region "us-east-1"
aws opsworks set-permission \
--stack-id ${STACK_ID} \
--iam-user-arn ${MANAGER_USER_ARN} \
--allow-ssh \
--allow-sudo \
--level ${PERMISSION_LEVEL} \
--region "us-east-1"
Layerの作成
LAYER_TYPE="custom"
LAYER_NAME="IISExample"
LAYER_SHORTNAME="iisexample"
CUSTOM_RECIPES="custom-recipes.json"
cat << EOF > ${CUSTOM_RECIPES}
{
"Setup": ["iis-cookbook::install"],
"Deploy": ["iis-cookbook::deploy"]
}
EOF
aws opsworks create-layer \
--stack-id ${STACK_ID} \
--type ${LAYER_TYPE} \
--name "${LAYER_NAME}" \
--shortname "${LAYER_SHORTNAME}" \
--custom-recipes file://${CUSTOM_RECIPES} \
--region "us-east-1"
Instanceの作成
LAYER_ID="********-****-****-****-************"
INSTANCE_TYPE="m3.large"
aws opsworks create-instance \
--stack-id ${STACK_ID} \
--layer-ids ${LAYER_ID} \
--instance-type ${INSTANCE_TYPE} \
--region "us-east-1"
Appsの作成
APPS_NAME="IIS-Example-App"
TYPE="other"
APP_SOURCE="OpsWorks-app-source.json"
cat << EOF > ${APP_SOURCE}
{
"Type": "other"
}
EOF
ENVIRONMENT_VARIABLES="Environment-Variables.json"
cat << EOF > ${ENVIRONMENT_VARIABLES}
[
{
"Key": "S3REGION",
"Value": "ap-northeast-1",
"Secure": false
},
{
"Key": "BUCKET",
"Value": "opsworks-${AWS_ACCOUNT_ID}-cookbook",
"Secure": false
},
{
"Key": "FILENAME",
"Value": "iis-application/default.htm",
"Secure": false
}
]
EOF
aws opsworks create-app \
--stack-id ${STACK_ID} \
--name ${APPS_NAME} \
--type ${TYPE} \
--app-source file://${APP_SOURCE} \
--environment file://${ENVIRONMENT_VARIABLES} \
--region "us-east-1"
(動作確認)Instanceの起動
INSTANCE_ID="********-****-****-****-************"
aws opsworks start-instance --instance-id ${INSTANCE_ID} --region "us-east-1"
aws opsworks stop-instance --instance-id ${INSTANCE_ID} --region "us-east-1"
Public DNSにブラウザでアクセスして、Hello Worldできたら成功です。
また、Management Consoleにssh(rdp)を許可したIAMユーザでログインし、RDPでログインするためのパスワードを発行することが可能です。
(正常にログインできるようになるまで、数分かかるようです。)