このサイトは非常にシンプルな構成で、AWS環境でEC2インスタンス1つにグローバルIPを割りあててそのままインターネットに公開している。
インスタンスタイプはt3a.nanoを使い、これは1hで0.0067USD@東京(月間5USDちょい)という低価格。
しかしオレゴンリージョンであればさらに0.0047USDに下がるという事で、東京リージョンからオレゴンリージョンに移設した。昨日。
東京リージョンで取得したAMIをオレゴンリージョンにコピー。EIPを新たに取得して、下方のCFnコードでスタック作成する。
便宜上jsonファイルは3つに分けている。
メンテナンス性は気にしていないが、実際面このシンプル構成だと全部作り直しで障害復旧とかできるので問題なかろう、である。
あとついでにIPv6対応してみた。IPv6設定で非常に有用な参考サイト 【備忘録】CloudFormationで IPv6 対応のVPCとサブネットを作る【CFn】 - サーバーワークス
それぞれのjsonコードが以下のような感じ。(使っていない設定も入っているが、気にしない)
{
"AWSTemplateFormatVersion" : "2010-09-09",
"Description" : "alterwoeks.tokyo env template. alterworks-aws-stack1-vpc",
"Parameters" : {
"APPParam" : {
"Type" : "String",
"Default" : "alterwoeks.tokyo",
"Description" : "eg. URL."
}
},
"Resources" : {
"AWTvpc" : {
"Type" : "AWS::EC2::VPC",
"Properties" : {
"CidrBlock" : "192.168.4.0/24",
"EnableDnsSupport" : "true",
"EnableDnsHostnames" : "true",
"InstanceTenancy" : "default",
"Tags" : [
{
"Key" : "Name",
"Value" : "AWTVPC"
},
{
"Key" : "APP",
"Value" : { "Ref" : "APPParam" }
}
]
}
},
"AWTvpcCidrBlock": {
"Type": "AWS::EC2::VPCCidrBlock",
"Properties": {
"VpcId": { "Ref" : "AWTvpc" },
"AmazonProvidedIpv6CidrBlock": true
}
},
"AWTSubnetAZa63pub" : {
"Type" : "AWS::EC2::Subnet",
"Properties" : {
"AssignIpv6AddressOnCreation" : "true",
"AvailabilityZone" : "us-west-2a",
"CidrBlock" : "192.168.4.0/26",
"MapPublicIpOnLaunch" : "true",
"Tags" : [
{
"Key" : "Name",
"Value" : "AWT-Subnet0-63pub"
},
{
"Key" : "APP",
"Value" : { "Ref" : "APPParam" }
}
],
"VpcId" : {"Ref" : "AWTvpc"},
"Ipv6CidrBlock": {
"Fn::Sub": [
"${VpcPart}${SubnetPart}",
{
"VpcPart": {
"Fn::Select": [
0,
{
"Fn::Split": [
"00::/56",
{
"Fn::Select": [
0,
{
"Fn::GetAtt": [
"AWTvpc",
"Ipv6CidrBlocks"
]
}
]
}
]
}
]
},
"SubnetPart": "01::/64"
}
]
}
},
"DependsOn" : "AWTvpcCidrBlock"
},
"AWTSubnetAZa127pri" : {
"Type" : "AWS::EC2::Subnet",
"Properties" : {
"AvailabilityZone" : "us-west-2a",
"CidrBlock" : "192.168.4.64/26",
"MapPublicIpOnLaunch" : "false",
"Tags" : [
{
"Key" : "Name",
"Value" : "AWT-Subnet64-127pri"
},
{
"Key" : "APP",
"Value" : { "Ref" : "APPParam" }
}
],
"VpcId" : {"Ref" : "AWTvpc"}
}
},
"AWTRouteTable1" : {
"Type" : "AWS::EC2::RouteTable",
"Properties" : {
"Tags" : [
{
"Key" : "Name",
"Value" : "AWT-RouteTable1"
},
{
"Key" : "APP",
"Value" : { "Ref" : "APPParam" }
}
],
"VpcId" : {"Ref" : "AWTvpc"}
}
},
"AWTRoute1" : {
"Type" : "AWS::EC2::Route",
"Properties" : {
"DestinationCidrBlock" : "0.0.0.0/0",
"GatewayId" : { "Ref" : "AWTigw" },
"RouteTableId" : { "Ref" : "AWTRouteTable1" }
},
"DependsOn" : "AWTigw"
},
"AWTRoute2" : {
"Type" : "AWS::EC2::Route",
"Properties" : {
"DestinationIpv6CidrBlock" : "::/0",
"GatewayId" : { "Ref" : "AWTigw" },
"RouteTableId" : { "Ref" : "AWTRouteTable1" }
},
"DependsOn" : "AWTigw"
},
"AWTRouteTable2" : {
"Type" : "AWS::EC2::RouteTable",
"Properties" : {
"Tags" : [
{
"Key" : "Name",
"Value" : "AWT-RouteTable2"
},
{
"Key" : "APP",
"Value" : { "Ref" : "APPParam" }
}
],
"VpcId" : {"Ref" : "AWTvpc"}
}
},
"AWTRouteTableAssoc1" : {
"Type" : "AWS::EC2::SubnetRouteTableAssociation",
"Properties" : {
"RouteTableId" : {"Ref" : "AWTRouteTable1"},
"SubnetId" : {"Ref" : "AWTSubnetAZa63pub"}
}
},
"AWTRouteTableAssoc2" : {
"Type" : "AWS::EC2::SubnetRouteTableAssociation",
"Properties" : {
"RouteTableId" : {"Ref" : "AWTRouteTable2"},
"SubnetId" : {"Ref" : "AWTSubnetAZa127pri"}
}
},
"AWTSGtoOffice" : {
"Type" : "AWS::EC2::SecurityGroup",
"Properties" : {
"GroupName" : "AWTtoOffice",
"GroupDescription" : "for My access",
"SecurityGroupIngress" : [
{
"CidrIp" : "133.200.193.160/32",
"Description" : "My outbounds IPv4",
"FromPort" : "0",
"IpProtocol" : "-1",
"ToPort" : "65535"
},
{
"CidrIpv6" : "2404:7a80:c1a0:3800::/64",
"Description" : "My outbounds IPv6",
"FromPort" : "0",
"IpProtocol" : "-1",
"ToPort" : "65535"
}
],
"SecurityGroupEgress" : [
{
"CidrIp" : "192.168.4.0/24",
"Description" : "Internal outbounds IPv4",
"FromPort" : "0",
"IpProtocol" : "-1",
"ToPort" : "65535"
}
],
"Tags" : [
{
"Key" : "Name",
"Value" : "AWTtoOffice"
},
{
"Key" : "APP",
"Value" : { "Ref" : "APPParam" }
}
],
"VpcId" : {"Ref" : "AWTvpc"}
}
},
"AWTSG1" : {
"Type" : "AWS::EC2::SecurityGroup",
"Properties" : {
"GroupName" : "AWTSG1",
"GroupDescription" : "for main-group",
"SecurityGroupEgress" : [
{
"CidrIp" : "0.0.0.0/0",
"Description" : "outbound IPv4 80",
"FromPort" : "80",
"IpProtocol" : "tcp",
"ToPort" : "80"
},
{
"CidrIp" : "0.0.0.0/0",
"Description" : "outbound IPv4 443",
"FromPort" : "443",
"IpProtocol" : "tcp",
"ToPort" : "443"
},
{
"CidrIpv6" : "::/0",
"Description" : "outbound IPv6 80",
"FromPort" : "80",
"IpProtocol" : "tcp",
"ToPort" : "80"
},
{
"CidrIpv6" : "::/0",
"Description" : "outbound IPv6 443",
"FromPort" : "443",
"IpProtocol" : "tcp",
"ToPort" : "443"
},
{
"CidrIp" : "0.0.0.0/0",
"Description" : "outbound IPv4 80 udp",
"FromPort" : "80",
"IpProtocol" : "udp",
"ToPort" : "80"
},
{
"CidrIp" : "0.0.0.0/0",
"Description" : "outbound IPv4 443 udp",
"FromPort" : "443",
"IpProtocol" : "udp",
"ToPort" : "443"
},
{
"CidrIpv6" : "::/0",
"Description" : "outbound IPv6 80 udp",
"FromPort" : "80",
"IpProtocol" : "udp",
"ToPort" : "80"
},
{
"CidrIpv6" : "::/0",
"Description" : "outbound IPv6 443 udp",
"FromPort" : "443",
"IpProtocol" : "udp",
"ToPort" : "443"
}
],
"SecurityGroupIngress" : [
{
"CidrIp" : "192.168.4.0/24",
"Description" : "All inbounds VPC",
"FromPort" : "0",
"IpProtocol" : "-1",
"ToPort" : "65535"
},
{
"CidrIp" : "0.0.0.0/0",
"Description" : "inbound IPv4 80",
"FromPort" : "80",
"IpProtocol" : "tcp",
"ToPort" : "80"
},
{
"CidrIp" : "0.0.0.0/0",
"Description" : "inbound IPv4 443",
"FromPort" : "443",
"IpProtocol" : "tcp",
"ToPort" : "443"
},
{
"CidrIpv6" : "::/0",
"Description" : "inbound IPv6 80",
"FromPort" : "80",
"IpProtocol" : "tcp",
"ToPort" : "80"
},
{
"CidrIpv6" : "::/0",
"Description" : "inbound IPv6 443",
"FromPort" : "443",
"IpProtocol" : "tcp",
"ToPort" : "443"
},
{
"CidrIp" : "0.0.0.0/0",
"Description" : "inbound IPv4 80 udp",
"FromPort" : "80",
"IpProtocol" : "udp",
"ToPort" : "80"
},
{
"CidrIp" : "0.0.0.0/0",
"Description" : "inbound IPv4 443 udp",
"FromPort" : "443",
"IpProtocol" : "udp",
"ToPort" : "443"
},
{
"CidrIpv6" : "::/0",
"Description" : "inbound IPv6 80 udp",
"FromPort" : "80",
"IpProtocol" : "udp",
"ToPort" : "80"
},
{
"CidrIpv6" : "::/0",
"Description" : "inbound IPv6 443 udp",
"FromPort" : "443",
"IpProtocol" : "udp",
"ToPort" : "443"
}
],
"Tags" : [
{
"Key" : "Name",
"Value" : "AWTSG1"
},
{
"Key" : "APP",
"Value" : { "Ref" : "APPParam" }
}
],
"VpcId" : {"Ref" : "AWTvpc"}
}
},
"AWTSG1Egress1" : {
"Type": "AWS::EC2::SecurityGroupEgress",
"Properties": {
"Description": "inMySG",
"DestinationSecurityGroupId": {"Fn::GetAtt" : ["AWTSG1","GroupId"]},
"FromPort": 0,
"GroupId": {"Fn::GetAtt" : ["AWTSG1","GroupId"]},
"IpProtocol": "-1",
"ToPort": 65535
}
},
"AWTSG1Ingress1": {
"Type": "AWS::EC2::SecurityGroupIngress",
"Properties": {
"Description": "inMySG",
"FromPort": 0,
"GroupId": {"Fn::GetAtt" : ["AWTSG1","GroupId"]},
"IpProtocol": "-1",
"SourceSecurityGroupId": {"Fn::GetAtt" : ["AWTSG1","GroupId"]},
"ToPort": 65535
}
},
"AWTigw" : {
"Type" : "AWS::EC2::InternetGateway",
"Properties" : {
"Tags" : [
{
"Key" : "Name",
"Value" : "AWT-igw"
},
{
"Key" : "APP",
"Value" : { "Ref" : "APPParam" }
}
]
}
},
"AWTigwAttach" : {
"Type" : "AWS::EC2::VPCGatewayAttachment",
"Properties" : {
"VpcId" : { "Ref" : "AWTvpc" },
"InternetGatewayId" : { "Ref" : "AWTigw" }
}
}
},
"Outputs" : {
"EXPAWTvpc" : {
"Description" : "Export AWTvpc",
"Value" : { "Ref" : "AWTvpc" },
"Export" : {"Name" : {"Fn::Sub": "${AWS::StackName}-vpc" }}
},
"EXPAWTSGtoOffice" : {
"Description" : "Export SGtoOffice",
"Value" : { "Ref" : "AWTSGtoOffice" },
"Export" : {"Name" : {"Fn::Sub": "${AWS::StackName}-SGtoOffice" }}
},
"EXPAWTSG1" : {
"Description" : "Export SG1",
"Value" : { "Ref" : "AWTSG1" },
"Export" : {"Name" : {"Fn::Sub": "${AWS::StackName}-SG1" }}
},
"EXPAWTSubnetA" : {
"Description" : "Export SubnetA",
"Value" : { "Ref" : "AWTSubnetAZa63pub" },
"Export" : {"Name" : {"Fn::Sub": "${AWS::StackName}-SubnetApub" }}
},
"EXPAWTSubnetB" : {
"Description" : "Export SubnetB",
"Value" : { "Ref" : "AWTSubnetAZa127pri" },
"Export" : {"Name" : {"Fn::Sub": "${AWS::StackName}-SubnetApri" }}
}
}
}
{
"AWSTemplateFormatVersion" : "2010-09-09",
"Description" : "alterworks.tokyo env template. alterworks-aws-stack2-iam",
"Parameters" : {
"NameParam" : {
"Type" : "String",
"Default" : "AWTTagEditRole",
"Description" : "eg. Role name."
},
"APPParam" : {
"Type" : "String",
"Default" : "alterwoeks.tokyo",
"Description" : "eg. URL."
}
},
"Resources" : {
"AWTTagRole" : {
"Type" : "AWS::IAM::Role",
"Properties" : {
"AssumeRolePolicyDocument": {
"Version" : "2012-10-17",
"Statement": [ {
"Effect": "Allow",
"Principal": {
"Service": [ "ec2.amazonaws.com" ]
},
"Action": [ "sts:AssumeRole" ]
} ]
},
"Description" : "Tag Edit Role",
"Path" : "/",
"RoleName" : "AWTTagEditRole",
"Tags" : [
{
"Key" : "Name",
"Value" : { "Ref" : "NameParam" }
},
{
"Key" : "APP",
"Value" : { "Ref" : "APPParam" }
}
]
}
},
"AWTTagPolicy" : {
"Type" : "AWS::IAM::Policy",
"Properties" : {
"PolicyDocument" : {
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"ec2:Describe*",
"ec2:CreateTags",
"ec2:DeleteTags"
],
"Resource": "*"
}
]
},
"PolicyName" : "AWTTagEditPolicy",
"Roles" : [ "AWTTagEditRole" ]
},
"DependsOn" : [ "AWTTagRole" ]
},
"AWTprofile" : {
"Type" : "AWS::IAM::InstanceProfile",
"Properties" : {
"InstanceProfileName" : "AWTTagEditRole",
"Path" : "/",
"Roles" : [ "AWTTagEditRole" ]
}
}
}
}
{
"AWSTemplateFormatVersion" : "2010-09-09",
"Description" : "alterworks.tokyo env template. alterworks-aws-stack3-instance",
"Parameters" : {
"NameParam" : {
"Type" : "String",
"Default" : "AWT1",
"Description" : "as hostname."
},
"ServerNameParam" : {
"Type" : "String",
"Default" : "input-Japanease-server-name",
"Description" : "as Japanease server name"
},
"APPParam" : {
"Type" : "String",
"Default" : "alterwoeks.tokyo",
"Description" : "as URL"
},
"EndpointParam" : {
"Type" : "String",
"Default" : "ec2.us-west-2.amazonaws.com",
"Description" : "as URL"
}
},
"Resources" : {
"AWTInstance1" : {
"Type" : "AWS::EC2::Instance",
"Properties" : {
"AvailabilityZone" : "us-west-2a",
"BlockDeviceMappings" : [
{
"DeviceName" : "/dev/xvda",
"Ebs" : { "DeleteOnTermination" : "true", "Encrypted" : "false", "VolumeSize" : "8", "VolumeType" : "gp2" }
}
],
"EbsOptimized" : "true",
"IamInstanceProfile" : "AWTTagEditRole",
"ImageId" : "<自己所有AMI-ID>",
"InstanceInitiatedShutdownBehavior" : "stop",
"InstanceType" : "t3a.nano",
"Monitoring" : "false",
"NetworkInterfaces" : [
{
"AssociatePublicIpAddress" : "false",
"DeleteOnTermination" : "true",
"Description" : "AWTENI1",
"DeviceIndex" : "0",
"GroupSet" : [
{
"Fn::ImportValue" : { "Fn::Sub" : "alterworks-aws-stack1-vpc-SGtoOffice" }
},
{
"Fn::ImportValue" : { "Fn::Sub" : "alterworks-aws-stack1-vpc-SG1" }
}
],
"PrivateIpAddress" : "192.168.4.16",
"SubnetId" : { "Fn::ImportValue" : { "Fn::Sub" : "alterworks-aws-stack1-vpc-SubnetApub" } }
}
],
"Tags" : [
{
"Key" : "Name",
"Value" : { "Ref" : "NameParam" }
},
{
"Key" : "ServerName",
"Value" : { "Ref" : "ServerNameParam" }
},
{
"Key" : "APP",
"Value" : { "Ref" : "APPParam" }
}
],
"Tenancy" : "default",
"UserData" : { "Fn::Base64" : { "Fn::Join" : [ "", [
"#cloud-config\n",
"#vim:syntax=yaml\n",
"users:\n",
"# A user by the name `ec2-user` is created in the image by default.\n",
" - default\n",
" - name: amaster\n",
" gecos: 'amazonLinux2 master'\n",
" groups: wheel\n",
" sudo: ['ALL=(ALL) NOPASSWD:ALL']\n",
" ssh-authorized-keys:\n",
" - ssh-rsa <自前のauthorized_keysに登録するやつ>\n",
" lock_passwd: true\n",
"chpasswd:\n",
" list: |\n",
" ec2-user:password-DUMMYuser\n",
"# In the above line, do not add any spaces after 'ec2-user:'.\n",
"write_files:\n",
" - path: /etc/cloud/cloud.cfg.d/80_disable_network_after_firstboot.cfg\n",
" content: |\n",
" # Disable network configuration after first boot\n",
" manage_resolv_conf: false\n",
" network:\n",
" config: disabled\n",
" - path: /tmp/awscli-def.config\n",
" content: |\n",
" \n",
" \n",
" us-west-2\n",
" json\n",
"ssh_deletekeys: true\n",
"packages:\n",
" - expect.x86_64\n",
"runcmd:\n",
" - hostnamectl set-hostname ",{ "Ref" : "NameParam" },"\n",
" - aws configure < /tmp/awscli-def.config\n",
" - AWS_AVAIL_ZONE=$(curl http://169.254.169.254/latest/meta-data/placement/availability-zone)\n",
" - AWS_REGION=${AWS_AVAIL_ZONE::-1}\n",
" - AWS_INSTANCE_ID=$(curl http://169.254.169.254/latest/meta-data/instance-id)\n",
" - AWS_ENDPOINT=",{ "Ref" : "EndpointParam" },"\n",
" - ROOT_VOLUME_IDS=$(aws --endpoint-url https://$AWS_ENDPOINT/ ec2 describe-instances --region $AWS_REGION --instance-id $AWS_INSTANCE_ID --output text --query Reservations[0].Instances[0].BlockDeviceMappings[0].Ebs.VolumeId)\n",
" - aws --endpoint-url https://$AWS_ENDPOINT/ ec2 create-tags --resources $ROOT_VOLUME_IDS --region $AWS_REGION --tags Key=Name,Value=",{ "Ref" : "NameParam" },"\n",
" - aws --endpoint-url https://$AWS_ENDPOINT/ ec2 create-tags --resources $ROOT_VOLUME_IDS --region $AWS_REGION --tags Key=APP,Value=",{ "Ref" : "APPParam" },"\n",
"disable_root: true\n"
]]}}
}
},
"AWTInstance1EIPAssoc": {
"Type": "AWS::EC2::EIPAssociation",
"Properties": {
"EIP": "54.245.2.180",
"InstanceId": {"Ref" : "AWTInstance1"}
}
}
}
}
今回はここまで