1.AWSCli
便利なCLIコマンド
EC2
EC2起動
aws ec2 start-instances --instance-ids [インスタンスID]
EC2停止
aws ec2 stop-instances --instance-ids [インスタンスID]
EC2再起動
aws ec2 reboot-instances --instance-ids [インスタンスID]
EC2削除
aws ec2 terminate-instances --instance-ids [インスタンスID]
EC2インスタンス閲覧(全体)
aws ec2 describe-instances
InstanceName=ro
aws ec2 describe-instances | jq -r --arg a ${InstanceName} '.Reservations[].Instances[]|select((.Tags[].Key == "Name") and (.Tags[].Value == $a))|.InstanceId'
i-0bf497983eb463f50
EC2インスタンス閲覧(特定)
aws ec2 describe-instances --instance-ids [インスタンスID]
EC2インスタンス自ホスト情報閲覧(例はインスタンスID表示)
curl 169.254.169.254/latest/meta-data/instance-id/
EC2インスタンス作成用 Sample JSONファイル作成
aws ec2 run-instances --generate-cli-skeleton > run-instances-test.json
EC2インスタンス作成用JSONファイル作成
aws ec2 run-instances --cli-input-json file://run-instances-test.json
次の構成でインスタンスを作成してみます。
- Amazon Linux
- t2.micro
- key-name の指定
- 既存のsecurity-groupの指定
- subnet-id の指定
- secondary-private-ip-addressesの指定
- associate-public-ip-address
- 20GBのEBSの割当
[実行結果]
$ aws ec2 run-instances --image-id ami-xxxxxxxx --instance-type t2.micro --key-name test-xxxxxxxx --subnet-id subnet-xxxxxxxx --security-group-ids sg-xxxxxxaa sg-xxxxxxbb --secondary-private-ip-addresses 192.168.1.99
--associate-public-ip-address --block-device-mappings "[{\"DeviceName\": \"/dev/xvda\",\"Ebs\":{\"Vo
lumeSize\":20}}]"
{
"OwnerId": "xxxxxxxxxxxx",
"ReservationId": "r-xxxxxxxx",
"Groups": [],
"Instances": [
{
"Monitoring": {
"State": "disabled"
},
"PublicDnsName": "",
"RootDeviceType": "ebs",
"State": {
"Code": 0,
"Name": "pending"
},
"EbsOptimized": false,
"LaunchTime": "2015-08-18T01:36:45.000Z",
"PrivateIpAddress": "192.168.1.178",
"ProductCodes": [],
"VpcId": "vpc-xxxxxxxx",
"StateTransitionReason": "",
"InstanceId": "i-xxxxxxxx",
"ImageId": "ami-cbf90ecb",
"PrivateDnsName": "ip-192-168-1-178.ap-northeast-1.compute.internal",
"KeyName": "test-xxxxxxxx",
"SecurityGroups": [
{
"GroupName": "https only",
"GroupId": "sg-xxxxxxaa"
},
{
"GroupName": "ssh-only",
"GroupId": "sg-xxxxxxbb"
}
],
"ClientToken": "",
"SubnetId": "subnet-xxxxxxxx",
"InstanceType": "t2.micro",
"NetworkInterfaces": [
{
"Status": "in-use",
"MacAddress": "06:60:51:02:cd:d1",
"SourceDestCheck": true,
"VpcId": "vpc-xxxxxxxx",
"Description": "",
"NetworkInterfaceId": "eni-xxxxxxxx",
"PrivateIpAddresses": [
{
"Primary": true,
"PrivateIpAddress": "192.168.1.178"
},
{
"PrivateDnsName": "",
"Primary": false,
"PrivateIpAddress": "192.168.1.99"
}
],
"Attachment": {
"Status": "attaching",
"DeviceIndex": 0,
"DeleteOnTermination": true,
"AttachmentId": "eni-attach-xxxxxxxx",
"AttachTime": "2015-08-18T01:36:45.000Z"
},
"Groups": [
{
"GroupName": "https only",
"GroupId": "sg-xxxxxxaa"
},
{
"GroupName": "ssh-only",
"GroupId": "sg-xxxxxxxxbb"
}
],
"SubnetId": "subnet-xxxxxxxx",
"OwnerId": "xxxxxxxxxxxx",
"PrivateIpAddress": "192.168.1.178"
}
],
"SourceDestCheck": true,
"Placement": {
"Tenancy": "default",
"GroupName": "",
"AvailabilityZone": "ap-northeast-1a"
},
"Hypervisor": "xen",
"BlockDeviceMappings": [],
"Architecture": "x86_64",
"StateReason": {
"Message": "pending",
"Code": "pending"
},
"RootDeviceName": "/dev/xvda",
"VirtualizationType": "hvm",
"AmiLaunchIndex": 0
}
]
}
RDS
RDS情報閲覧(全体)
aws rds describe-db-instances
RDS情報閲覧(特定)
aws rds describe-db-instances --db-instance-identifier [RDS識別子]
RDS起動
aws rds start-db-instance --db-instance-identifier [RDS識別子]
RDS停止
aws rds stop-db-instance --db-instance-identifier [RDS識別子]
RDS再起動
aws rds reboot-db-instance --db-instance-identifier [RDS識別子]
RDS削除
aws rds delete-db-instance --db-instance-identifier [RDS識別子]
RDS起動ステータス確認(起動/停止の振り逃げ待ち後に実施するのが便利)
aws rds describe-db-instances --db-instance-identifier [RDS識別子] | jq -r '.DBInstances[].DBInstanceStatus'
RDSログファイル一覧
aws rds describe-db-log-files --db-instance-identifier [RDS識別子]
RDSログファイル一覧(検索)
aws rds describe-db-log-files --db-instance-identifier [RDS識別子]
--filename-contains <ログ名> --output text
RDSログ出力
aws rds download-db-log-file-portion --db-instance-identifier auro-pos-inst --log-file-name <ログ名>
基本JSONで出るが、テキスト形式で出力することも可能。
[root@ro ~]# aws rds download-db-log-file-portion --db-instance-identifier auro-pos-inst --log-file-name error/postgres.log --output text
2019-08-24 17:15:12.427 GMT [5563] LOG: skipping missing configuration file "/rdsdbdata/db/postgresql.auto.conf"
2019-08-24 17:15:12 UTC::@:[5563]:WARNING: unrecognized configuration parameter "rds.enable_plan_management"
2019-08-24 17:15:12 UTC::@:[5563]:LOG: database system is shut down
Postgres Shared Memory Value: 2344689664 bytes
2019-08-24 17:15:13.980 GMT [5687] LOG: skipping missing configuration file "/rdsdbdata/db/postgresql.auto.conf"
2019-08-24 17:15:13 UTC::@:[5687]:WARNING: unrecognized configuration parameter "rds.enable_plan_management"
2019-08-24 17:15:13 UTC::@:[5687]:LOG: listening on IPv4 address "0.0.0.0", port 5432
2019-08-24 17:15:13 UTC::@:[5687]:LOG: listening on IPv6 address "::", port 5432
2019-08-24 17:15:13 UTC::@:[5687]:LOG: listening on Unix socket "/tmp/.s.PGSQL.5432"
2019-08-24 17:15:14 UTC::@:[5687]:LOG: could not write pg_stat_statement file "pg_stat_tmp/pgss_query_texts.stat": No such file or directory
2019-08-24 17:15:14 UTC::@:[5687]:LOG: redirecting log output to logging collector process
2019-08-24 17:15:14 UTC::@:[5687]:HINT: Future log output will appear in directory "/rdsdbdata/log/error".
2019-08-24 17:15:32 UTC::@:[5824]:LOG: skipping missing configuration file "/rdsdbdata/db/postgresql.auto.conf"
2019-08-24 17:16:28 UTC::@:[5824]:LOG: skipping missing configuration file "/rdsdbdata/db/postgresql.auto.conf"
2019-08-24 17:17:39.819 GMT [9420] LOG: skipping missing configuration file "/rdsdbdata/db/postgresql.auto.conf"
2019-08-24 17:17:39 UTC::@:[9420]:WARNING: unrecognized configuration parameter "rds.enable_plan_management"
2019-08-24 17:17:39 UTC::@:[9420]:LOG: database system is shut down
Postgres Shared Memory Value: 2344689664 bytes
2019-08-24 17:17:40.321 GMT [9489] LOG: skipping missing configuration file "/rdsdbdata/db/postgresql.auto.conf"
2019-08-24 17:17:40 UTC::@:[9489]:WARNING: unrecognized configuration parameter "rds.enable_plan_management"
2019-08-24 17:17:40 UTC::@:[9489]:LOG: listening on IPv4 address "0.0.0.0", port 5432
2019-08-24 17:17:40 UTC::@:[9489]:LOG: listening on IPv6 address "::", port 5432
2019-08-24 17:17:40 UTC::@:[9489]:LOG: listening on Unix socket "/tmp/.s.PGSQL.5432"
2019-08-24 17:17:40 UTC::@:[9489]:LOG: redirecting log output to logging collector process
2019-08-24 17:17:40 UTC::@:[9489]:HINT: Future log output will appear in directory "/rdsdbdata/log/error".
※Auroraクラスタ用
RDSクラスタ情報閲覧(全体)
aws rds describe-db-clusters
RDSクラスタ情報閲覧(全体)
aws rds describe-db-clusters --db-instance-identifier [RDSクラスタ名]
RDS起動
aws rds start-db-cluster --db-cluster-identifier [RDS識別子]
RDS停止
aws rds stop-db-cluster --db-cluster-identifier [RDS識別子]
S3
cp,mv,syncはS3バケット to S3バケットも可能
S3一覧表示
aws s3 ls
S3の中身表示
aws s3 ls s3://{バケット名}/{パス}
バケットを作成する
aws s3 mb s3://{バケット名}
バケットを削除する(空でない場合は削除されない)
aws s3 rb s3://{バケット名}
バケットを削除する(空でなくても削除される)
aws s3 rb s3://{バケット名} --force
バケットの内容をローカルのフォルダと同期する(追加・更新のみで削除されない)
aws s3 sync {フォルダパス} s3://{バケット名}/{パス}
バケットの内容をローカルのフォルダと同期する(削除もされる)
aws s3 sync {フォルダパス} s3://{バケット名}/{パス} --delete
ローカルのファイルをバケットにコピーする
aws s3 cp {ファイルパス} s3://{バケット名}/{パス}
ローカルのファイルをバケットに移動する
aws s3 mv {ファイルパス} s3://{バケット名}/{パス}
バケットのファイルを削除する
aws s3 rm s3://{バケット名}/{ファイルパス}
バケットのフォルダを削除する
aws s3 rm s3://{バケット名}/{フォルダパス} --recursive
S3でfind的な処理をする(cp,mv,rm)
aws s3 cp s3://{バケット名}/{prefix} --recursive --exclude "*" --include "*検索条件*"
EIP
新規Elastic IP発行
aws ec2 allocate-address --domain vpc
Elasitc IPをインスタンスに関連付け
aws ec2 associate-address --allocation-id {allocation-id} --instance {instance-id}
Elasitc IPの関連付けを外す
aws ec2 disassociate-address --association-id {association-id}
Elasitc IPを開放(消す)
aws ec2 release-address --allocation-id {allocation-id}
Route53
ホストゾーン一覧
aws route53 list-hosted-zones
DNSレコード閲覧
aws route53 list-resource-record-sets --hosted-zone-id ${HOSTZONE}
DNSレコード更新
aws route53 change-resource-record-sets --hosted-zone-id ${HOSTZONE} --change-batch file://[OS上フルパス]
{
"Changes": [
{
"Action": "UPSERT",
"ResourceRecordSet": {
"Name": "XXXXXXX.",
"Type": "A",
"TTL": 600,
"ResourceRecords": [
{
"Value": "XXXXX"
}
]
}
}
]
}
{
"Changes": [
{
"Action": "DELETE",
"ResourceRecordSet": {
"Name": "XXXXXXX.",
"Type": "A",
"TTL": 600,
"ResourceRecords": [
{
"Value": "XXXXX"
}
]
}
}
]
}
aws route53 change-resource-record-sets下記のようなレスポンスがあり
{
"ChangeInfo": {
"Status": "PENDING",
"SubmittedAt": "2019-08-18T13:04:06.280Z",
"Id": "/change/C3BRXQ3SIAXYU5"
}
}
⇒PENDINGからINSYNCステータスになればDNS設定反映完了。確認の仕方としては上記のIdが必要
aws route53 get-change --id "/change/C3BRXQ3SIAXYU5";
{
"ChangeInfo": {
"Status": "INSYNC",
"SubmittedAt": "2019-08-18T13:04:06.280Z",
"Id": "/change/C3BRXQ3SIAXYU5"
}
}
2.CloudFormationによる構築自動化
構築自動化ツール。構築を自動化できるので非常に重宝する。
JSONかYAML形式で記載したコード(Template)からデプロイ。
# Templateの構文チェック。ダメな時はRC=0以外が返ってくる。
aws cloudformation validate-template --template-body file:///cloudformation/template/vpcnwcreate.yml
# スタック作成。CLI上は振り逃げ。
aws cloudformation create-stack --template-body file:///cloudformation/template/vpcnwcreate.yml --stack-name cloudformation-test1
# スタック構成確認。StackStatusで作成中、削除中等状態確認もできる
aws cloudformation describe-stacks --stack-name cloudformation-test1
# スタック削除。CLI上は振り逃げで何も表示されない
aws cloudformation delete-stack --stack-name cloudformation-test1
---
AWSTemplateFormatVersion: '2010-09-09'
Parameters:
ProjectCode:
Type: String
Default: CloudFormation-v1
Description: Project Code
VPCCidr:
Type: String
Default: 172.32.0.0/16
Description: VPCCidr
PublicSubnetCidr1:
Type: String
Default: 172.32.10.0/24
Description: PublicSubnetCidr1
PublicSubnetCidr2:
Type: String
Default: 172.32.20.0/24
Description: PublicSubnetCidr2
PrivateSubnetCidr1:
Type: String
Default: 172.32.30.0/24
Description: PrivateSubnetCidr1
PrivateSubnetCidr2:
Type: String
Default: 172.32.40.0/24
Description: PrivateSubnetCidr2
Resources:
VPC:
Type: AWS::EC2::VPC
Properties:
CidrBlock: !Ref VPCCidr
Tags:
- Key: Name
Value: !Join [ "-", [ !Ref ProjectCode, vpc ] ]
InternetGateway:
Type: AWS::EC2::InternetGateway
Properties:
Tags:
- Key: Name
Value: !Join [ "-", [ !Ref ProjectCode, igw ] ]
AttachGateway:
Type: AWS::EC2::VPCGatewayAttachment
Properties:
VpcId: !Ref VPC
InternetGatewayId: !Ref InternetGateway
PublicRouteTableIGW:
Type: AWS::EC2::RouteTable
DependsOn: AttachGateway
Properties:
VpcId: !Ref VPC
Tags:
- Key: Name
Value: !Join [ "-", [ !Ref ProjectCode, public-route-table-igw ] ]
PublicRouteIGW:
Type: AWS::EC2::Route
DependsOn: AttachGateway
Properties:
RouteTableId: !Ref PublicRouteTableIGW
DestinationCidrBlock: 0.0.0.0/0
GatewayId: !Ref InternetGateway
PublicSubnet1:
Type: AWS::EC2::Subnet
DependsOn: AttachGateway
Properties:
VpcId: !Ref VPC
AvailabilityZone: us-east-1a
CidrBlock: !Ref PublicSubnetCidr1
Tags:
- Key: Name
Value: !Join [ "-", [ !Ref ProjectCode, PublicSubnet1 ] ]
PublicSubnet2:
Type: AWS::EC2::Subnet
DependsOn: AttachGateway
Properties:
VpcId: !Ref VPC
AvailabilityZone: us-east-1b
CidrBlock: !Ref PublicSubnetCidr2
Tags:
- Key: Name
Value: !Join [ "-", [ !Ref ProjectCode, PublicSubnet2 ] ]
PrivateSubnet1:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref VPC
AvailabilityZone: us-east-1a
CidrBlock: !Ref PrivateSubnetCidr1
Tags:
- Key: Name
Value: !Join [ "-", [ !Ref ProjectCode, PrivateSubnet1 ] ]
PrivateSubnet2:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref VPC
AvailabilityZone: us-east-1b
CidrBlock: !Ref PrivateSubnetCidr2
Tags:
- Key: Name
Value: !Join [ "-", [ !Ref ProjectCode, PrivateSubnet2 ] ]
PublicSubnet1RouteTableAssociation:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
SubnetId:
Ref: PublicSubnet1
RouteTableId:
Ref: PublicRouteTableIGW
PublicSubnet2RouteTableAssociation:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
SubnetId:
Ref: PublicSubnet2
RouteTableId:
Ref: PublicRouteTableIGW
NatGateway:
Type: AWS::EC2::NatGateway
DependsOn: AttachGateway
Properties:
AllocationId:
Fn::GetAtt: [ EIP, AllocationId ]
SubnetId:
Ref: PublicSubnet1
Tags:
- Key: Name
Value: !Join [ "-", [ !Ref ProjectCode, NatGateway ] ]
EIP:
Type: AWS::EC2::EIP
Properties:
Domain: vpc
PrivateRouteTable:
Type: AWS::EC2::RouteTable
Properties:
VpcId: !Ref VPC
Tags:
- Key: Name
Value: !Join [ "-", [ !Ref ProjectCode, private-route-table ] ]
PrivateRoute:
Type: AWS::EC2::Route
DependsOn: NatGateway
Properties:
RouteTableId: !Ref PrivateRouteTable
DestinationCidrBlock: 0.0.0.0/0
NatGatewayId: !Ref NatGateway
PrivateSubnet1RouteTableAssociation:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
SubnetId:
Ref: PrivateSubnet1
RouteTableId:
Ref: PrivateRouteTable
PrivateSubnet2RouteTableAssociation:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
SubnetId:
Ref: PrivateSubnet2
RouteTableId:
Ref: PrivateRouteTable
AWSTemplateFormatVersion: '2010-09-09'
Description: This CloudFormation template to create EC2 instances.
Parameters:
MyVpcId:
Type: AWS::EC2::VPC::Id
MySubnetId1:
Type: AWS::EC2::Subnet::Id
MySubnetId2:
Type: AWS::EC2::Subnet::Id
MyKeyName:
Type: AWS::EC2::KeyPair::KeyName
Default: aws
Mappings:
Prod:
ApEc2Instance:
InstanceType: t2.micro
AmiId: ami-0b898040803850657
RootVolumeSize: 10
DataVolumeSize: 20
Ap1:
Hostname: app1
Resources:
MyEc2SecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: Enable ssh access to the instances
VpcId: !Ref MyVpcId
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: 22
ToPort: 22
CidrIp: 0.0.0.0/0
- IpProtocol: tcp
FromPort: 80
ToPort: 80
CidrIp: 0.0.0.0/0
MyEc2Instance1:
Type: AWS::EC2::Instance
Properties:
InstanceType: !FindInMap [ Prod, ApEc2Instance, InstanceType ]
ImageId: !FindInMap [ Prod, ApEc2Instance, AmiId ]
SubnetId: !Ref MySubnetId1
SecurityGroupIds:
- !GetAtt MyEc2SecurityGroup.GroupId
KeyName: !Ref MyKeyName
BlockDeviceMappings:
- DeviceName: /dev/xvda
Ebs:
VolumeType: gp2
VolumeSize: !FindInMap [ Prod, ApEc2Instance, RootVolumeSize ]
DeleteOnTermination: true
- DeviceName: /dev/xvdf
Ebs:
VolumeType: gp2
VolumeSize: !FindInMap [ Prod, ApEc2Instance, DataVolumeSize ]
DeleteOnTermination: true
InstanceInitiatedShutdownBehavior: stop
Tenancy: default
UserData:
Fn::Base64: !Sub |
#!/bin/bash
yum -y update
yum -y install nginx && systemctl enable nginx && systemctl start nginx
Tags:
- Key: Name
Value: !FindInMap [ Prod, Ap1,Hostname ]
MyEip1:
Type: AWS::EC2::EIP
Properties:
InstanceId: !Ref MyEc2Instance1
Domain: vpc
AWSTemplateFormatVersion: '2010-09-09'
Description: This CloudFormation template to create EC2 instances.
Parameters:
MyVpcId:
Type: AWS::EC2::VPC::Id
MySubnetId1:
Type: AWS::EC2::Subnet::Id
MySubnetId2:
Type: AWS::EC2::Subnet::Id
MyKeyName:
Type: AWS::EC2::KeyPair::KeyName
Default: aws
Mappings:
Prod:
ApEc2Instance:
InstanceType: t2.micro
AmiId: ami-0b898040803850657
RootVolumeSize: 10
DataVolumeSize: 20
Ap1:
Hostname: app1
Ap2:
Hostname: app2
Resources:
MyEc2SecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: Enable ssh access to the instances
VpcId: !Ref MyVpcId
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: 22
ToPort: 22
CidrIp: 0.0.0.0/0
- IpProtocol: tcp
FromPort: 80
ToPort: 80
CidrIp: 0.0.0.0/0
MyEc2Instance1:
Type: AWS::EC2::Instance
Properties:
InstanceType: !FindInMap [ Prod, ApEc2Instance, InstanceType ]
ImageId: !FindInMap [ Prod, ApEc2Instance, AmiId ]
SubnetId: !Ref MySubnetId1
SecurityGroupIds:
- !GetAtt MyEc2SecurityGroup.GroupId
KeyName: !Ref MyKeyName
BlockDeviceMappings:
- DeviceName: /dev/xvda
Ebs:
VolumeType: gp2
VolumeSize: !FindInMap [ Prod, ApEc2Instance, RootVolumeSize ]
DeleteOnTermination: true
- DeviceName: /dev/xvdf
Ebs:
VolumeType: gp2
VolumeSize: !FindInMap [ Prod, ApEc2Instance, DataVolumeSize ]
DeleteOnTermination: true
InstanceInitiatedShutdownBehavior: stop
Tenancy: default
UserData:
Fn::Base64: !Sub |
#!/bin/bash
yum -y update
yum -y install nginx && systemctl enable nginx && systemctl start nginx
Tags:
- Key: Name
Value: !FindInMap [ Prod, Ap1,Hostname ]
MyEc2Instance2:
Type: AWS::EC2::Instance
Properties:
InstanceType: !FindInMap [ Prod, ApEc2Instance, InstanceType ]
ImageId: !FindInMap [ Prod, ApEc2Instance, AmiId ]
SubnetId: !Ref MySubnetId2
SecurityGroupIds:
- !GetAtt MyEc2SecurityGroup.GroupId
KeyName: !Ref MyKeyName
BlockDeviceMappings:
- DeviceName: /dev/xvda
Ebs:
VolumeType: gp2
VolumeSize: !FindInMap [ Prod, ApEc2Instance, RootVolumeSize ]
DeleteOnTermination: true
- DeviceName: /dev/xvdf
Ebs:
VolumeType: gp2
VolumeSize: !FindInMap [ Prod, ApEc2Instance, DataVolumeSize ]
DeleteOnTermination: true
InstanceInitiatedShutdownBehavior: stop
Tenancy: default
UserData:
Fn::Base64: !Sub |
#!/bin/bash
yum -y update
yum -y install nginx && systemctl enable nginx && systemctl start nginx
Tags:
- Key: Name
Value: !FindInMap [ Prod, Ap2,Hostname ]
MyEip1:
Type: AWS::EC2::EIP
Properties:
InstanceId: !Ref MyEc2Instance1
Domain: vpc
MyEip2:
Type: AWS::EC2::EIP
Properties:
InstanceId: !Ref MyEc2Instance2
Domain: vpc
AWSTemplateFormatVersion: '2010-09-09'
Description: This CloudFormation template to create EC2 instances.
Parameters:
MyVpcId:
Type: AWS::EC2::VPC::Id
MySubnetId1:
Type: AWS::EC2::Subnet::Id
MySubnetId2:
Type: AWS::EC2::Subnet::Id
MyInstance1:
Type: AWS::EC2::Instance::Id
MyInstance2:
Type: AWS::EC2::Instance::Id
Resources:
MyElbSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupName: MyElbSecurityGroup
GroupDescription: Enable ssh access to the instances
VpcId: !Ref MyVpcId
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: 80
ToPort: 80
CidrIp: 0.0.0.0/0
- IpProtocol: tcp
FromPort: 443
ToPort: 443
CidrIp: 0.0.0.0/0
MyTargetGroup:
Type: AWS::ElasticLoadBalancingV2::TargetGroup
Properties:
HealthCheckIntervalSeconds: 30
HealthCheckPath: /status
HealthCheckPort: 80
HealthCheckProtocol: HTTP
HealthCheckTimeoutSeconds: 10 # NLB では削除。
HealthyThresholdCount: 4
Matcher: # NLB では削除。
HttpCode: 200
Name: MyTargetGroup
Port: 80
Protocol: HTTP # NLB では "TCP"
Targets:
- Id: !Ref MyInstance1
Port: 80
- Id: !Ref MyInstance2
Port: 80
UnhealthyThresholdCount: 3
VpcId: !Ref MyVpcId
MyElb:
Type: AWS::ElasticLoadBalancingV2::LoadBalancer
Properties:
Name: MyELbName
Scheme: internet-facing
SecurityGroups:
- !Ref MyElbSecurityGroup
Subnets:
- !Ref MySubnetId1
- !Ref MySubnetId2
Type: application # NLB では "network"
MyListener:
Type: AWS::ElasticLoadBalancingV2::Listener
Properties:
DefaultActions:
- TargetGroupArn: !Ref MyTargetGroup
Type: forward
LoadBalancerArn: !Ref MyElb
Port: 80
Protocol: HTTP # NLB では "TCP"
AWSTemplateFormatVersion: '2010-09-09'
Description: This CloudFormation template to create EC2 instances & ALB.
Parameters:
MyVpcId:
Type: AWS::EC2::VPC::Id
MySubnetId1:
Type: AWS::EC2::Subnet::Id
MySubnetId2:
Type: AWS::EC2::Subnet::Id
MyKeyName:
Type: AWS::EC2::KeyPair::KeyName
Default: aws
MyImageId:
Type: AWS::EC2::Image::Id
Default: ami-0b898040803850657
Mappings:
Prod:
ApEc2Instance:
InstanceType: t2.micro
RootVolumeSize: 12
Ap1:
Hostname: app1
Ap2:
Hostname: app2
Resources:
MyEc2SecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: Enable ssh access to the instances
VpcId: !Ref MyVpcId
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: 22
ToPort: 22
CidrIp: 0.0.0.0/0
- IpProtocol: tcp
FromPort: 80
ToPort: 80
CidrIp: 0.0.0.0/0
MyEc2Instance1:
Type: AWS::EC2::Instance
Properties:
InstanceType: !FindInMap [ Prod, ApEc2Instance, InstanceType ]
ImageId: !Ref MyImageId
SubnetId: !Ref MySubnetId1
SecurityGroupIds:
- !GetAtt MyEc2SecurityGroup.GroupId
KeyName: !Ref MyKeyName
BlockDeviceMappings:
- DeviceName: /dev/xvda
Ebs:
VolumeType: gp2
VolumeSize: !FindInMap [ Prod, ApEc2Instance, RootVolumeSize ]
Encrypted: true
DeleteOnTermination: true
InstanceInitiatedShutdownBehavior: stop
Tenancy: default
UserData:
Fn::Base64: !Sub |
#!/bin/bash
echo | amazon-linux-extras install nginx1.12 && systemctl enable nginx && systemctl start nginx
yum -y update
Tags:
- Key: Name
Value: !FindInMap [ Prod, Ap1,Hostname ]
MyEc2Instance2:
Type: AWS::EC2::Instance
Properties:
InstanceType: !FindInMap [ Prod, ApEc2Instance, InstanceType ]
ImageId: !Ref MyImageId
SubnetId: !Ref MySubnetId2
SecurityGroupIds:
- !GetAtt MyEc2SecurityGroup.GroupId
KeyName: !Ref MyKeyName
BlockDeviceMappings:
- DeviceName: /dev/xvda
Ebs:
VolumeType: gp2
VolumeSize: !FindInMap [ Prod, ApEc2Instance, RootVolumeSize ]
Encrypted: true
DeleteOnTermination: true
InstanceInitiatedShutdownBehavior: stop
Tenancy: default
UserData:
Fn::Base64: !Sub |
#!/bin/bash
echo | amazon-linux-extras install nginx1.12 && systemctl enable nginx && systemctl start nginx
yum -y update
Tags:
- Key: Name
Value: !FindInMap [ Prod, Ap2,Hostname ]
MyEip1:
Type: AWS::EC2::EIP
Properties:
InstanceId: !Ref MyEc2Instance1
Domain: vpc
MyEip2:
Type: AWS::EC2::EIP
Properties:
InstanceId: !Ref MyEc2Instance2
Domain: vpc
MyElbSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupName: MyElbSecurityGroup
GroupDescription: Enable ssh access to the instances
VpcId: !Ref MyVpcId
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: 80
ToPort: 80
CidrIp: 0.0.0.0/0
- IpProtocol: tcp
FromPort: 443
ToPort: 443
CidrIp: 0.0.0.0/0
MyTargetGroup:
Type: AWS::ElasticLoadBalancingV2::TargetGroup
Properties:
HealthCheckIntervalSeconds: 30
HealthCheckPath: /status
HealthCheckPort: 80
HealthCheckProtocol: HTTP
HealthCheckTimeoutSeconds: 10 # NLB では削除。
HealthyThresholdCount: 4
Matcher: # NLB では削除。
HttpCode: 200
Name: MyTargetGroup
Port: 80
Protocol: HTTP # NLB では "TCP"
Targets:
- Id: !Ref MyEc2Instance1
Port: 80
- Id: !Ref MyEc2Instance2
Port: 80
UnhealthyThresholdCount: 3
VpcId: !Ref MyVpcId
MyElb:
Type: AWS::ElasticLoadBalancingV2::LoadBalancer
Properties:
Name: MyELbName
Scheme: internet-facing
SecurityGroups:
- !Ref MyElbSecurityGroup
Subnets:
- !Ref MySubnetId1
- !Ref MySubnetId2
Type: application # NLB では "network"
MyListener:
Type: AWS::ElasticLoadBalancingV2::Listener
Properties:
DefaultActions:
- TargetGroupArn: !Ref MyTargetGroup
Type: forward
LoadBalancerArn: !Ref MyElb
Port: 80
Protocol: HTTP # NLB では "TCP"
AWSTemplateFormatVersion: "2010-09-09"
Resources:
S3AccessRole:
Type: "AWS::IAM::Role"
Properties:
AssumeRolePolicyDocument:
Version: "2012-10-17"
Statement:
-
Effect: "Allow"
Principal:
Service:
- "ec2.amazonaws.com"
Action:
- "sts:AssumeRole"
Path: "/"
S3AccessPolicies:
Type: "AWS::IAM::Policy"
Properties:
PolicyName: "S3Access"
PolicyDocument:
Version: "2012-10-17"
Statement:
-
Effect: "Allow"
Action: "*"
Resource: "- arn:aws:s3:::test12349999"
-
Effect: "Allow"
Action:
- s3:ListAllMyBuckets
Resource: "- arn:aws:s3:::*"
Roles:
- !Ref S3AccessRole
S3AccessInstanceProfile:
Type: "AWS::IAM::InstanceProfile"
Properties:
Path: "/"
Roles:
- !Ref S3AccessRole
(参考)主なParameter Type指定可能一覧
AWS::EC2::KeyPair::KeyName
AWS::EC2::SecurityGroup::Id
AWS::EC2::Subnet::Id
AWS::EC2::VPC::Id
ListAWS::EC2::VPC::Id
ListAWS::EC2::SecurityGroup::Id
ListAWS::EC2::Subnet::Id
AWS::EC2::AvailabilityZone::Name
ListAWS::EC2::AvailabilityZone::Name
AWS::EC2::Instance::Id
ListAWS::EC2::Instance::Id
AWS::EC2::Image::Id
ListAWS::EC2::Image::Id
AWS::EC2::SecurityGroup::GroupName
ListAWS::EC2::SecurityGroup::GroupName
AWS::EC2::Volume::Id
ListAWS::EC2::Volume::Id
AWS::Route53::HostedZone::Id
ListAWS::Route53::HostedZone::Id
AWSTemplateFormatVersion: '2010-09-09'
Description: This CloudFormation template to create RDS db instances.
Mappings:
prd:
DBInstance:
Engine: aurora-postgresql
EngineVersion: 10.7
RDS1AvailabilityZone: us-east-1a
RDS2AvailabilityZone: us-east-1b
BackupRetentionPeriod: 7
PreferredBackupWindow: 17:00-18:00
ClusterPreferredMaintenanceWindow: sun:18:00-sun:19:00
InstancePreferredMaintenanceWindow: sun:18:00-sun:19:00
DatabaseName: AuroraDB
AutoMinorVersionUpgrade: false
#Aurora Postgresql10.7でないとこのクラスはNG
DBInstanceClass: db.t3.medium
DBParameterGroup:
DBEngineFamily: aurora-postgresql10
Parameters:
MyVpcId:
Type: AWS::EC2::VPC::Id
MySubnetId1:
Type: AWS::EC2::Subnet::Id
MySubnetId2:
Type: AWS::EC2::Subnet::Id
Environment:
Description: Type of this environment.
Type: String
Default: prd
AllowedValues:
- prd
- stg
SystemName:
Description: Name of this system.
Type: String
Default: test-rdsx
Username:
Description: Name of DB mater username.
Type: String
Default: postgres
Password:
Description: Name of DB mater user password.
Type: String
NoEcho: true
Metadata:
AWS::CloudFormation::Interface:
ParameterGroups:
- Label:
default: Environment Configuration
Parameters:
- SystemName
- Environment
- Label:
default: RDS DB instace Configuration
Parameters:
- Username
- Password
Resources:
# IAM Role for enhanced monitoring
RDSMonitoringRole:
Type: AWS::IAM::Role
Properties:
RoleName: !Sub ${SystemName}-${Environment}-rds-monitoring-role
Path: /
AssumeRolePolicyDocument:
!Sub |
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "monitoring.rds.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
ManagedPolicyArns:
- arn:aws:iam::aws:policy/service-role/AmazonRDSEnhancedMonitoringRole
RDSCluster:
Type: AWS::RDS::DBCluster
Properties:
MasterUsername: !Ref Username
MasterUserPassword: !Ref Password
Engine: !FindInMap [ !Ref Environment, DBInstance, Engine ]
DBSubnetGroupName: !Ref DBSubnetGroup
DBClusterParameterGroupName: !Ref RDSDBClusterParameterGroup
VpcSecurityGroupIds:
- !Ref MyRDSSG
BackupRetentionPeriod: !FindInMap [ !Ref Environment, DBInstance, BackupRetentionPeriod ]
PreferredBackupWindow: !FindInMap [ !Ref Environment, DBInstance, PreferredBackupWindow ]
DatabaseName: !FindInMap [ !Ref Environment, DBInstance, DatabaseName ]
DBClusterIdentifier: !Sub ${SystemName}-${Environment}-aurora-posgre
DeletionProtection: true
EngineMode: provisioned
EngineVersion: !FindInMap [ !Ref Environment, DBInstance, EngineVersion ]
PreferredMaintenanceWindow: !FindInMap [ !Ref Environment, DBInstance, ClusterPreferredMaintenanceWindow ]
StorageEncrypted: true
Tags:
- Key: Name
Value: !Sub ${SystemName}-${Environment}-aurora-posgre-cluster
RDSDBInstance1:
Type: AWS::RDS::DBInstance
Properties:
DBSubnetGroupName: !Ref DBSubnetGroup
DBParameterGroupName: !Ref RDSDBParameterGroup
Engine: !FindInMap [ !Ref Environment, DBInstance, Engine ]
EngineVersion: !FindInMap [ !Ref Environment, DBInstance, EngineVersion ]
DBClusterIdentifier: !Ref RDSCluster
PubliclyAccessible: 'false'
AvailabilityZone: !FindInMap [ !Ref Environment, DBInstance, RDS1AvailabilityZone ]
DBInstanceClass: !FindInMap [ !Ref Environment, DBInstance, DBInstanceClass ]
AutoMinorVersionUpgrade: !FindInMap [ !Ref Environment, DBInstance, AutoMinorVersionUpgrade ]
CopyTagsToSnapshot: true
DBInstanceIdentifier: !Sub ${SystemName}-${Environment}-aurora-posgre-1
EnablePerformanceInsights: true
PreferredMaintenanceWindow: !FindInMap [ !Ref Environment, DBInstance, InstancePreferredMaintenanceWindow ]
# DeletionProtection: true Clusterレベルでしか有効化不能
MonitoringInterval: 60
MonitoringRoleArn: !GetAtt RDSMonitoringRole.Arn
PubliclyAccessible: false
PromotionTier: 0
Tags:
- Key: Name
Value: !Sub ${SystemName}-${Environment}-aurora-posgre-1
RDSDBInstance2:
Type: AWS::RDS::DBInstance
Properties:
DBSubnetGroupName: !Ref DBSubnetGroup
DBParameterGroupName: !Ref RDSDBParameterGroup
Engine: !FindInMap [ !Ref Environment, DBInstance, Engine ]
EngineVersion: !FindInMap [ !Ref Environment, DBInstance, EngineVersion ]
DBClusterIdentifier: !Ref RDSCluster
PubliclyAccessible: 'false'
AvailabilityZone: !FindInMap [ !Ref Environment, DBInstance, RDS2AvailabilityZone ]
DBInstanceClass: !FindInMap [ !Ref Environment, DBInstance, DBInstanceClass ]
AutoMinorVersionUpgrade: !FindInMap [ !Ref Environment, DBInstance, AutoMinorVersionUpgrade ]
CopyTagsToSnapshot: true
DBInstanceIdentifier: !Sub ${SystemName}-${Environment}-aurora-posgre-2
EnablePerformanceInsights: true
PreferredMaintenanceWindow: !FindInMap [ !Ref Environment, DBInstance, InstancePreferredMaintenanceWindow ]
# DeletionProtection: true Clusterレベルでしか有効化不能
MonitoringInterval: 60
MonitoringRoleArn: !GetAtt RDSMonitoringRole.Arn
PubliclyAccessible: false
PromotionTier: 1
Tags:
- Key: Name
Value: !Sub ${SystemName}-${Environment}-aurora-posgre-2
#RDS Security Group
MyRDSSG:
Type: AWS::EC2::SecurityGroup
Properties:
GroupName: RDSSecurityGroup
GroupDescription: Enable db access
VpcId: !Ref MyVpcId
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: 5432
ToPort: 5432
CidrIp: 0.0.0.0/0
Tags:
- Key: Name
Value: !Sub ${SystemName}-${Environment}-db-security-group
# DB subnet group
DBSubnetGroup:
Type: AWS::RDS::DBSubnetGroup
Properties:
DBSubnetGroupName: !Sub ${SystemName}-${Environment}-db-subnet-group
DBSubnetGroupDescription: !Sub ${SystemName}-${Environment}-db-subnet-group
SubnetIds:
- !Ref MySubnetId1
- !Ref MySubnetId2
Tags:
- Key: Name
Value: !Sub ${SystemName}-${Environment}-db-subnet-group
# DB Cluster Parameter Group
RDSDBClusterParameterGroup:
Type: AWS::RDS::DBClusterParameterGroup
Properties:
Description: !Sub ${SystemName}-${Environment}-db-cluster-param-group
Family: !FindInMap [ !Ref Environment, DBParameterGroup, DBEngineFamily ]
Parameters:
client_encoding: UTF8
Tags:
- Key: Name
Value: !Sub ${SystemName}-${Environment}-db-cluster-param-group
# DB parameter group
RDSDBParameterGroup:
Type: AWS::RDS::DBParameterGroup
Properties:
Description: !Sub ${SystemName}-${Environment}-db-param-group
Family: !FindInMap [ !Ref Environment, DBParameterGroup, DBEngineFamily ]
Tags:
- Key: Name
Value: !Sub ${SystemName}-${Environment}-db-param-group
METRIC_LIST="
4XXError,Sum
5XXError,Sum
Count,Sum
IntegrationLatency,Average
Latency,Average \
sudo /usr/bin/aws cloudwatch get-metric-statistics
--metric-name Count
--statistics Sum
--namespace "AWS/ApiGateway"
--dimensions "Name=ApiName,Value=testing"
--start-time date --iso-8601=seconds --date "360 seconds ago"
--end-time date --iso-8601=seconds --date "60 seconds ago"
--period 60
Amazon S3
S3とはAWSで利用できるストレージサービスであり、高可用性、高い堅牢性、安価なオブジェクトストレージである。
公式ガイドでは以下。引用
Amazon Simple Storage Service はインターネット用のストレージサービスです。また、ウェブスケールのコンピューティングを開発者が簡単に利用できるよう設計されています。
Amazon S3 のウェブサービスインターフェイスはシンプルで、いつでも、ウェブのどこからでも容量に関係なくデータを格納および取得できます。これにより、すべての開発者が、スケーラブルで信頼性が高く、かつ高速で安価なデータストレージインフラストラクチャを利用できるようになります。このインフラストラクチャは、Amazon が使用しているウェブサイトのグローバルネットワークと同じものです。このサービスの目的は、規模の拡大や縮小のメリットを最大限に活かし、開発者に提供することです。
https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/dev/Welcome.html
S3バケットへのアクセス権限設計
S3バケットにアクセス権限を付与する方法
・ACL
・バケットポリシー
・IAMポリシー
ACLはバケット単位、またはオブジェクト単位で設定可能。
バケットポリシーはJSONによってAction, Effect, Principal, Resourceなどパラメータを駆使してバケット単位のマクロなアクセス権限をしける。またprefix単位で敷くことも書き方によっては可能(Condition)
IAMもバケットポリシーと同じく、JSON形式で定義する。バケットポリシーとの違いは、S3にアクセスする主体がユーザではなく、IAMユーザやAWSサービスといったクライアントであること。
ユーザ:S3のHTTPパスへアクセス(※CloudFront経由でのS3オリジンする際はこちら)
クライアント:aws cliやsdk等のAPIでS3へアクセス
またこの3つの仕組みだが、それぞれ許可・拒否を同一のバケットやオブジェクトに設定すると、
アクセスは拒否される。(1つでも拒否があれば拒否。権限の上書きはできない)
# 世界中誰でもexamplebucketバケットのオブジェクトを閲覧
{
"Version":"2012-10-17",
"Statement":[
{
"Sid":"AddPerm",
"Effect":"Allow",
"Principal": "*",
"Action":["s3:GetObject"],
"Resource":["arn:aws:s3:::examplebucket/*"]
}
]
}
# test12349999/publicだけアクセス許可する
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AddPerm",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::test12349999/public/*"
}
]
}
S3バケットへのパブリックアクセスに関して
上記3つの方法があるが、複雑で難易度高という理由もあるのか、アカウント単位、またはバケット単位で下記でパブリックアクセスを
一括管理することも可能。パブリックアクセスしたい用途もある場合はアカウント単位は少なくともオフにしておくべき。
ユースケースとしては例えば、ACLで許可をしない場合は、ACL関連の2つにはチェックをつけておくのが妥当。
またパブリックアクセスを完全拒否する場合は、全部チェックをつけておくのが妥当。
Amazon Elastic Load Balancer
AWS上で利用可能なロードバランサー。L7に対応したアプリケーションロードバランサー、L4に対応したネットワークロードバランサー等がある。
Webアプリケーションを複数台のAPサーバで負荷分散させる場合はAWSで利用するサービス。
公式ガイドでは以下。。。
Elastic Load Balancing は、アプリケーションへのトラフィックを複数のターゲット (Amazon EC2 インスタンス、コンテナ、IP アドレス、Lambda 関数など) に自動的に分散します。Elastic Load Balancing は、変動するアプリケーショントラフィックの負荷を、1 つのアベイラビリティーゾーンまたは複数のアベイラビリティーゾーンで処理できます。Elastic Load Balancing では、3 種類のロードバランサーが用意されています。これらはすべて、アプリケーションの耐障害性を高めるのに必要な高い可用性、自動スケーリング、堅牢なセキュリティを特徴としています。
アイドルタイムアウト設計
ELBは、ロードバランサのサービスとしてリバースプロキシ機能を提供する。処理の流れは以下となる。
- ELBはクライアントからのリクエストを受信し、EC2インスタンスに転送する
- EC2インスタンスはELBが転送したリクエストに対応する処理を実行する
- EC2インスタンスはレスポンスとしてELBに処理の結果を返送する
- ELBはEC2インスタンスのレスポンスをクライアントに転送する
ELBのアイドルタイムアウト値は、上記手順の2と3にかかった時間の合計値。
デフォルトは60秒で、60秒を経過するとELBはEC2インスタンスのレスポンスを待たずに、エラーとしてクライアントにHTTP 504: Gateway Timeoutを返す。
EC2でのリクエストに対する処理がJavaやPHPなどの動的処理で時間がかかったり、EC2の処理性能が足りないというケースで起こりうるトラブルである。
ちなみにELB側の60秒というタイムアウトは変更可能である。
ELB側のアイドルタイムアウト値を鑑みて、webサーバ側(例としてはApacheやNginx)のタイムアウト値はELBのタイムアウトよりも大きな値にすることが推奨される。
AWS公式情報だとELBが60秒の場合はApacheのタイムアウト値は120秒。
この設定が推奨される理由は、ELBのセッション維持機能を有効に利用するためである。 ELBはリクエストが無くても、バックエンドサーバとのセッションを維持します(KeepAlive)。バックエンドサーバとのセッションが維持されることで、無駄なハンドシェイクなどがスキップできるため、ELBの性能を最大限に発揮することができる。しかしバックエンドサーバ側のMWタイムアウト値がELBよりも小さいと、MW側で維持されているセッションが捨てられてしまい、新規でセッションをつなぎに行く必要がある。
参考
https://aws.amazon.com/jp/premiumsupport/knowledge-center/apache-backend-elb/
https://www.techscore.com/blog/2019/09/09/http-keepalive%e3%81%a8%e3%83%aa%e3%83%90%e3%83%bc%e3%82%b9%e3%83%97%e3%83%ad%e3%82%ad%e3%82%b7%e3%81%ab%e3%81%be%e3%81%a4%e3%82%8f%e3%82%8b%e8%a9%b1/
ElastiCache
AWSで利用可能なインメモリキャッシュシステム。RDBへの負荷軽減、処理高速化のために利用される。
Redisでなければデータの永続化はできないが、インメモリの分処理が早い。
公式ガイドでは、
Amazon ElastiCache では、完全マネージド型の Redis および Memcached をご利用いただけます。普及しているオープンソース互換のインメモリデータストアを、シームレスにデプロイ、運用、スケールできます。高スループットかつ低レイテンシーなインメモリデータストアからデータを取得して、大量のデータを扱うアプリケーションを構築したり、既存のアプリケーションのパフォーマンスを改善したりすることが可能です。Amazon ElastiCache は、ゲーム、アドテック、金融サービス、ヘルスケア、IoT などのアプリケーションで大いに活用されています。
ElastiCache(Redis)
Memcachedと比較した時のredisのメリットとしては、以下が存在する。
・マルチAZ構成が可能(Master/Standby,Standbyはリードレプリカ)
・データのバックアップが取得可能
・クラスターモード有効化によるシャーディングが可能。
またRedisの各種用語としては以下。
ノード
ElastiCacheの最小の構成要素。メモリとかCPUが割り当てられている。(≒インスタンスみたいなものだと思っている。)
シャード
複数のノードをまとめたグループ。データをシャードごとに分散して保存できる。シャードにはID(NodeGroupId)が割り当てられている。
1つのシャード内に複数のノードが存在することで、シャード内のノード間でデータが同期(レプリケーション)される。
クラスターモードが無効のElastiCacheクラスターではシャードは常に1つとなる。クラスターモードが有効のElastiCacheクラスターではシャードは最大90個となる。
クラスター
シャードをまとめたグループ。クラスターにもID(ReplicationGroupID)が割り当てられる。
クラスターモードが有効のElastiCacheクラスターでは、複数のシャードを作ることでデータがシャード間で分割される。
クラスターモード(Redis バージョン 3.2 以降)
クラスターモードがONの場合はシャーディング(パーティショニング)機能により、Elasticacheへの書き込みのIOも複数ノードグループ間で分散できるメリットがある。
書き込みの負荷分散を実施したい場合がクラスターモードの有効化が妥当と考えられる。
Cloudinitを使ったOSの自動初期設定
OSの初期設定等を初回AMIからの起動時、または毎回の再起動時に自動で実施する機能が。
実態はsystemdのサービスであり、下記のサービスがOS起動時に上から順々に実施される。
- cloud-init-local
- cloud-init
- cloud-config
- cloud-final
※各種サービスの起動はcloud-configとcloud-finalの間
上記の各サービスで何が実施されるかは/etc/cloud/cloud.cfgにモジュールとして定義されている。
(例えば、set-passwordsはcloud-configで実施される。cloud_init_modules/cloud_config_modules/cloud_final_modulesが実行されるモジュールが何かとそのフローを定義する部分でモジュール内で何が行われるかはそれ以外の部分か?)
各モジュールが何をするかは下記マニュアル参照。
https://cloudinit.readthedocs.io/en/latest/topics/modules.html#
# WARNING: Modifications to this file may be overridden by files in
# /etc/cloud/cloud.cfg.d
users:
- default
disable_root: true
ssh_pwauth: false
mount_default_fields: [~, ~, 'auto', 'defaults,nofail', '0', '2']
resize_rootfs: noblock
resize_rootfs_tmp: /dev
ssh_deletekeys: false
ssh_genkeytypes: ~
syslog_fix_perms: ~
datasource_list: [ Ec2, None ]
repo_upgrade: security
repo_upgrade_exclude:
- kernel
- nvidia*
- cuda*
# Might interfere with ec2-net-utils
network:
config: disabled
cloud_init_modules:
- migrator
- bootcmd
- write-files
- write-metadata
- growpart
- resizefs
- set-hostname
- update-hostname
- update-etc-hosts
- rsyslog
- users-groups
- ssh
- resolv-conf
cloud_config_modules:
- disk_setup
- mounts
- locale
- set-passwords
- yum-configure
- yum-add-repo
- package-update-upgrade-install
- timezone
- disable-ec2-metadata
- runcmd
cloud_final_modules:
- scripts-per-once
- scripts-per-boot
- scripts-per-instance
- scripts-user
- ssh-authkey-fingerprints
- keys-to-console
- phone-home
- final-message
- power-state-change
system_info:
# This will affect which distro class gets used
distro: amazon
distro_short: amzn
default_user:
name: ec2-user
lock_passwd: true
gecos: EC2 Default User
groups: [wheel, adm, systemd-journal]
sudo: ["ALL=(ALL) NOPASSWD:ALL"]
shell: /bin/bash
paths:
cloud_dir: /var/lib/cloud
templates_dir: /etc/cloud/templates
ssh_svcname: sshd
mounts:
- [ ephemeral0, /media/ephemeral0 ]
- [ swap, none, swap, sw, "0", "0" ]
# vim:syntax=yaml
個人的には下記のcloudinit用のcfgを/etc/cloud.cfg.d/以下に配置してデフォルトの設定をカスタマイズしたい。
# cloud-config
locale: ja_JP.UTF-8
timezone: Asia/Tokyo
resize_rootfs: true
ssh_pwauth: true
repo_update: none
repo_upgrade: none
write_files:
- content: |
net.ipv6.conf.all.disable_ipv6 = 1
owner: root:root
permissions: '0644'
path: /etc/sysctl.d/50-ipv6-disable.conf
packages:
- httpd
- mod_ssl
runcmd:
- sysctl --system
また、EC2起動時にOSホスト名をNameタグに合わせたいので下記シェルを/var/lib/cloud/scripts/per-boot/以下に配置しておく。
# !/bin/sh
##### リージョン名を取得
REGION=`/usr/bin/curl -s http://169.254.169.254/latest/meta-data/placement/availability-zone/ | sed 's/.$//'`
##### インスタンス自身のインスタンスIDを取得
INSTANCE_ID=`/usr/bin/curl -s http://169.254.169.254/latest/meta-data/instance-id`
##### インスタンス自身のIPアドレスを取得
# IP_ADDRESS=`/usr/bin/curl -s http://169.254.169.254/latest/meta-data/local-ipv4`
##### Nameタグを取得
NAME_TAG=`/usr/bin/aws ec2 describe-instances --region ${REGION} --instance-ids ${INSTANCE_ID=} --query 'Reservations[].Instances[].Tags[?Key==\`Name\`].Value' --output text`
hostnamectl set-hostname ${NAME_TAG}
Packerを使ったAMIの自動構築
Packerとは、AWSやAzuru、VMwareなどで主にはマシンイメージを自動構築することができるツールである。
いわば、インフラで言うところのサーバのゴールデンイメージをコードで管理できるツールのようなもの。
AWSで言うと、マシンイメージ=AMIだが、下記をワンコマンドで自動で実行してくれるイメージ。
(1)ベースイメージからEC2起動
(2)SSHログインして必要な定義変更実施
(3)EC2停止
(4)AMI化
(5)EC2削除
Packerモジュールダウンロード先
https://www.packer.io/downloads.html
Packerに必要なIAMポリシー
https://www.packer.io/docs/builders/amazon.html#using-an-iam-task-or-instance-role
### 定義ファイルJSON
[root@ro ~]# cat packer/ec2.json
{
"variables": {
"aws_access_key": "AKIAQ5HN5QSFSQJCPRJC",
"aws_secret_key": "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"
},
"builders": [
{
"type": "amazon-ebs",
"access_key": "{{user `aws_access_key`}}",
"secret_key": "{{user `aws_secret_key`}}",
"region": "us-east-1",
"vpc_id":"vpc-07c81d6a30ab7d6fb",
"subnet_id":"subnet-09a44aa58f747445f",
"source_ami": "ami-0b69ea66ff7391e80",
"instance_type": "t2.micro",
"ssh_username": "ec2-user",
"ssh_timeout": "5m",
"ami_name": "hello2_ami_{{timestamp}}",
"associate_public_ip_address": true,
"tags": {
"Name": "BaseAMI",
"OS_Version": "Amazon Linux2"
}
}
],
"provisioners": [
{
"type": "shell",
"inline": [
"sleep 30",
"sudo localectl set-locale LANG=ja_JP.UTF8",
"sudo timedatectl set-timezone Asia/Tokyo",
"sudo systemctl disable atd postfix",
"sudo systemctl mask rpcbind",
"sudo dd if=/dev/zero of=/swap bs=1M count=1024",
"sudo chmod 600 /swap",
"sudo mkswap /swap",
"sudo sed -i -e '$ a /swap swap swap defaults 0 0' /etc/fstab",
"sudo swapon -a",
"sudo groupadd -g 9999 logingrp",
"sudo useradd -u 9999 awsusr"
]
}
]
}
### 実行
./packer build ec2.json