はじめに
AWS Storage GatewayのファイルゲートウェイをVPCエンドポイントを利用したVPC閉塞環境を、CLIで構築する手順です。この手順ではNFS接続、SMB(ゲスト接続)、SMB(ActiveDirectory認証)の構成を作成します。またキャッシュリフレッシュ、ソフトウェアップデート、およびリフレッシュ完了やS3アップロード完了のCloud Watch Event連携のセットアップ手順も整理しています。
作成手順
(1)事前設定
(1)-(a) 作業環境の準備
作業環境として、下記を準備します。
(1)-(b) CLI実行用の事前準備
これ以降のAWS-CLIで共通で利用するパラメータを環境変数で設定しておきます。
export PROFILE=<設定したプロファイル名称を指定。デフォルトの場合はdefaultを設定>
export REGION=ap-northeast-1
IGWでインターネットアクセス可能で、パブリックアクセス可能なサブネットx2、プライベートなサブネットx2の合計4つのサブネットを所有するVPCを作成します。
(2)-(a)テンプレートのダウンロード
私が作成し利用しているVPC作成用のCloudFormationテンプレートを利用します。まず、githubからテンプレートをダウンロードします。
curl -o vpc-4subnets.yaml https://raw.githubusercontent.com/Noppy/CfnCreatingVPC/master/vpc-4subnets.yaml
(2)-(b)VPC作成
ダウンロードしたテンプレートを利用し、VPCをデプロイします。
CFN_STACK_PARAMETERS='
[
{
"ParameterKey": "DnsHostnames",
"ParameterValue": "true"
},
{
"ParameterKey": "DnsSupport",
"ParameterValue": "true"
},
{
"ParameterKey": "InternetAccess",
"ParameterValue": "true"
},
{
"ParameterKey": "EnableNatGW",
"ParameterValue": "false"
},
{
"ParameterKey": "VpcName",
"ParameterValue": "StorageGWPoCVPC"
},
{
"ParameterKey": "VpcInternalDnsName",
"ParameterValue": "sgwpoc.local."
}
]'
aws --profile ${PROFILE} cloudformation create-stack \
--stack-name SGWPoC-VPC \
--template-body "file://./vpc-4subnets.yaml" \
--parameters "${CFN_STACK_PARAMETERS}" \
--capabilities CAPABILITY_IAM ;
(3) VPCEndpoint設定
必要となるVPC Endpointを作成します。この手順ではエンドポイントポリシーは設定してません。必有れば追加設定してください。
(3)-(a) 構成情報取得
VPCID=$(aws --profile ${PROFILE} --output text \
cloudformation describe-stacks \
--stack-name SGWPoC-VPC \
--query 'Stacks[].Outputs[?OutputKey==`VpcId`].[OutputValue]')
VPC_CIDR=$(aws --profile ${PROFILE} --output text \
cloudformation describe-stacks \
--stack-name SGWPoC-VPC \
--query 'Stacks[].Outputs[?OutputKey==`VpcCidr`].[OutputValue]')
PublicSubnet1Id=$(aws --profile ${PROFILE} --output text \
cloudformation describe-stacks \
--stack-name SGWPoC-VPC \
--query 'Stacks[].Outputs[?OutputKey==`PublicSubnet1Id`].[OutputValue]')
PublicSubnet2Id=$(aws --profile ${PROFILE} --output text \
cloudformation describe-stacks \
--stack-name SGWPoC-VPC \
--query 'Stacks[].Outputs[?OutputKey==`PublicSubnet2Id`].[OutputValue]')
PrivateSubnet1Id=$(aws --profile ${PROFILE} --output text \
cloudformation describe-stacks \
--stack-name SGWPoC-VPC \
--query 'Stacks[].Outputs[?OutputKey==`PrivateSubnet1Id`].[OutputValue]')
PrivateSubnet2Id=$(aws --profile ${PROFILE} --output text \
cloudformation describe-stacks \
--stack-name SGWPoC-VPC \
--query 'Stacks[].Outputs[?OutputKey==`PrivateSubnet2Id`].[OutputValue]')
PrivateSubnet1RouteTableId=$(aws --profile ${PROFILE} --output text \
cloudformation describe-stacks \
--stack-name SGWPoC-VPC \
--query 'Stacks[].Outputs[?OutputKey==`PrivateSubnet1RouteTableId`].[OutputValue]')
PrivateSubnet2RouteTableId=$(aws --profile ${PROFILE} --output text \
cloudformation describe-stacks \
--stack-name SGWPoC-VPC \
--query 'Stacks[].Outputs[?OutputKey==`PrivateSubnet2RouteTableId`].[OutputValue]')
echo -e "VPCID=$VPCID\nVPC_CIDR=$VPC_CIDR\nPublicSubnet1Id =$PublicSubnet1Id\nPublicSubnet2Id =$PublicSubnet2Id\nPrivateSubnet1Id=$PrivateSubnet1Id\nPrivateSubnet2Id=$PrivateSubnet2Id\nPrivateSubnet1RouteTableId=$PrivateSubnet1RouteTableId \nPrivateSubnet2RouteTableId=$PrivateSubnet2RouteTableId"
(3)-(b) VPC: VPCEndpointの作成
VPCENDPOINT_SG_ID=$(aws --profile ${PROFILE} --output text \
ec2 create-security-group \
--group-name VpcEndpointSG \
--description "Allow https" \
--vpc-id ${VPCID}) ;
aws --profile ${PROFILE} \
ec2 create-tags \
--resources ${VPCENDPOINT_SG_ID} \
--tags "Key=Name,Value=VpcEndpointSG" ;
aws --profile ${PROFILE} \
ec2 authorize-security-group-ingress \
--group-id ${VPCENDPOINT_SG_ID} \
--protocol tcp \
--port 443 \
--cidr ${VPC_CIDR} ;
VPCENDPOINT_STORAGEGW_SG_ID=$(aws --profile ${PROFILE} --output text \
ec2 create-security-group \
--group-name SGW-VpcEndpointSG \
--description "Allow https" \
--vpc-id ${VPCID}) ;
aws --profile ${PROFILE} \
ec2 create-tags \
--resources ${VPCENDPOINT_STORAGEGW_SG_ID} \
--tags "Key=Name,Value=SGW-VpcEndpointSG" ;
aws --profile ${PROFILE} \
ec2 authorize-security-group-ingress \
--group-id ${VPCENDPOINT_STORAGEGW_SG_ID} \
--protocol tcp \
--port 443 \
--cidr ${VPC_CIDR} ;
aws --profile ${PROFILE} \
ec2 authorize-security-group-ingress \
--group-id ${VPCENDPOINT_STORAGEGW_SG_ID} \
--protocol tcp \
--port 1026-1028 \
--cidr ${VPC_CIDR} ;
aws --profile ${PROFILE} \
ec2 authorize-security-group-ingress \
--group-id ${VPCENDPOINT_STORAGEGW_SG_ID} \
--protocol tcp \
--port 1031 \
--cidr ${VPC_CIDR} ;
aws --profile ${PROFILE} \
ec2 authorize-security-group-ingress \
--group-id ${VPCENDPOINT_STORAGEGW_SG_ID} \
--protocol tcp \
--port 2222 \
--cidr ${VPC_CIDR} ;
aws --profile ${PROFILE} \
ec2 create-vpc-endpoint \
--vpc-id ${VPCID} \
--service-name com.amazonaws.${REGION}.s3 \
--route-table-ids ${PrivateSubnet1RouteTableId} ${PrivateSubnet2RouteTableId}
aws --profile ${PROFILE} \
ec2 create-vpc-endpoint \
--vpc-id ${VPCID} \
--vpc-endpoint-type Interface \
--service-name com.amazonaws.${REGION}.storagegateway \
--subnet-id ${PrivateSubnet1Id} ${PrivateSubnet2Id} \
--security-group-id ${VPCENDPOINT_STORAGEGW_SG_ID} ;
aws --profile ${PROFILE} \
ec2 create-vpc-endpoint \
--vpc-id ${VPCID} \
--vpc-endpoint-type Interface \
--service-name com.amazonaws.${REGION}.ssm \
--subnet-id ${PrivateSubnet1Id} ${PrivateSubnet2Id} \
--security-group-id ${VPCENDPOINT_SG_ID} ;
aws --profile ${PROFILE} \
ec2 create-vpc-endpoint \
--vpc-id ${VPCID} \
--vpc-endpoint-type Interface \
--service-name com.amazonaws.${REGION}.ec2messages \
--subnet-id ${PrivateSubnet1Id} ${PrivateSubnet2Id} \
--security-group-id ${VPCENDPOINT_SG_ID} ;
aws --profile ${PROFILE} \
ec2 create-vpc-endpoint \
--vpc-id ${VPCID} \
--vpc-endpoint-type Interface \
--service-name com.amazonaws.${REGION}.ssmmessages \
--subnet-id ${PrivateSubnet1Id} ${PrivateSubnet2Id} \
--security-group-id ${VPCENDPOINT_SG_ID} ;
(4) Storage Gateway管理用のIAMロール(管理サーバ用)作成
(4)-(a) IAMロール作成
POLICY='{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "",
"Effect": "Allow",
"Principal": {
"Service": "ec2.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}'
aws --profile ${PROFILE} \
iam create-role \
--role-name "Ec2-StorageGW-AdminRole" \
--assume-role-policy-document "${POLICY}" \
--max-session-duration 43200
aws --profile ${PROFILE} \
iam attach-role-policy \
--role-name "Ec2-StorageGW-AdminRole" \
--policy-arn arn:aws:iam::aws:policy/AWSStorageGatewayFullAccess
aws --profile ${PROFILE} \
iam attach-role-policy \
--role-name "Ec2-StorageGW-AdminRole" \
--policy-arn arn:aws:iam::aws:policy/CloudWatchLogsFullAccess
aws --profile ${PROFILE} \
iam attach-role-policy \
--role-name "Ec2-StorageGW-AdminRole" \
--policy-arn arn:aws:iam::aws:policy/ReadOnlyAccess
aws --profile ${PROFILE} \
iam create-instance-profile \
--instance-profile-name "Ec2-StorageGW-AdminRole-Profile";
aws --profile ${PROFILE} \
iam add-role-to-instance-profile \
--instance-profile-name "Ec2-StorageGW-AdminRole-Profile" \
--role-name "Ec2-StorageGW-AdminRole" ;
(5)-(a) セキュリティーグループ作成(Bastion)
(i) Client - SSHログイン用 Security Group
SSH_SG_ID=$(aws --profile ${PROFILE} --output text \
ec2 create-security-group \
--group-name SshSG \
--description "Allow ssh" \
--vpc-id ${VPCID}) ;
aws --profile ${PROFILE} \
ec2 create-tags \
--resources ${SSH_SG_ID} \
--tags "Key=Name,Value=SshSG" ;
aws --profile ${PROFILE} \
ec2 authorize-security-group-ingress \
--group-id ${SSH_SG_ID} \
--protocol tcp \
--port 22 \
--cidr 0.0.0.0/0 ;
(ii) Client - RDPログイン用 Security Group
RDP_SG_ID=$(aws --profile ${PROFILE} --output text \
ec2 create-security-group \
--group-name RdpSG \
--description "Allow rdp" \
--vpc-id ${VPCID}) ;
aws --profile ${PROFILE} \
ec2 create-tags \
--resources ${RDP_SG_ID} \
--tags "Key=Name,Value=RdpSG" ;
aws --profile ${PROFILE} \
ec2 authorize-security-group-ingress \
--group-id ${RDP_SG_ID} \
--protocol tcp \
--port 3389 \
--cidr 0.0.0.0/0 ;
(iii) Client識別用 Security Group
CLIENT_SG_ID=$(aws --profile ${PROFILE} --output text \
ec2 create-security-group \
--group-name ClientSG \
--description "Allow rdp" \
--vpc-id ${VPCID}) ;
aws --profile ${PROFILE} \
ec2 create-tags \
--resources ${CLIENT_SG_ID} \
--tags "Key=Name,Value=ClientSG" ;
(iv) Manager - SSHログイン用 Security Group
MGR_SSH_SG_ID=$(aws --profile ${PROFILE} --output text \
ec2 create-security-group \
--group-name Mgr-SshSG \
--description "Allow ssh" \
--vpc-id ${VPCID}) ;
aws --profile ${PROFILE} \
ec2 create-tags \
--resources ${MGR_SSH_SG_ID} \
--tags "Key=Name,Value=Mgr-SshSG" ;
aws --profile ${PROFILE} \
ec2 authorize-security-group-ingress \
--group-id ${MGR_SSH_SG_ID} \
--protocol tcp \
--port 22 \
--cidr 0.0.0.0/0 ;
(iiv) セキュリティーグループ設定情報の確認
SSH_SG_ID=$(aws --profile ${PROFILE} --output text \
ec2 describe-security-groups \
--filter 'Name=group-name,Values=SshSG' \
--query 'SecurityGroups[].GroupId');
RDP_SG_ID=$(aws --profile ${PROFILE} --output text \
ec2 describe-security-groups \
--filter 'Name=group-name,Values=RdpSG' \
--query 'SecurityGroups[].GroupId');
CLIENT_SG_ID=$(aws --profile ${PROFILE} --output text \
ec2 describe-security-groups \
--filter 'Name=group-name,Values=ClientSG' \
--query 'SecurityGroups[].GroupId');
MGR_SG_ID=$(aws --profile ${PROFILE} --output text \
ec2 describe-security-groups \
--filter 'Name=group-name,Values=Mgr-SshSG' \
--query 'SecurityGroups[].GroupId');
echo -e "SSH_SG_ID =${SSH_SG_ID}\nRDP_SG_ID =${RDP_SG_ID}\nCLIENT_SG_ID=${CLIENT_SG_ID}\nMGR_SG_ID =${MGR_SG_ID}"
(5)-(b)インスタンス作成用の事前情報取得
KEYNAME="CHANGE_KEY_PAIR_NAME"
AL2_AMIID=$(aws --profile ${PROFILE} --output text \
ec2 describe-images \
--owners amazon \
--filters 'Name=name,Values=amzn2-ami-hvm-2.0.????????.?-x86_64-gp2' \
'Name=state,Values=available' \
--query 'reverse(sort_by(Images, &CreationDate))[:1].ImageId' ) ;
WIN2019_AMIID=$(aws --profile ${PROFILE} --output text \
ec2 describe-images \
--owners amazon \
--filters 'Name=name,Values=Windows_Server-2019-Japanese-Full-Base-????.??.??' \
'Name=state,Values=available' \
--query 'reverse(sort_by(Images, &CreationDate))[:1].ImageId' ) ;
echo -e "KEYNAME=${KEYNAME}\nAL2_AMIID=${AL2_AMIID}\nWIN2019_AMIID=${WIN2019_AMIID}"
(5)-(c) Liunux-Client作成
INSTANCE_TYPE="t2.micro"
TAGJSON='
[
{
"ResourceType": "instance",
"Tags": [
{
"Key": "Name",
"Value": "Linux-Client"
}
]
}
]'
USER_DATA='
#!/bin/bash -xe
yum -y update
yum -y install bind bind-utils
hostnamectl set-hostname Linux-Client
'
aws --profile ${PROFILE} \
ec2 run-instances \
--image-id ${AL2_AMIID} \
--instance-type ${INSTANCE_TYPE} \
--key-name ${KEYNAME} \
--subnet-id ${PublicSubnet1Id} \
--security-group-ids ${SSH_SG_ID} ${CLIENT_SG_ID}\
--associate-public-ip-address \
--tag-specifications "${TAGJSON}" \
--user-data "${USER_DATA}" ;
(5)-(d) Windows-Client作成
INSTANCE_TYPE="t2.micro"
TAGJSON='
[
{
"ResourceType": "instance",
"Tags": [
{
"Key": "Name",
"Value": "Windows-Client"
}
]
}
]'
aws --profile ${PROFILE} \
ec2 run-instances \
--image-id ${WIN2019_AMIID} \
--instance-type ${INSTANCE_TYPE} \
--key-name ${KEYNAME} \
--subnet-id ${PublicSubnet1Id} \
--security-group-ids ${RDP_SG_ID} ${CLIENT_SG_ID}\
--associate-public-ip-address \
--tag-specifications "${TAGJSON}" ;
(5)-(e) Manager(Linux)の作成
ファイルゲートウェイのアクティベーション作業を行う管理インスタンスを起動します。
INSTANCE_TYPE="t2.micro"
TAGJSON='
[
{
"ResourceType": "instance",
"Tags": [
{
"Key": "Name",
"Value": "Manager-Linux"
}
]
}
]'
USER_DATA='
#!/bin/bash -xe
yum -y update
yum -y install bind bind-utils
hostnamectl set-hostname Mgr-linux
'
aws --profile ${PROFILE} \
ec2 run-instances \
--image-id ${AL2_AMIID} \
--instance-type t2.micro \
--key-name ${KEYNAME} \
--subnet-id ${PublicSubnet2Id} \
--security-group-ids ${MGR_SSH_SG_ID}\
--associate-public-ip-address \
--tag-specifications "${TAGJSON}" \
--user-data "${USER_DATA}" \
--iam-instance-profile "Name=Ec2-StorageGW-AdminRole-Profile";
(6) Storage Gateway作成(事前準備)
Storage Gatewayで利用するS3のバケットと、S3アクセス用にStorage Gatewayが利用するIAMロールを作成します。
(6)-(a) Storage Gateway用のSecurityGroup作成
(i) SGW用 Security Group
CLIENT_SG_ID=$(aws --profile ${PROFILE} --output text \
ec2 describe-security-groups \
--filter 'Name=group-name,Values=ClientSG' \
--query 'SecurityGroups[].GroupId');
MGR_SG_ID=$(aws --profile ${PROFILE} --output text \
ec2 describe-security-groups \
--filter 'Name=group-name,Values=Mgr-SshSG' \
--query 'SecurityGroups[].GroupId');
echo -e "CLIENT_SG_ID=${CLIENT_SG_ID}\nMGR_SG_ID =${MGR_SG_ID}"
SGW_SG_ID=$(aws --profile ${PROFILE} --output text \
ec2 create-security-group \
--group-name SGWSG \
--description "Allow gateway" \
--vpc-id ${VPCID}) ;
aws --profile ${PROFILE} \
ec2 create-tags \
--resources ${SGW_SG_ID} \
--tags "Key=Name,Value=StorageGWSG" ;
aws --profile ${PROFILE} \
ec2 authorize-security-group-ingress \
--group-id ${SGW_SG_ID} \
--protocol tcp \
--port 80 \
--source-group ${MGR_SG_ID} ;
aws --profile ${PROFILE} \
ec2 authorize-security-group-ingress \
--group-id ${SGW_SG_ID} \
--protocol tcp \
--port 22 \
--source-group ${MGR_SG_ID} ;
aws --profile ${PROFILE} \
ec2 authorize-security-group-ingress \
--group-id ${SGW_SG_ID} \
--protocol tcp \
--port 139 \
--source-group ${CLIENT_SG_ID} ;
aws --profile ${PROFILE} \
ec2 authorize-security-group-ingress \
--group-id ${SGW_SG_ID} \
--protocol tcp \
--port 445 \
--source-group ${CLIENT_SG_ID} ;
aws --profile ${PROFILE} \
ec2 authorize-security-group-ingress \
--group-id ${SGW_SG_ID} \
--protocol tcp \
--port 2049 \
--source-group ${CLIENT_SG_ID} ;
aws --profile ${PROFILE} \
ec2 authorize-security-group-ingress \
--group-id ${SGW_SG_ID} \
--protocol tcp \
--port 111 \
--source-group ${CLIENT_SG_ID} ;
aws --profile ${PROFILE} \
ec2 authorize-security-group-ingress \
--group-id ${SGW_SG_ID} \
--protocol tcp \
--port 20048 \
--source-group ${CLIENT_SG_ID} ;
(6)-(b) KMSキー作成
S3暗号化用のKMSのCMK(Customer Master Key)を作成します。キーポリシーはIAMロール作成後に設定します。
KEY_ID=$( \
aws --profile ${PROFILE} --output text \
kms create-key \
--description "CMK for S3 buckets" \
--origin AWS_KMS \
--query 'KeyMetadata.KeyId' )
aws --profile ${PROFILE} \
kms create-alias \
--alias-name alias/Key_For_S3Buckets \
--target-key-id ${KEY_ID}
BUCKET_NAME="storagegw-bucket-$( od -vAn -to1 </dev/urandom | tr -d " " | fold -w 10 | head -n 1)"
REGION=$(aws --profile ${PROFILE} configure get region)
aws --profile ${PROFILE} \
s3api create-bucket \
--bucket ${BUCKET_NAME} \
--create-bucket-configuration LocationConstraint=${REGION};
(ii) バケットポリシー設定
特定のCMKでの暗号化を強制するバケットポリシーを設定します。
KEY_ARN=$(aws --profile ${PROFILE} --output text \
kms describe-key \
--key-id alias/Key_For_S3Buckets \
--query 'KeyMetadata.Arn' \
)
POLICY='{
"Version": "2012-10-17",
"Id": "S3KeyPolicy",
"Statement": [
{
"Sid": "Force KMS Key",
"Effect": "Deny",
"Principal": "*",
"Action": "s3:PutObject",
"Resource": "arn:aws:s3:::'"${BUCKET_NAME}"'/*",
"Condition": {
"StringNotEquals": {
"s3:x-amz-server-side-encryption-aws-kms-key-id": "'"${KEY_ARN}"'"
}
}
}
]
}'
aws --profile ${PROFILE} s3api \
put-bucket-policy \
--bucket ${BUCKET_NAME} \
--policy "${POLICY}"
(6)-(d) Storage Gateway ファイル共有-S3アクセス用 IAMRole作成
POLICY='{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "",
"Effect": "Allow",
"Principal": {
"Service": "storagegateway.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}'
aws --profile ${PROFILE} \
iam create-role \
--role-name "StorageGateway-S3AccessRole" \
--assume-role-policy-document "${POLICY}" \
--max-session-duration 43200
POLICY='{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "OperatBucket",
"Effect": "Allow",
"Action": [
"s3:GetAccelerateConfiguration",
"s3:GetBucketLocation",
"s3:GetBucketVersioning",
"s3:ListBucket",
"s3:ListBucketVersions",
"s3:ListBucketMultipartUploads"
],
"Resource": [
"arn:aws:s3:::'"${BUCKET_NAME}"'"
]
},
{
"Sid": "PuAndGetObject",
"Effect": "Allow",
"Action": [
"s3:AbortMultipartUpload",
"s3:DeleteObject",
"s3:DeleteObjectVersion",
"s3:GetObject",
"s3:GetObjectAcl",
"s3:GetObjectVersion",
"s3:ListMultipartUploadParts",
"s3:PutObject",
"s3:PutObjectAcl"
],
"Resource": [
"arn:aws:s3:::'"${BUCKET_NAME}"'/*"
]
}
]
}'
aws --profile ${PROFILE} \
iam put-role-policy \
--role-name "StorageGateway-S3AccessRole" \
--policy-name "AccessS3buckets" \
--policy-document "${POLICY}";
POLICY='{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowLogs",
"Effect": "Allow",
"Action": [
"logs:CreateLogStream",
"logs:PutLogEvents"
],
"Resource": [
"*"
]
}
]
}'
aws --profile ${PROFILE} \
iam put-role-policy \
--role-name "StorageGateway-S3AccessRole" \
--policy-name "PutCLoudWatchLogs" \
--policy-document "${POLICY}";
(6)-(e) Storage Gateway管理用Roleに上記IAMのPassRole権限付与
この後のStorage Gatewayのファイル共有作成時(CreateSmbFileShare)に、ファイル共有からS3にPUT/GETするためのIAMロールを指定し割り当ています。この作業時に管理者のIAM権限としてeにPassRoleのアクションを許可する必要があります。
S3AccessRole_ARN=$(aws --profile ${PROFILE} --output text \
iam get-role \
--role-name "StorageGateway-S3AccessRole" \
--query 'Role.Arn') ;
POLICY='{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "PassRole",
"Effect": "Allow",
"Action": [
"iam:PassRole"
],
"Resource": [
"'"${S3AccessRole_ARN}"'"
]
}
]
}'
aws --profile ${PROFILE} \
iam put-role-policy \
--role-name "Ec2-StorageGW-AdminRole" \
--policy-name "PassRole" \
--policy-document "${POLICY}";
(6)-(f) CMKキーポリシー設定
ADMIN_ARN=$(aws --profile ${PROFILE} --output text \
sts get-caller-identity --query 'Arn')
ACCOUNT_ID=$(aws --profile ${PROFILE} --output text \
sts get-caller-identity --query 'Account')
S3AccessRole_ARN=$(aws --profile ${PROFILE} --output text \
iam get-role \
--role-name "StorageGateway-S3AccessRole" \
--query 'Role.Arn') ;
STORAGEGW_ADMIN_ROLE_ARN=$(aws --profile ${PROFILE} --output text \
iam get-role \
--role-name "Ec2-StorageGW-AdminRole" \
--query 'Role.Arn') ;
KEY_ARN=$( aws --profile ${PROFILE} --output text \
kms describe-key \
--key-id "alias/Key_For_S3Buckets" \
--query 'KeyMetadata.Arn')
POLICY='{
"Version": "2012-10-17",
"Id": "key-default-1",
"Statement": [
{
"Sid": "Administrator",
"Effect": "Allow",
"Principal": {
"AWS": [
"'"${ADMIN_ARN}"'",
"'"${STORAGEGW_ADMIN_ROLE_ARN}"'",
"arn:aws:iam::'"${ACCOUNT_ID}"':role/OrganizationAccountAccessRole"
]
},
"Action": "kms:*",
"Resource": "*"
},
{
"Sid": "User",
"Effect": "Allow",
"Principal": {
"AWS": [
"'"${S3AccessRole_ARN}"'"
]
},
"Action": [
"kms:DescribeKey",
"kms:Decrypt",
"kms:GenerateDataKey"
],
"Resource": "*"
}
]
}'
aws --profile ${PROFILE} \
kms put-key-policy \
--key-id "${KEY_ARN}" \
--policy-name "default" \
--policy "${POLICY}" \
--no-bypass-policy-lockout-safety-check ;
(6)-(g) NTP接続不可回避用のRoute53 Private Hosted Zone設定
ファイルゲートウェイに設定されているNTPサーバ(同期先)は、インターネット上のNTPサーバ(x.amazon.pool.ntp.org
)です。そのためファイルゲートウェイをインターネット接続ができない環境に設置した場合、時刻同期処理を行うことができません。この手順は、Route53のPrivate Hosted Zoneを活用し、x.amazon.pool.ntp.orgのアクセス先をAWS time sync(169.254.169.123)にアクセスするようにしてます。
REGION=$(aws --profile ${PROFILE} configure get region)
aws --profile ${PROFILE} \
route53 create-hosted-zone \
--name "amazon.pool.ntp.org" \
--caller-reference $(date '+%Y-%m-%d-%H:%M') \
--vpc VPCRegion=${REGION},VPCId=${VPCID} ;
HOSTED_ZONE_ID=$(aws --profile ${PROFILE} --output text \
route53 list-hosted-zones-by-name \
--dns-name "amazon.pool.ntp.org" \
--query 'HostedZones[].Id' | sed -e 's/\/hostedzone\///') ;
CHANGE_BATCH_JSON='{
"Comment": "CREATE NTP records ",
"Changes": [
{
"Action": "CREATE",
"ResourceRecordSet": {
"Name": "0.amazon.pool.ntp.org",
"Type": "A",
"TTL": 300,
"ResourceRecords": [
{
"Value": "169.254.169.123"
}
]
}
},
{
"Action": "CREATE",
"ResourceRecordSet": {
"Name": "1.amazon.pool.ntp.org",
"Type": "A",
"TTL": 300,
"ResourceRecords": [
{
"Value": "169.254.169.123"
}
]
}
},
{
"Action": "CREATE",
"ResourceRecordSet": {
"Name": "2.amazon.pool.ntp.org",
"Type": "A",
"TTL": 300,
"ResourceRecords": [
{
"Value": "169.254.169.123"
}
]
}
},
{
"Action": "CREATE",
"ResourceRecordSet": {
"Name": "3.amazon.pool.ntp.org",
"Type": "A",
"TTL": 300,
"ResourceRecords": [
{
"Value": "169.254.169.123"
}
]
}
}
]
}'
aws --profile ${PROFILE} \
route53 change-resource-record-sets \
--hosted-zone-id ${HOSTED_ZONE_ID} \
--change-batch "${CHANGE_BATCH_JSON}";
ゲートウェイを作成、アクティベーションして利用可能な状態にします。
FGW_AMIID=$(aws --profile ${PROFILE} --output text \
ec2 describe-images \
--owners amazon \
--filters 'Name=name,Values=aws-storage-gateway-??????????' \
'Name=state,Values=available' \
--query 'reverse(sort_by(Images, &CreationDate))[:1].ImageId' );
SGW_SG_ID=$(aws --profile ${PROFILE} --output text \
ec2 describe-security-groups \
--filter 'Name=group-name,Values=SGWSG' \
--query 'SecurityGroups[].GroupId');
INSTANCE_TYPE=c5.4xlarge
TAGJSON='
[
{
"ResourceType": "instance",
"Tags": [
{
"Key": "Name",
"Value": "Fgw"
}
]
}
]'
BLOCK_DEVICE_MAPPINGS='[
{
"DeviceName": "/dev/xvda",
"Ebs": {
"DeleteOnTermination": true,
"VolumeType": "io1",
"Iops": 4000,
"VolumeSize": 350,
"Encrypted": false
}
},
{
"DeviceName": "/dev/sdm",
"Ebs": {
"DeleteOnTermination": true,
"VolumeType": "io1",
"Iops": 3000,
"VolumeSize": 16384,
"Encrypted": false
}
}
]'
aws --profile ${PROFILE} \
ec2 run-instances \
--image-id ${FGW_AMIID} \
--instance-type ${INSTANCE_TYPE} \
--key-name ${KEYNAME} \
--subnet-id ${PrivateSubnet1Id} \
--security-group-ids ${SGW_SG_ID} \
--block-device-mappings "${BLOCK_DEVICE_MAPPINGS}" \
--tag-specifications "${TAGJSON}" \
--monitoring Enabled=true ;
(ii)AutoRecovery設定
export REGION=ap-northeast-1
GatewayInstanceID=$(aws --profile ${PROFILE} --output text \
ec2 describe-instances \
--filters "Name=tag:Name,Values=Fgw" "Name=instance-state-name,Values=running" \
--query 'Reservations[*].Instances[*].InstanceId' )
aws --profile ${PROFILE} \
cloudwatch put-metric-alarm \
--region "${REGION}" \
--alarm-name "recover-ec2-instance-${GatewayInstanceID}" \
--alarm-description "recover-FileGateway-ec2-instance" \
--alarm-actions \
"arn:aws:automate:${REGION}:ec2:recover" \
--namespace AWS/EC2 \
--metric-name StatusCheckFailed_System \
--dimensions Name=InstanceId,Value=${GatewayInstanceID} \
--comparison-operator GreaterThanThreshold \
--unit Count \
--statistic Average \
--period 60 \
--threshold 1 \
--evaluation-periods 1
(7)-(b) Mgr-Linuxへのログインとセットアップ
以後の作業で、Mgr-Linuxを利用するため、sshログインとセットアップを行います。
(i) 作業端末からMgr-Linuxへのログイン(ここではMAC前提)
MgrIP=$(aws --profile ${PROFILE} --output text \
ec2 describe-instances \
--filters "Name=tag:Name,Values=Manager-Linux" "Name=instance-state-name,Values=running" \
--query 'Reservations[*].Instances[*].PublicIpAddress' )
ssh-add
ssh -A ec2-user@${MgrIP}
(ii) Mgr-Linuxのセットアップ
以下はSSHログインした、Mgr-Linux上での作業となります。
curl -o "get-pip.py" "https://bootstrap.pypa.io/get-pip.py"
sudo python get-pip.py
pip install --upgrade --user awscli
echo 'export PATH=$HOME/.local/bin:$PATH' >> ~/.bashrc
. ~/.bashrc
Region=$(curl -s http://169.254.169.254/latest/meta-data/placement/availability-zone | sed -e 's/.$//')
aws configure set region ${Region}
aws configure set output json
aws sts get-caller-identity
export PROFILE=default
(iii) 構成情報の取得
export PROFILE=default
VPCID=$(aws --profile ${PROFILE} --output text \
cloudformation describe-stacks \
--stack-name SGWPoC-VPC \
--query 'Stacks[].Outputs[?OutputKey==`VpcId`].[OutputValue]')
VPC_CIDR=$(aws --profile ${PROFILE} --output text \
cloudformation describe-stacks \
--stack-name SGWPoC-VPC \
--query 'Stacks[].Outputs[?OutputKey==`VpcCidr`].[OutputValue]')
PublicSubnet1Id=$(aws --profile ${PROFILE} --output text \
cloudformation describe-stacks \
--stack-name SGWPoC-VPC \
--query 'Stacks[].Outputs[?OutputKey==`PublicSubnet1Id`].[OutputValue]')
PublicSubnet2Id=$(aws --profile ${PROFILE} --output text \
cloudformation describe-stacks \
--stack-name SGWPoC-VPC \
--query 'Stacks[].Outputs[?OutputKey==`PublicSubnet2Id`].[OutputValue]')
PrivateSubnet1Id=$(aws --profile ${PROFILE} --output text \
cloudformation describe-stacks \
--stack-name SGWPoC-VPC \
--query 'Stacks[].Outputs[?OutputKey==`PrivateSubnet1Id`].[OutputValue]')
PrivateSubnet2Id=$(aws --profile ${PROFILE} --output text \
cloudformation describe-stacks \
--stack-name SGWPoC-VPC \
--query 'Stacks[].Outputs[?OutputKey==`PrivateSubnet2Id`].[OutputValue]')
PrivateSubnet1RouteTableId=$(aws --profile ${PROFILE} --output text \
cloudformation describe-stacks \
--stack-name SGWPoC-VPC \
--query 'Stacks[].Outputs[?OutputKey==`PrivateSubnet1RouteTableId`].[OutputValue]')
PrivateSubnet2RouteTableId=$(aws --profile ${PROFILE} --output text \
cloudformation describe-stacks \
--stack-name SGWPoC-VPC \
--query 'Stacks[].Outputs[?OutputKey==`PrivateSubnet2RouteTableId`].[OutputValue]')
echo -e "VPCID=$VPCID\nVPC_CIDR=$VPC_CIDR\nPublicSubnet1Id =$PublicSubnet1Id\nPublicSubnet2Id =$PublicSubnet2Id\nPrivateSubnet1Id=$PrivateSubnet1Id\nPrivateSubnet2Id=$PrivateSubnet2Id\nPrivateSubnet1RouteTableId=$PrivateSubnet1RouteTableId \nPrivateSubnet2RouteTableId=$PrivateSubnet2RouteTableId"
ファイルゲートウェイから、 アクティベーションキーを取得します。
GatewayIP=$(aws --profile ${PROFILE} --output text \
ec2 describe-instances \
--filters "Name=tag:Name,Values=Fgw" "Name=instance-state-name,Values=running" \
--query 'Reservations[*].Instances[*].PrivateIpAddress' )
REGION=$(aws --profile ${PROFILE} configure get region)
VPCEndpointDNSname=$(aws --profile ${PROFILE} --output text \
ec2 describe-vpc-endpoints \
--filters \
"Name=service-name,Values=com.amazonaws.ap-northeast-1.storagegateway" \
"Name=vpc-id,Values=${VPCID}" \
--query 'VpcEndpoints[*].DnsEntries[0].DnsName' );
echo ${GatewayIP} ${REGION} ${VPCEndpointDNSname}
ACTIVATION_URL="http://${GatewayIP}/?gatewayType=FILE_S3&activationRegion=${REGION}&vpcEndpoint=${VPCEndpointDNSname}&no_redirect"
echo ${ACTIVATION_URL}
ACTIVATION_KEY=$(curl "${ACTIVATION_URL}")
echo ${ACTIVATION_KEY}
参考:
https://docs.aws.amazon.com/ja_jp/storagegateway/latest/userguide/gateway-private-link.html#GettingStartedActivateGateway-file-vpc
ファイルゲートウェイをアクティベーションします。
REGION=$(aws --profile ${PROFILE} configure get region)
aws --profile ${PROFILE} \
storagegateway activate-gateway \
--activation-key ${ACTIVATION_KEY} \
--gateway-name SgPoC-Gateway-1 \
--gateway-timezone "GMT+9:00" \
--gateway-region ${REGION} \
--gateway-type FILE_S3
aws --profile ${PROFILE} storagegateway describe-gateway-information --gateway-arn <GATEWAYのARN>
<参考 gateway-typeの説明>
- "STORED" : VolumeGateway(Store type)
- "CACHED" : VolumeGateway(Cache tyep)
- "VTL" : VirtualTapeLibrary
- "FILE_S3": File Gateway
(7)-(e) ローカルディスク設定
GATEWAY_ARN=$(aws --profile ${PROFILE} --output text storagegateway list-gateways |awk '/SgPoC-Gateway-1/{ print $4 }')
DiskIds=$(aws --profile ${PROFILE} --output text storagegateway list-local-disks --gateway-arn ${GATEWAY_ARN} --query 'Disks[*].DiskId'| sed -e 's/\n/ /')
echo ${DiskIds}
aws --profile ${PROFILE} storagegateway \
add-cache \
--gateway-arn ${GATEWAY_ARN} \
--disk-ids ${DiskIds}
aws --profile ${PROFILE} --output text \
storagegateway list-local-disks \
--gateway-arn ${GATEWAY_ARN}
参照:https://docs.aws.amazon.com/ja_jp/storagegateway/latest/userguide/create-gateway-file.html
(7)-(f) CloudWatch Logs設定
ファイルゲートウェイインスタンスから、Logsへのログ出力設定を行います。LogsにはS3へのDenyAccess情報などが記録されます。
GATEWAY_ARN=$(aws --output text storagegateway list-gateways |awk '/SgPoC-Gateway-1/{ match($0, /arn:aws:storagegateway:\S*/); print substr($0, RSTART, RLENGTH) }')
echo "GATEWAY_ARN=$GATEWAY_ARN Region=${Region} AccuntId=${AccuntId}"
LOG_GROUP_NAME=${SgPoC-Gateway-1}
aws --profile ${PROFILE} \
logs create-log-group \
--log-group-name ${LOG_GROUP_NAME};
LOG_GROUP_ARN=$(aws --profile ${PROFILE} --output text \
logs describe-log-groups \
--log-group-name-prefix ${LOG_GROUP_NAME} \
--query 'logGroups[].arn' );
aws --profile ${PROFILE} \
storagegateway update-gateway-information \
--gateway-arn ${GATEWAY_ARN} \
--cloud-watch-log-group-arn ${LOG_GROUP_ARN}
(8) File Gateway - ファイル共有設定(NFS)
NFSのファイル共有を作成し、LinuxクライアントからNFS接続します。
(8)-(a)情報の確認と設定(S3, IAMロール、ゲートウェイ)
Linux Managerで下記設定を実行します。
上記(6)で作成したS3バケット以外のバケットを利用する場合は、(6)-(c)で作成した、"StorageGateway-S3AccessRole"ロールのリソース句に該当のS3バケットを追加してください。
BUCKET_NAME=<バケット名を個別に設定>
BUCKETARN="arn:aws:s3:::${BUCKET_NAME}"
ROLE="StorageGateway-S3AccessRole"
ROLEARN=$(aws --profile ${PROFILE} --output text \
iam get-role \
--role-name "StorageGateway-S3AccessRole" \
--query 'Role.Arn')
GATEWAY_ARN=$(aws --profile ${PROFILE} --output text storagegateway list-gateways |awk '/SgPoC-Gateway-1/{ print $4 }')
CLIENT_TOKEN=$(cat /dev/urandom | base64 | fold -w 38 | sed -e 's/[\/\+\=]/0/g' | head -n 1)
KEY_ARN=$( aws --profile ${PROFILE} --output text \
kms describe-key \
--key-id "alias/Key_For_S3Buckets" \
--query 'KeyMetadata.Arn')
echo -e "BUCKET=${BUCKETARN}\nROLE_ARN=${ROLEARN}\nGATEWAY_ARN=${GATEWAY_ARN}\nCLIENT_TOKEN=${CLIENT_TOKEN}\nKEY_ARN=${KEY_ARN}"
(8)-(b)ファイル共有(NFS)の作成
FILE_SHARE_DEFAULT_JSON='{
"FileMode": "0666",
"DirectoryMode": "0777",
"GroupId": 65534,
"OwnerId": 65534
}'
aws --profile ${PROFILE} storagegateway \
create-nfs-file-share \
--client-token ${CLIENT_TOKEN} \
--gateway-arn "${GATEWAY_ARN}" \
--location-arn "${BUCKETARN}" \
--role "${ROLEARN}" \
--nfs-file-share-defaults "${FILE_SHARE_DEFAULT_JSON}" \
--client-list "0.0.0.0/0" \
--squash "RootSquash" \
--kms-encrypted \
--kms-key ${KEY_ARN} ;
(8)-(c) Linuxクライアントからの接続
作業端末から、Linuxクライアントに接続し、NFSマウントを実行します。
(i) 作業端末からMgr-Linuxへのログイン(ここではMAC前提)
以後の作業で、Linux-Clientを利用するため、sshログインとセットアップを行います。
LinuxClinetIP=$(aws --profile ${PROFILE} --output text \
ec2 describe-instances \
--filters "Name=tag:Name,Values=Linux-Client" "Name=instance-state-name,Values=running" \
--query 'Reservations[*].Instances[*].PublicIpAddress' )
ssh-add
ssh -A ec2-user@${LinuxClinetIP}
Linux-Clientにユーザ"ec2-user"でログイン完了した後に、下記コマンドでNFSマウントします。
sudo -i
FGWIP=<ファイルGWのPrivateIPを設定>
EXPORT_PATH=<ファイル共有のエクスポートパス情報を(/から始まる情報)を設定>
echo -e "FGWIP=${FGWIP}\nEXPORT_PATH=${EXPORT_PATH}"
情報確認後、マウント設定を行います。
mkdir /nfs
echo "${FGWIP}:${EXPORT_PATH} /nfs nfs nolock,hard 0 2" >> /etc/fstab
mount -a
df
(9) File Gateway - ファイル共有設定(SMB - Guest Access)
ActiveDirectoryを利用しない、ゲストアクセスタイプのSMBのファイル共有を作成し、WindowsクライアントからSMB(ゲストアクセス)接続します。
Linux Managerで下記設定を実行します。
(9)-(a) SMB設定(SMBSecurityStrategy)
GATEWAY_ARN=$(aws --profile ${PROFILE} --output text storagegateway list-gateways |awk '/SgPoC-Gateway-1/{ print $4 }')
aws --profile ${PROFILE} storagegateway \
update-smb-security-strategy \
--gateway-arn ${GATEWAY_ARN} \
--smb-security-strategy MandatoryEncryption
(9)-(b) ゲストアクセス用の SMB ファイル共有を設定
PASSWORD="HogeHoge@"
aws --profile ${PROFILE} storagegateway \
set-smb-guest-password \
--gateway-arn ${GATEWAY_ARN} \
--password ${PASSWORD}
(9)-(c) SMBファイル共有
上記(6)で作成したS3バケット以外のバケットを利用する場合は、(6)-(c)で作成した、"StorageGateway-S3AccessRole"ロールのリソース句に該当のS3バケットを追加してください。
BUCKET_NAME=<バケット名を個別に設定>
BUCKETARN="arn:aws:s3:::${BUCKET_NAME}"
ROLE="StorageGateway-S3AccessRole"
ROLEARN=$(aws --profile ${PROFILE} --output text \
iam get-role \
--role-name "StorageGateway-S3AccessRole" \
--query 'Role.Arn')
GATEWAY_ARN=$(aws --profile ${PROFILE} --output text storagegateway list-gateways |awk '/SgPoC-Gateway-1/{ print $4 }')
CLIENT_TOKEN=$(cat /dev/urandom | base64 | fold -w 38 | sed -e 's/[\/\+\=]/0/g' | head -n 1)
KEY_ARN=$( aws --profile ${PROFILE} --output text \
kms describe-key \
--key-id "alias/Key_For_S3Buckets" \
--query 'KeyMetadata.Arn')
echo -e "BUCKET=${BUCKETARN}\nROLE_ARN=${ROLEARN}\nGATEWAY_ARN=${GATEWAY_ARN}\nCLIENT_TOKEN=${CLIENT_TOKEN}\nKEY_ARN=${KEY_ARN}"
aws --profile ${PROFILE} storagegateway \
create-smb-file-share \
--client-token ${CLIENT_TOKEN} \
--gateway-arn "${GATEWAY_ARN}" \
--location-arn "${BUCKETARN}" \
--role "${ROLEARN}" \
--object-acl bucket-owner-full-control \
--default-storage-class S3_STANDARD \
--guess-mime-type-enabled \
--authentication GuestAccess \
--kms-encrypted \
--kms-key ${KEY_ARN} ;
(9)-(d) Windows-ClinetからのSMBアクセス
Windows ClinetにRDPログインし、SMB接続をします。
説明は省略します。
ファイルゲートウェイとクライアントのWindowsサーバをADに参加させ、AD認証でファイル共有する手順です。この手順ではADに AWS Directory ServiceのAWS Managed Microsoft ADを利用しています。
作業端末で作業を実施ます。
(i)情報収集
PROFILE=<プロファイルを指定>
VPCID=$(aws --profile ${PROFILE} --output text \
cloudformation describe-stacks \
--stack-name SGWPoC-VPC \
--query 'Stacks[].Outputs[?OutputKey==`VpcId`].[OutputValue]')
PublicSubnet2Id=$(aws --profile ${PROFILE} --output text \
cloudformation describe-stacks \
--stack-name SGWPoC-VPC \
--query 'Stacks[].Outputs[?OutputKey==`PublicSubnet2Id`].[OutputValue]')
PrivateSubnet1Id=$(aws --profile ${PROFILE} --output text \
cloudformation describe-stacks \
--stack-name SGWPoC-VPC \
--query 'Stacks[].Outputs[?OutputKey==`PrivateSubnet1Id`].[OutputValue]')
PrivateSubnet2Id=$(aws --profile ${PROFILE} --output text \
cloudformation describe-stacks \
--stack-name SGWPoC-VPC \
--query 'Stacks[].Outputs[?OutputKey==`PrivateSubnet2Id`].[OutputValue]')
echo -e "VPCID=$VPCID\nPublicSubnet2Id=${PublicSubnet2Id}\nPrivateSubnet1Id=$PrivateSubnet1Id\nPrivateSubnet2Id=$PrivateSubnet2Id\n"
(ii) Managed Microsoft AD(MAD)作成のための情報設定
AD_NAME="sgwpoc.local"
AD_EDITION="Standard"
KEYNAME="CHANGE_KEY_PAIR_NAME"
AD_PASSWORD="$( cat /dev/urandom | base64 |tr -dc 'a-zA-Z0-9' | fold -w 16 | head -n 1)${RANDOM}"
echo ${AD_PASSWORD}
- ADのパスワードは、8~64 文字で指定し、「admin」という語は含めず、英小文字、英大文字、数字、特殊文字の 4 つのカテゴリのうちの 3 つを含める必要があります。
(iii) Managed Microsoft AD(MAD)作成
MADを作成します。MADのENIに付与されるセキュリティーグループは、ADサービスが自動的に作成します。
aws --profile ${PROFILE} ds \
create-microsoft-ad \
--name "${AD_NAME}" \
--short-name "SgwPoC" \
--description "AD for StorageGateway PoC" \
--password "${AD_PASSWORD}" \
--edition "${AD_EDITION}" \
--vpc-settings "VpcId=${VPCID},SubnetIds=${PrivateSubnet1Id},${PrivateSubnet2Id}" ;
(10)-(b) AD管理用のWindows-AD-Mgr作成
(i)構成情報取得
KEYNAME="CHANGE_KEY_PAIR_NAME"
INSTANCE_TYPE="t2.micro"
WIN2019_AMIID=$(aws --profile ${PROFILE} --output text \
ec2 describe-images \
--owners amazon \
--filters 'Name=name,Values=Windows_Server-2019-Japanese-Full-Base-????.??.??' \
'Name=state,Values=available' \
--query 'reverse(sort_by(Images, &CreationDate))[:1].ImageId' ) ;
RDP_SG_ID=$(aws --profile ${PROFILE} --output text \
ec2 describe-security-groups \
--filter 'Name=group-name,Values=RdpSG' \
--query 'SecurityGroups[].GroupId');
echo -e "KEYNAME=${KEYNAME}\nINSTANCE_TYPE=${INSTANCE_TYPE}\nWIN2019_AMIID=${WIN2019_AMIID}\nRDP_SG_ID=${RDP_SG_ID}"
TAGJSON='
[
{
"ResourceType": "instance",
"Tags": [
{
"Key": "Name",
"Value": "Windows-AD-Mgr"
}
]
}
]'
aws --profile ${PROFILE} \
ec2 run-instances \
--image-id ${WIN2019_AMIID} \
--instance-type ${INSTANCE_TYPE} \
--key-name ${KEYNAME} \
--subnet-id ${PublicSubnet2Id} \
--security-group-ids ${RDP_SG_ID} \
--associate-public-ip-address \
--tag-specifications "${TAGJSON}" ;
(10)-(c) AD管理用のWindows-AD-MgrへのAD管理ツールセットアップとAD参加
Import-Module ServerManager
Install-WindowsFeature -Name GPMC,RSAT-AD-PowerShell,RSAT-AD-AdminCenter,RSAT-ADDS-Tools,RSAT-DNS-Server
- 以下の手順でドメイン参加させます。
- DNSの参照先を
ADのDNSアドレス(IPアドレス)
に変更します。
Get-NetAdapter | Set-DnsClientServerAddress -ServerAddresses <ADの1つ目のIPアドレス>,<ADの2つ目のIPアドレス>
Get-NetAdapter | Get-DnsClientServerAddress
Add-Computer -DomainName sgwpoc.local -Credential admin
Restart-Computer
- RDPで、ドメイン
sgwpoc.local
、ユーザAdmin
でログインします。
- Power Shellを起動し
sgwpoc.local
のドメイン情報を参照できることを確認します。
Get-ADDomain -Identity sgwpoc.local
Windows-Clientインスタンスについて、(10)-(C)と同じ手順で、ADに参加させます。
ファイルゲートウェイのDNS参照先を、ADに変更します。変更は、ファイルゲートウェイにssh接続して変更します。
MgrIP=$(aws --profile ${PROFILE} --output text \
ec2 describe-instances \
--filters "Name=tag:Name,Values=Manager-Linux" "Name=instance-state-name,Values=running" \
--query 'Reservations[*].Instances[*].PublicIpAddress' )
ssh-add
ssh -A ec2-user@${MgrIP}
GatewayIP=$(aws --output text ec2 describe-instances --query 'Reservations[*].Instances[*].PrivateIpAddress' --filters "Name=tag:Name,Values=Fgw" "Name=instance-state-name,Values=running")
ssh admin@${GatewayIP}
ファイルゲートウェイの下記メニューが表示されたら、以下の箇条書きの内容を参考にDNS設定を行います。
AWS Storage Gateway - Configuration
1: HTTP/SOCKS Proxy Configuration
2: Network Configuration
3: Test Network Connectivity
4: View System Resource Check (0 Errors)
5: License Information
6: Command Prompt
Press "x" to exit session
Enter command:
Network Configuration
を選び、Edit DNS Configuration
を選択
Available adapters
でeth0
を入力
Assign by DHCP [y/n]:
は、DNSを静的設定するためn
を選択
Enter primary DNS
とEnter secondary DNS
に、ADのDNSアドレス
のIPアドレスを指定
Apply config [y/n]:
でy
で設定反映する
- 終了する
PROFILE="default"
AD_DOMAIN_NAME="sgwpoc.local"
AD_USER="admin"
AD_PASSWORD="< (10)-(a) (ii)で設定したパスワード>"
GATEWAY_ARN=$(aws --profile ${PROFILE} --output text storagegateway list-gateways |awk '/SgPoC-Gateway-1/{ print $4 }')
aws --profile ${PROFILE} \
storagegateway join-domain \
--gateway-arn ${GATEWAY_ARN} \
--domain-name ${AD_DOMAIN_NAME} \
--user-name ${AD_USER} \
--password ${AD_PASSWORD} ;
(iii) SMBファイル共有(AD認証)の作成
上記(6)で作成したS3バケット以外のバケットを利用する場合は、(6)-(c)で作成した、"StorageGateway-S3AccessRole"ロールのリソース句に該当のS3バケットを追加してください。
BUCKET_NAME=storagegw-bucket-smb-ad
BUCKETARN="arn:aws:s3:::${BUCKET_NAME}"
ROLE="StorageGateway-S3AccessRole"
ROLEARN=$(aws --profile ${PROFILE} --output text \
iam get-role \
--role-name "StorageGateway-S3AccessRole" \
--query 'Role.Arn')
GATEWAY_ARN=$(aws --profile ${PROFILE} --output text storagegateway list-gateways |awk '/SgPoC-Gateway-1/{ print $4 }')
CLIENT_TOKEN=$(cat /dev/urandom | base64 | fold -w 38 | sed -e 's/[\/\+\=]/0/g' | head -n 1)
KEY_ARN=$( aws --profile ${PROFILE} --output text \
kms describe-key \
--key-id "alias/Key_For_S3Buckets" \
--query 'KeyMetadata.Arn')
echo -e "BUCKET=${BUCKETARN}\nROLE_ARN=${ROLEARN}\nGATEWAY_ARN=${GATEWAY_ARN}\nCLIENT_TOKEN=${CLIENT_TOKEN}\nKEY_ARN=${KEY_ARN}"
aws --profile ${PROFILE} storagegateway \
create-smb-file-share \
--client-token ${CLIENT_TOKEN} \
--gateway-arn "${GATEWAY_ARN}" \
--location-arn "${BUCKETARN}" \
--role "${ROLEARN}" \
--object-acl bucket-owner-full-control \
--default-storage-class S3_STANDARD \
--guess-mime-type-enabled \
--authentication ActiveDirectory \
--kms-encrypted \
--kms-key ${KEY_ARN} ;
(iv) Windows-Clientからの接続
クライアントから接続確認します。
net use [WindowsDriveLetter]: \\10.1.163.138\storagegw-bucket-smb-ad
(11)運用その他
(11)-(a) キャッシュリフレッシュ
(i)対象バケット全体をリフレッシュする
FILE_SHARE_ARN="<操作したいファイル共有のARNを指定する>"
FOLDER_LIST='/'
aws --profile ${PROFILE} storagegateway \
refresh-cache \
--file-share-arn ${FILE_SHARE_ARN} \
--folder-list ${FOLDER_LIST} \
--recursive ;
- デフォルト(パラメータ未指定)では、下記条件でリフレッシュされる
- --folder-list: "/"(バケット全体が対象)
- --recursive: フォルダーリストで指定したフォルダから、登録済みのサブフォルダを再帰的にリフレッシュする
(ii)特定のフォルダをリフレッシュする
FILE_SHARE_ARN=ファイル共有のARNを設定
FOLDER_LIST='/test2 /test3'
aws --profile ${PROFILE} storagegateway \
refresh-cache \
--file-share-arn ${FILE_SHARE_ARN} \
--folder-list ${FOLDER_LIST} \
--recursive ;
(11)-(b) ソフトウェアアップデート
(i)構成確認
GATEWAY_ARN=$(aws --profile ${PROFILE} --output text storagegateway list-gateways |awk '/SgPoC-Gateway-1/{ print $4 }')
aws --profile ${PROFILE} storagegateway \
describe-gateway-information \
--gateway-arn ${GATEWAY_ARN};
(ii)ソフトウェアアップデート
aws --profile ${PROFILE} storagegateway \
update-gateway-software-now \
--gateway-arn ${GATEWAY_ARN};
(iii)アップデート確認
aws --profile ${PROFILE} storagegateway \
describe-gateway-information \
--gateway-arn ${GATEWAY_ARN};
(11)-(c) イベント連携(リフレッシュ完了通知のイベント連携)
以下の作業は、AdministratorAccess
のIAMポリシーがある作業端末で実行します。
EMAIL_ADDRESS='email@address'
TOPIC_ARN=$(aws --profile ${PROFILE} --output text \
sns create-topic \
--name Sgw-Topic)
aws --profile ${PROFILE} sns \
subscribe \
--topic-arn ${TOPIC_ARN} \
--protocol email \
--notification-endpoint ${EMAIL_ADDRESS}
aws --profile ${PROFILE} sns \
publish \
--topic-arn ${TOPIC_ARN} \
--message 'Hello World!!' ;
(ii)CloudWatch Events Roule作成とSNS Topicリソースポリシー変更
Storage Gatewayのリフレッシュキャッシュの完了通知を受けて、作成したSNS Topicに連携する、Eventsのルールを作成します。
GATEWAY_ARN=$(aws --profile ${PROFILE} --output text storagegateway list-gateways |awk '/SgPoC-Gateway-1/{ print $4 }')
FILE_SHARE_ARNs=$(aws --profile ${PROFILE} --output text \
storagegateway list-file-shares \
--gateway-arn ${GATEWAY_ARN} \
--query FileShareInfoList[].FileShareARN )
TOPIC_ARN=$( aws --profile ${PROFILE} --output text \
sns list-topics | awk '/Sgw-Topic/{print $2}' )
ACCOUNT_ID=$(aws --profile ${PROFILE} --output text \
sts get-caller-identity --query 'Account')
EVENT_PATTERN='
{
"source": [
"aws.storagegateway"
],
"resources":['"$( echo $(for i in $FILE_SHARE_ARNs;do echo '"'"${i}"'",';done)|sed -e 's/,$//')"'
],
"detail-type": [
"Storage Gateway Refresh Cache Event"
]
}'
aws --profile ${PROFILE} --output text events \
put-rule \
--name SgwPoc-Finish-RefleshCache \
--description "Receive notification of completion of specified file gateways RefreshCache and notify SNS topic" \
--event-pattern "${EVENT_PATTERN}" \
--schedule-expression "" \
--state ENABLED ;
aws --profile ${PROFILE} events \
put-targets \
--rule SgwPoc-Finish-RefleshCache \
--targets "Id=1,Arn=${TOPIC_ARN},Input=,InputPath=";
JSON='{
"Version": "2012-10-17",
"Id": "__default_policy_ID",
"Statement": [
{
"Sid": "__default_statement_ID",
"Effect": "Allow",
"Principal": {
"AWS": "*"
},
"Action": [
"SNS:GetTopicAttributes",
"SNS:SetTopicAttributes",
"SNS:AddPermission",
"SNS:RemovePermission",
"SNS:DeleteTopic",
"SNS:Subscribe",
"SNS:ListSubscriptionsByTopic",
"SNS:Publish",
"SNS:Receive"
],
"Resource": "'"${TOPIC_ARN}"'",
"Condition": {
"StringEquals": {
"AWS:SourceOwner": "'"${ACCOUNT_ID}"'"
}
}
},
{
"Sid": "AWSEvents_SgwPoc-Finish-RefleshCache_1",
"Effect": "Allow",
"Principal": {
"Service": "events.amazonaws.com"
},
"Action": "sns:Publish",
"Resource": "'"${TOPIC_ARN}"'"
}
]
}'
aws --profile ${PROFILE} sns \
set-topic-attributes \
--topic-arn ${TOPIC_ARN} \
--attribute-name Policy \
--attribute-value "${JSON}"
(iii)リフレッシュ実行
FILE_SHARE_ARN="<操作したいファイル共有のARNを指定する>"
FOLDER_LIST='/'
aws --profile ${PROFILE} \
storagegateway refresh-cache \
--file-share-arn ${FILE_SHARE_ARN} \
--folder-list ${FOLDER_LIST} \
--recursive ;
(11)-(d) イベント連携(ファイルアップロード完了通知)
(11)-(c)のリフレッシュ完了通知と同じSNS Topicを利用し、ファイルのアップロード完了通知を行います。本作業の前提として、(11)-(c)の設定済みであることとします。
(i) CloudWatch Events設定
GATEWAY_ARN=$(aws --profile ${PROFILE} --output text storagegateway list-gateways |awk '/SgPoC-Gateway-1/{ print $4 }')
FILE_SHARE_ARNs=$(aws --profile ${PROFILE} --output text \
storagegateway list-file-shares \
--gateway-arn ${GATEWAY_ARN} \
--query FileShareInfoList[].FileShareARN )
TOPIC_ARN=$( aws --profile ${PROFILE} --output text \
sns list-topics | awk '/Sgw-Topic/{print $2}' )
EVENT_PATTERN='
{
"source": [
"aws.storagegateway"
],
"resources":['"$( echo $(for i in $FILE_SHARE_ARNs;do echo '"'"${i}"'",';done)|sed -e 's/,$//')"'
],
"detail-type": [
"Storage Gateway File Upload Event"
]
}'
aws --profile ${PROFILE} --output text events \
put-rule \
--name SgwPoc-Finish-File-Upload \
--description "Receive notification of completion of specified file gateways files upload and notify SNS topic" \
--event-pattern "${EVENT_PATTERN}" \
--schedule-expression "" \
--state ENABLED ;
aws --profile ${PROFILE} events \
put-targets \
--rule SgwPoc-Finish-File-Upload \
--targets "Id=1,Arn=${TOPIC_ARN},Input=,InputPath=";
(ii) アップロード完了通知設定
FILE_SHARE_ARN="<操作したいファイル共有のARNを指定する>"
aws --profile ${PROFILE} storagegateway \
notify-when-uploaded \
--file-share-arn ${FILE_SHARE_ARN};