AWSを始めたらVPCとEC2の複雑さに悩んだのでクラス図にしてみた

# あらまし

いまさらながら AWS の勉強を始めたのですが、VPC と EC2 だけでも関連するリソースの種類が多くてなかなか理解ができなくて困りました。

例えばセキュリティグループとネットワーク ACL のように似ているようで性質が大きく異なるものや、何が何に従属して、1 対多なのか多対多なのか、といったリソースどうしの関係がなかなか頭に入らず、何度もマニュアルを見直したりしていました。

しかしよく考えたら、多数の要素どうしの複雑な関係に悩んだことは今まで何度もあって、データベースを解析する時には ER 図を、プログラムのソースを解析する時にはクラス図を作って理解してきたことを思い出しました。

そんなわけで、AWS の VP Cと EC2 および関連するリソースの関係を自分が理解するために、クラス図を作ってみました。

# クラス図

作図には [PlantUML](http://plantuml.com/ja/) を使用しました。
多重度の上限値に関しては、とりあえず `*` とか `1..*` のように上限なしで記述しました。

```plantuml
@startuml

package "AWS Infrastructure" {
  "Resion"          "1"   o==   "N"     "Availability Zone"

  class "Availability Zone" {
    Resion
  }
}

package "VPC service" {
  "VPC"             "1"   o--   "*"     "Subnet"
  "VPC"             "1"   --    "1"     "Internet Gateway"
  "VPC"             "1"   <--   "*"     "VPC Endpoint"
  "VPC"             "1"   <--   "1..*"  "Route Table"

  "Subnet"          "*"   --    "1"     "Network ACL"
  "Subnet"          "1"   <--   "*"     "NAT Gateway"
  "Subnet"          "*"   --    "1"     "Route Table"

  "Route Table"     "1"   o--   "*"     "Route"
  "Route"           "*"   -->   "1"     "Target"          : "Target"

  interface "Target"
  "Target"                <|..          "Internet Gateway"
  "Target"                <|..          "NAT Gateway"
  "Target"                <|..          "VPC Endpoint"

  "VPC Endpoint"    "*"   -->   "1"     "Endpoint Service"
  interface "Endpoint Service"

  class "VPC" {
    Resion
    IPv4 CIDR
    Owner
  }

  class "Subnet" {
    VPC
    Availability Zone
    IPv4 CIDR
    Network ACL
    Route Table
  }

  class "Internet Gateway" {
  }

  class "NAT Gateway" {
    Subnet
  }

  class "Network ACL" {
  }

  class "Route Table" {
    VPC
  }

  class "Route" {
    Route Table
    Destination
    Target
  }

  class "VPC Endpoint" {
    VPC
    Endpoint Service
  }
}

package "EC2 service" {
  "Key Pair"        "1"   <--   "*"     "EC2 Instance"
  "EC2 Instance"    "1"   o-->  "*"     "EBS"
  "EC2 Instance"    "1"   o-->  "1..*"  "ENI"

  "ENI"             "1"   --    "*"     "Elastic IP"
  "ENI"             "*"   -->   "*"     "Security Group"

  "Security Group"  "1"   o-->  "*"     "Inbound Rule"
  "Inbound Rule"    "*"   -->   "0..1"  "Security Group"   : "Source"

  "Security Group"  "1"   o-->  "*"     "Outbound Rule"
  "Outbound Rule"   "*"   -->   "0..1"  "Security Group"   : "Destination"

  class "EC2 Instance" {
    Instance Type
    Key Pair
  }

  class "EBS" {
    Size
  }

  class "ENI" {
    Src/Dst Check Flag
    Subnet
  }

  class "Elastic IP" {
    ENI
  }

  class "Security Group" {
  }

  class "Inbound Rule" {
    Type
    Protocol
    Port Range
    Source
  }

  class "Outbound Rule" {
    Type
    Protocol
    Port Range
    Destination
  }
}

package "S3 service" {
  class "Bucket" {
  } 
}

"Resion"            "1"   <==   "*"     "VPC"
"Availability Zone" "1"   <==   "*"     "Subnet"

"VPC"               "1"   <--   "*"     "Security Group"
"Subnet"            "1"   <--   "*"     "ENI"
"Target"                  <|..          "ENI"

"Endpoint Service"        <|..          "Bucket"
@enduml
```

以下のようにクラス図の一部に注目すると、リソースどうしの関連が分かりやすくなります。

- 1 つの VPC にインターネットゲートウェイは1つだけ

```plantuml
@startuml
"VPC" "1" - "1" "Internet Gateway"
@enduml
```

- 1 つのサブネットにルートテーブルは 1 つだけ
- 1 つのルートテーブルは複数のサブネットに設定できる
- 1 つのインターネットゲートウェイは複数のサブネットに設定できる

```plantuml
@startuml
interface "Target"
"Target" <|. "Internet Gateway"

"Subnet"      "*" -   "1" "Route Table"
"Route Table" "1" o-  "*" "Route"
"Route"       "*" -   "1" "Target"      : "Target"

class "Subnet" {
  Route Table
}

class "Route" {
  Route Table
  Target
}
@enduml
```

- 1 つのサブネットにネットワーク ACL は 1 つだけ
- 1 つのネットワーク ACL は複数のサブネットに設定できる

```plantuml
@startuml
"Subnet" "*" - "1" "Network ACL"
@enduml
```

# あとがき

勉強しながら作っているので理解不足の点が多々あると思いますが、今後理解を進めながら図の完成度を上げていきたいと思います。

# 参考資料

- [Amazon VPC ユーザーガイド](https://docs.aws.amazon.com/ja_jp/vpc/latest/userguide/what-is-amazon-vpc.html)
- [Amazon EC2 Linux インスタンス用ユーザーガイド](https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/concepts.html)
- [PlantUML 概要](http://plantuml.com/ja/)