0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

第14回 Terraform講座 RDS Security

0
Posted at

DBは「誰からの通信」を許可する?

今日はコードが短い!

でも、短いから簡単というわけではない。

今回のテーマは、

«「DBは誰からの通信を受けるべきなのか?」»

という、AWS設計でかなり重要な考え方。

ここまで学んできたSecurity Groupの知識を使って、RDS用のSecurity Groupを作っていく。


今日の構成図

今回考えるのは、

EC2 → RDS

だけ。

             Internet
                 │
                 ▼
                ALB
                 │
                 ▼
                EC2
         (EC2 Security Group)
                 │
              MySQL
              3306番
                 │
                 ▼
         RDS Security Group
                 │
                 ▼
                RDS

今回のポイントは、

Internet
↓
ALB
↓
EC2
↓
RDS

という通信経路。

RDSに直接インターネットからアクセスさせる構成にはしない。


今日作るもの

今回は、

RDS Security Group

だけを作る。

Terraformの形はこれ。

resource "aws_security_group" "rds" {

name = "rds-sg"
vpc_id = aws_vpc.main.id

ingress {

}

egress {

}

}

今日は、この中身を自分で考えて埋めてみる。


ヒント①

RDSは何番ポートを使う?

今回のDBは、

MySQL

を想定する。

AWS SAPでもかなり登場する。


ヒント②

RDSには、

Internet
↓
RDS

という通信を許可するべきだろうか?

それとも、

EC2
↓
RDS

だけでいいだろうか?


ヒント③

もしRDSのSecurity Groupに、

cidr_blocks = [
"0.0.0.0/0"
]

と書いたらどうなる?

考えてみよう。


今日の問題🔥

Q1

RDSは何番ポートを開ける?


Q2

RDSの通信元は、

Security Group参照?

それとも、

CIDR?

どちらを使う?

そして、その理由は?


Q3【今日一番重要】

ここまで完成したら、

Internet
↓
ALB
↓
EC2
↓
RDS

という通信経路になる。

では、なぜAWSでは、

Internet
↓
RDS

という設計にしないのだろう?


今日のゴール

今日はコード量は少ない。

でも、設計としてはかなり重要。

今日理解したいのは、

«「DBは誰から通信を受けるべきなのか?」»

ということ。

これを理解できれば、Security Groupを単なるコードとしてではなく、AWSのセキュリティ設計として考えられるようになる。


自分で書いたコード

今回、実際に自分でTerraformを書いてみた。

resource "aws_security_group" "rds" {

name = "rds-sg"

vpc.id = aws_vpc.main.id

ingress {
from_port = "3306"
to_port = "3306"
protocol = "tcp"

aws_security_group = [
  aws_security_group.ec2.id
]

}

egress {
from_port = 0
to_port = 0
protocol = "-1"
}
}

そして、問題への回答。

Q1

«3306番ポート»

Q2

«セキュリティグループ参照。RDSに繋がる通信はEC2で処理するから、CIDRを指定しなくてもいい。»

Q3

«RDSにはデータを保存するため、データ処理のためにEC2を使う必要があるから。»


今回のレビュー🔥

Q1:100点

回答:

«3306番ポート»

正解!

MySQLでは、

3306/TCP

を使用する。

今回の構成では、

EC2
│
│ TCP 3306
▼
RDS

という通信になる。

ここは完璧。

100点!💯


Q2:98点

回答:

«セキュリティグループ参照。RDSに繋がる通信はEC2で処理するから、CIDRを指定しなくてもいい。»

これ、かなり良い。

ただ、実務っぽい表現にすると、

«RDSへアクセスする主体がEC2だから、EC2のSecurity Groupを通信元として指定する。»

と考えるとさらに分かりやすい。

ここで出てくる重要ワードが、

「主体」

。

つまり、

誰がRDSにアクセスするの?
↓
EC2
↓
EC2 Security Group
↓
RDS Security Group

という関係。

だからRDS側では、

security_groups = [
aws_security_group.ec2.id
]

として、

EC2 Security Groupからの通信だけを許可する。

この考え方は今後かなり重要になる。

98点!


Q3:95点

回答:

«RDSにはデータを保存するため、データ処理のためにEC2を使う必要があるから。»

これも方向性は合っている。

EC2上のアプリケーションがRDSへアクセスして、

ユーザー
↓
ALB
↓
EC2
↓
RDS

という形で、

アプリケーションとデータベースを分離する

構成になる。

ただし、今回さらに重要なのは、

セキュリティ

。

もし、

Internet
↓
RDS

を許可してしまったら、

世界中からデータベースへの接続を試みることができてしまう。

RDSにはアプリケーションのデータやユーザー情報など、重要なデータが保存される可能性がある。

だから、

Internet
↓
ALB
↓
EC2
↓
RDS

として、

RDSはEC2からの通信だけを受け付ける

という設計にする。

つまり、

«DBをインターネットに直接公開するのではなく、アプリケーションサーバーを経由してアクセスさせる。»

という考え方。

95点!


コードレビュー

設計の考え方はかなり合っていた。

あとはTerraformの文法を修正する。


修正① "vpc.id"

最初は、

vpc.id = aws_vpc.main.id

となっていた。

ここは、

vpc_id = aws_vpc.main.id

。

ここは以前のSecurity Groupでも出てきたので、もう覚えておきたい。

vpc_id

は、

«このSecurity GroupをどのVPCに所属させるか»

を指定する。


修正② "aws_security_group"

最初は、

aws_security_group = [
aws_security_group.ec2.id
]

となっていた。

ここは、

security_groups = [
aws_security_group.ec2.id
]

