AWS Organizationsで作った環境でVPCを作っていく

作業の流れ

  1. AWS OrganizationでOrganization Unit ( OU )作成、AWS Organization 内で AWSアカウントも作成
  2. VPC作成、サブネットを各AZごとに合計3つ作成
  3. VPC内でインターネットゲートウェイ作成, 作成したVPCに紐付け

AWS、アカウント作成直後のネットワーク設定

実作業

AWSの具体的なリソースは省略しています。得られた値で読み替えてください。

VPC作成
  • プロファイルは都度、変更してください
  • –cidr-block は 既存サブネットと被らないように取得してください
  • vpcのタグ名は都度、変更する

CLIでの作成はここが非常に参考になります

aws ec2 --profile test-site create-vpc --cidr-block "172.37.0.0/16" --tag-specifications  "ResourceType=vpc,Tags=[{Key=Name,Value=prod}]"
{
    "Vpc": {
        "CidrBlock": "172.37.0.0/16",
        "DhcpOptionsId": "dopt-08f0bf2e614f696d8",
        "State": "pending",
        "VpcId": "vpc-04d******"
        "OwnerId": "*************",
        "InstanceTenancy": "default",
        "Ipv6CidrBlockAssociationSet": [],
        "CidrBlockAssociationSet": [
            {
                "AssociationId": "vpc-cidr-assoc-",
                "CidrBlock": "172.37.0.0/16",
                "CidrBlockState": {
                    "State": "associated"
                }
            }
        ],
        "IsDefault": false,
        "Tags": [
            {
                "Key": "Name",
                "Value": "prod"
            }
        ]
    }
}

また上記のCLIで作成した際の 「 “VpcId”: “vpc-???“このVpcId の値は使うのでメモしておく

サブネット作成

上記でメモしたVPC IDを使う。またどのサブネットを使うか考えておく

aws ec2 create-subnet  --profile test-site --vpc-id vpc-??? --availability-zone "ap-northeast-1a" --cidr-block 172.37.127.0/24
{
    "Subnet": {
        "AvailabilityZone": "ap-northeast-1a",
        "AvailabilityZoneId": "apne1-az4",
        "AvailableIpAddressCount": 251,
        "CidrBlock": "172.37.127.0/24",
        "DefaultForAz": false,
        "MapPublicIpOnLaunch": false,
        "State": "available",
        "SubnetId": "subnet-0",
        "VpcId": "vpc-???",
        "OwnerId": "",
        "AssignIpv6AddressOnCreation": false,
        "Ipv6CidrBlockAssociationSet": [],
        "SubnetArn": "arn:aws:ec2:ap-northeast-1:****:subnet/subnet-"
    }
}

実行例) test-site様向けに1VPC内の3AZに、それぞれパブリック、プライベート、合計6サブネットを作成した

aws ec2 create-subnet  --profile test-site --vpc-id vpc-??? --availability-zone "ap-northeast-1a" --cidr-block 172.37.1.0/24 --tag-speci
fications  "ResourceType=subnet,Tags=[{Key=Name,Value=prod-pri-1a}]"

aws ec2 create-subnet  --profile test-site --vpc-id vpc-??? --availability-zone "ap-northeast-1c" --cidr-block 172.37.2.0/24 --tag-speci
fications  "ResourceType=subnet,Tags=[{Key=Name,Value=prod-pri-1c}]"

aws ec2 create-subnet  --profile test-site --vpc-id vpc-??? --availability-zone "ap-northeast-1d" --cidr-block 172.37.3.0/24 --tag-specifications  "ResourceType=subnet,Tags=[{Key=Name,Value=prod-pri-1d}]"

aws ec2 create-subnet  --profile test-site --vpc-id vpc-??? --availability-zone "ap-northeast-1a" --cidr-block 172.37.127.0/24 --tag-speci
fications  "ResourceType=subnet,Tags=[{Key=Name,Value=prod-pub-1a}]"

aws ec2 create-subnet  --profile test-site --vpc-id vpc-??? --availability-zone "ap-northeast-1c" --cidr-block 172.37.128.0/24 --tag-spe
cifications  "ResourceType=subnet,Tags=[{Key=Name,Value=prod-pub-1c}]"

aws ec2 create-subnet  --profile test-site --vpc-id vpc-??? --availability-zone "ap-northeast-1d" --cidr-block 172.37.129.0/24 --tag-spe
cifications  "ResourceType=subnet,Tags=[{Key=Name,Value=prod-pub-1d}]"

インターネットゲートウェイ作成

aws ec2 create-internet-gateway  --profile test-site  | jq -r '.InternetGateway.InternetGatewayId'

