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": "557047673318"
    }
}

プライベート用を作成( タグで「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に接続できない
User
CloudFront
ALB
EC2
RDS