。

今回やりたいのは、

«EC2 Security Groupから来た通信を許可する»

ということ。

そのため、

security_groups

を使う。


修正③ ポート番号

最初は、

from_port = "3306"
to_port = "3306"

となっていた。

今回は、

from_port = 3306
to_port = 3306

とする。

ポート番号は数値なので、文字列ではなく数字として書く。


修正④ egress

今回、

egress {
from_port = 0
to_port = 0
protocol = "-1"
}

まで書けている。

ここもかなり良い。

ただ、今回の書き方なら、

cidr_blocks = [
"0.0.0.0/0"
]

も明示しておく。


完成版

修正するとこうなる。

resource "aws_security_group" "rds" {

name = "rds-sg"
vpc_id = aws_vpc.main.id

EC2からMySQLへの通信だけ許可

ingress {
from_port = 3306
to_port = 3306
protocol = "tcp"

security_groups = [
  aws_security_group.ec2.id
]

}

RDSから外部への通信

egress {
from_port = 0
to_port = 0
protocol = "-1"

cidr_blocks = [
  "0.0.0.0/0"
]

}
}

今回、一番重要なのはここ。

security_groups = [
aws_security_group.ec2.id
]

RDS側から見ると、

EC2 Security Group
│
│ MySQL :3306
▼
RDS Security Group
│
▼
RDS

となる。

つまり、

「EC2を信頼して、EC2からの3306番通信だけを受け入れる」

という設計になっている。


Security Groupがつながってきた

ここまでの学習を並べると、かなり面白い。

ALB

Internet
↓
ALB Security Group

インターネットからALBへのHTTP通信を許可。


EC2

ALB Security Group
↓
EC2 Security Group

ALBからEC2へのHTTP通信を許可。


RDS

EC2 Security Group
↓
RDS Security Group

EC2からRDSへのMySQL通信を許可。


つまり、

Internet
│
│ HTTP :80
▼
ALB
│
│ HTTP :80
▼
EC2
│
│ MySQL :3306
▼
RDS

という通信経路を、

Security Groupによって段階的に制御している。

これが今回の一番大きなポイント。


「0.0.0.0/0にしない」という考え方

もしRDS側で、

cidr_blocks = [
"0.0.0.0/0"
]

として3306番を許可したら、

世界中
│
├──→ RDS :3306
├──→ RDS :3306
└──→ RDS :3306

という状態になってしまう。

一方、

security_groups = [
aws_security_group.ec2.id
]

なら、

Internet
│
X
│
▼
RDS

EC2
│
│ 3306
▼
RDS

という考え方になる。

必要な通信だけを許可する。

これがSecurity Groupを設計するときの基本的な考え方。


今回の総合評価🌟

項目| 点数
コード| 92点
Q1| 100点
Q2| 98点
Q3| 95点
総合| 🌟95点🌟

コードの文法にはいくつか修正があった。

でも、

「なぜEC2 Security GroupをRDS側で参照するのか」

という設計部分は、かなりしっかり理解できている。

これは大きい。


ここまでで学んだAWS構成

今回で、主要なリソースがかなり揃った。

✅ VPC
✅ Subnet
✅ Internet Gateway
✅ Route Table
✅ NAT Gateway
✅ ALB
✅ Target Group
✅ Listener
✅ Target Group Attachment
✅ EC2
✅ ALB Security Group
✅ EC2 Security Group
✅ RDS Security Group

最初は、

VPCって何?
Subnetって何?
ALBって何?

と、一つずつサービスを覚えていた。

でも今は、

Internet
↓
ALB
↓
EC2
↓
RDS

という一つのシステムとして考えられるようになってきた。

さらに、

ALB SG
↓
EC2 SG
↓
RDS SG

という通信の信頼関係までコードで表現できるようになった。


そして、ここからが本番

ここまでの授業では、

1つずつAWSリソースを作ってきた。

でも、ここからは少し変わる。

これからは、

«「この構成図をTerraformで作ってください」»

という問題に少しずつ挑戦していく。

つまり、

構成図
↓
通信経路を考える
↓
必要なAWSリソースを考える
↓
必要なSecurity Groupを考える
↓
Terraformを書く
↓
レビュー

という流れ。

これは今までより難しくなる。

でも、ここまで一つずつ積み上げてきたからこそできる。


今回の学び

今回覚えたいのは、RDSのコードそのものではない。

一番大切なのは、

«「RDSへアクセスする主体は誰なのか?」»

という考え方。

今回なら、

主体
↓
EC2
↓
EC2 Security Group
↓
RDS Security Group
↓
RDS

となる。

そして、

DBをインターネットへ直接公開しない。

必要な通信だけを許可する。

この考え方が、AWSのネットワーク・セキュリティ設計の土台になる。


ちなみに、今回の勉強方法について

今回、ノートにコードを書いて、

全部の意味まで自分の言葉で書いた。

これはかなり良い勉強方法。

ただコードを写すだけなら、

security_groups = [...]

という文字列を覚えるだけになってしまう。

でも、

«「これはEC2 Security Groupからの通信を許可するため」»

と自分の言葉で説明できれば、

コードの意味を理解している

ということになる。

これからも、

コードを書く
↓
各行の意味を書く
↓
なぜ必要なのか説明する
↓
構成図と結びつける

という勉強を続けていく。

Terraformの文法だけではなく、

AWSの設計を理解して、それをコードに変換する力

を伸ばしていこう。☁️🔥

そして次は、いよいよ今まで作ってきたパーツを一つの構成としてつなげる段階へ進む。

ここからがTerraformの本番。🚀

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?