出力例) 下記のうち、InternetGatewayId は再度使います。このIDを元にVPCにインターネットゲートウェイを接続します

{
    "InternetGateway": {
        "Attachments": [],
        "InternetGatewayId": "igw-",
        "OwnerId": "",
        "Tags": []
    }
}
インターネットゲートウェイをVPCに接続
aws ec2 attach-internet-gateway  --profile test-site --vpc-id vpc-??? --internet-gateway-id igw-
ルートテーブルを作る

パブリックセグメント用のルートテーブル

aws ec2 create-route-table  --profile test-site --vpc-id vpc-??? --tag-specifications  "ResourceType=route-table,Tags=[{Key=Name,Value=public}]"
{
    "RouteTable": {
        "Associations": [],
        "PropagatingVgws": [],
        "RouteTableId": "rtb-",
        "Routes": [
            {
                "DestinationCidrBlock": "172.37.0.0/16",
                "GatewayId": "local",
                "Origin": "CreateRouteTable",
                "State": "active"
            }
        ],
        "Tags": [
            {
                "Key": "Name",
                "Value": "public"
            }
        ],
        "VpcId": "vpc-???",
        "OwnerId": "123456789012"
    }
}

プライベート用を作成( タグで「private」を付けている

aws ec2 create-route-table  --profile test-site --vpc-id vpc-??? --tag-specifications  "ResourceType=route-table,Tags=[{Key=Name,Value=private}]"
{
    "RouteTable": {
        "Associations": [],
        "PropagatingVgws": [],
        "RouteTableId": "rtb-",
        "Routes": [
            {
                "DestinationCidrBlock": "172.37.0.0/16",
                "GatewayId": "local",
                "Origin": "CreateRouteTable",
                "State": "active"
            }
        ],
        "Tags": [
            {
                "Key": "Name",
                "Value": "private"
            }
        ],
        "VpcId": "vpc-???",
        "OwnerId": ""
    }
}
NATゲートウェイの作成、インターネットゲートウェイ接続

AWS VPC のインターネットゲートウェイは、外側( インターネット側 )からAWS内のグローバルIPアドレスを持つEC2インスタンスへのトラフィックを転送する、 ( 余談だが、EC2全てにグローバルIPアドレスを付与する運用ならVPCのインターネットゲートウェイだけで運用が可能。 が、セキュリティの観点から、すべてグローバルIPアドレスを付与するような、つまり外部に全てを晒しているようなシステム構成より、 必要な箇所だけ外部に露出させる、プライベートIPアドレスを併用したシステム構成の方がセキュアだと言える。

一般的なベストプラクティスに従い、プライベートIPアドレスとグローバルIPアドレスを併用している。 NATゲートウェイは「内側から外側へのトラフィックをルーティングする」

NATゲートウェイを作成する

aws ec2 allocate-address --profile test-site --domain vpc
{
    "PublicIp": "1.2.3.4",
    "AllocationId": "eipalloc-",
    "PublicIpv4Pool": "amazon",
    "NetworkBorderGroup": "ap-northeast-1",
    "Domain": "vpc"
}
aws ec2 create-nat-gateway --profile test-site  --subnet-id subnet- --allocation-id eipalloc-
{
    "ClientToken": "----",
    "NatGateway": {
        "CreateTime": "2021-03-09T03:31:24+00:00",
        "NatGatewayAddresses": [
            {
                "AllocationId": "eipalloc-"
            }
        ],
        "NatGatewayId": "nat-",
        "State": "pending",
        "SubnetId": "subnet-",
        "VpcId": "vpc-???"
    }
}

NATゲートウェイをプライベートのネットワークのルーティングに付与

aws ec2 create-route --profile test-site --route-table-id rtb- --destination-cidr-block 0.0.0.0/0 --nat-gateway-id nat-
ルートテーブルに外部へのインターネットゲートウェイのルーティングを追加
aws ec2 create-route  --profile test-site  --route-table-id rtb- --destination-cidr-block 0.0.0.0/0 --gateway-id igw-

確認

aws ec2 describe-route-tables  --profile test-site   --route-table-id  rtb-
サブネット一覧
aws ec2 describe-subnets  --profile test-site  --filters "Name=vpc-id,Values=vpc-???" --query 'Subnets[*].{ID:SubnetId,CIDR:CidrBlock}'

下記のような一覧が得られるので、そのうち『パブリックにしたいサブネットのID』を考える

[
    {
        "ID": "subnet-",
        "CIDR": "172.37.127.0/24"
    },
    {
        "ID": "subnet-",
        "CIDR": "172.37.3.0/24"
    },
    {
        "ID": "subnet-",
        "CIDR": "172.37.1.0/24"
    },
    {
        "ID": "subnet-",
        "CIDR": "172.37.129.0/24"
    },
    {
        "ID": "subnet-",
        "CIDR": "172.37.128.0/24"
    },
    {
        "ID": "subnet-",
        "CIDR": "172.37.2.0/24"
    }
]

パブリック用の3つのサブネットを、外部に接続できるルーティングテーブルに接続する (3回くりかえす)

aws ec2 associate-route-table  --profile test-site --route-table-id rtb- --subnet-id subnet-

プライベート用の3つのサブネットを、プライベート用のルーティングテーブルに接続する (3回くりかえす)

aws ec2 associate-route-table  --profile test-site --route-table-id rtb- --subnet-id subnet-
ssh鍵の設定
aws ec2 create-key-pair  --profile test-site  --key-name test-site --query 'KeyMaterial' --output text > test-site.pem

出来上がった test-site.pem は

自分のホームディレクトリ直下の .ssh 配下に置き、chmod 600 でパーミッションを600にする

セキュリティグループ
aws ec2 create-security-group  --profile test-site --group-name webfront --description "Security group for web access" --vpc-id vpc-
{
    "GroupId": "sg-"
}

Port 80, 443 はインターネットに全公開

aws ec2 authorize-security-group-ingress  --profile test-site --group-id sg- --protocol tcp --port 80 --cidr 0.0.0.0/0
aws ec2 authorize-security-group-ingress  --profile test-site --group-id sg- --protocol tcp --port 443 --cidr 0.0.0.0/0

Port 22 はローカルのみ許可

aws ec2 authorize-security-group-ingress  --profile test-site  --group-id sg- --protocol tcp --port 22 --cidr 172.37.0.0/16
EC2にSSM経由でログインできるように、IAMの設定を追加

https://dev.classmethod.jp/articles/not-recommended-amazonec2roleforssm/

AmazonSSMManagedInstanceCore というIAMポリシーを付与したロールを作成する事で SSM 経由で ssh できるようになります。

サブネット作成以降

上記のCLIで作成した際の 「 “VpcId”: “vpc-",」このVpcId の値は使うのでメモしておく

  1. サブネット作成

  2. インターネットゲートウェイ作成

  3. ルートゲートウェイ設定 https://ap-northeast-1.console.aws.amazon.com/vpc/home?region=ap-northeast-1#RouteTables:sort=routeTableId VPN作成後、標準のルートテーブルがあるので、[ Name ]だけprodなどと変更 ルートを追加する [ 送信先 ] 0.0.0.0/0 [ ターゲット ] 先程つくったインターネットゲートウェイを指定 更に、ここで、トランジットゲートウェイを追加したいが…

  4. NATゲートウェイ作成 https://ap-northeast-1.console.aws.amazon.com/vpc/home?region=ap-northeast-1#CreateNatGateway: サブネット: public Elastic IP 割り当て ID: 新規に作成した

  5. プライベート用にルートテーブルを作成 publicとは別にプライベート用のルートテーブルを作成する 名称はprivate 新しいVPCに作成、ルートを追加 [ 送信先 ] 0.0.0.0/0 [ ターゲット ] NATゲートウェイ

パブリック用、プライベート用、2つのルートテーブルに、サブネットを紐付ける。 2020/04/24 時点だと日本リージョンには、3つのAZがあり、それぞれのAZにパブリック、プライベートのサブネットを作っている。 つまりパブリックで3サブネット、プライベートで3サブネットを作る。 先程、作成したパブリック用ルートテーブルにパブリック用サブネット3個を紐付ける。 プライベート用ルートテーブルにプライベート用サブネット3個を紐付ける。

セキュリティグループ作成。2つ作成する。

  • webfront port 80を全てに許可。port 10022をVPCのプライベートアドレスに向けて公開
  • ops port 10022を全てに許可する事を目的にするが「EC2は最初、port 22でsshdをlistenする」ので、最初は22で全てを許可

opsにsshでログイン、 sudo vi /etc/ssh/sshd_config#Port 22 -> Port 10022 とコメントアウトを外した上でポートを変更する

サーバからログアウトした後、上記のセキュリティグループのops側を変更、許可するポートを 22 -> 10022 に変更する。

  1. EC2を作成。この際に作成するSSHの鍵は ここに保存

  2. EC2サーバにはsshではなく、 SSM経由でログインできるようにする

  3. EC2内でCanvas LMSの構築 DBはRDS上で作ったものにする

  4. ALBで使うSSL証明書の発行

  5. DB作成

Todo

下記も追記したい

  1. DBをCLIから
  2. dbsubnetをCLIから
  3. ALBをCLIから
  4. DB用セキュリティグループ作成をCLIから( でないとDBに接続できない