Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
Help us understand the problem. What is going on with this article?

AWS便利ナレッジ集

More than 1 year has passed since last update.

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

タグのNameからインスタンスIDを算出
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の割当

[実行結果]

EC2インスタンス作成用JSONファイル作成
$ 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上フルパス]

DNSレコード作成・更新用JSON
{
 "Changes": [
  {
   "Action": "UPSERT",
   "ResourceRecordSet": {
    "Name": "XXXXXXX.",
    "Type": "A",
    "TTL": 600,
    "ResourceRecords": [
     {
      "Value": "XXXXX"
     }
    ]
   }
  }
 ]
}
DNSレコード削除用JSON
{
 "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)からデプロイ。

awscliによる操作
#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

VPCNW&Subnet&RouteTable&IGW&NatGateway(YAMLファイル)
---
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
EC2_1台sample
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

EC2_2台sample
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

ALB
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"
ec2&alb
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"
IAMロール作成
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

RDS作成用(AuroraPostgreSQL)
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つにはチェックをつけておくのが妥当。
またパブリックアクセスを完全拒否する場合は、全部チェックをつけておくのが妥当。

image.png

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は、ロードバランサのサービスとしてリバースプロキシ機能を提供する。処理の流れは以下となる。

  1. ELBはクライアントからのリクエストを受信し、EC2インスタンスに転送する
  2. EC2インスタンスはELBが転送したリクエストに対応する処理を実行する
  3. EC2インスタンスはレスポンスとしてELBに処理の結果を返送する
  4. 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 以降)

<クラスターモードの違いによる構成の違い>
image.png

クラスターモードがONの場合はシャーディング(パーティショニング)機能により、Elasticacheへの書き込みのIOも複数ノードグループ間で分散できるメリットがある。
書き込みの負荷分散を実施したい場合がクラスターモードの有効化が妥当と考えられる。

参考
https://docs.aws.amazon.com/ja_jp/AmazonElastiCache/latest/red-ug/Replication.Redis-RedisCluster.html

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#

/etc/cloud/cloud.cfg
# 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/以下に配置してデフォルトの設定をカスタマイズしたい。

カスタマイズ用cloudinitcfg
#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/以下に配置しておく。

set_hostname.sh
#!/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

Packer実行例
###定義ファイル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

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away