この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので十分ご注意ください。
皆様こんにちは。
今回はTerraformを利用して、AWSで高可用性アーキテクトの構築をしていきます。
ALB、EC2、RDS、EFSのセキュリティグループ(以下SG)を作成し、各SGの設定内容についても記事にしています。
1.高可用性アーキテクト構築目次
2.セキュリティグループとは
セキュリティグループは仮想ファイアウォールとして機能し、関連付けられたリソースに到達および離れるトラフィックを制御します。例えば、セキュリティグループを EC2 インスタンスに関連付けると、インスタンスのインバウンドトラフィックとアウトバウンドトラフィックが制御されます。
SGは、EC2やELB、RDSなど、インスタンス単位の通信制御に利用します。インスタンスには少なくとも1つのSGをアタッチする必要があります。
通信制御としては、インバウンド(内向き、外部からVPCへ)とアウトバウンド(外向き、内部から外部へ)の制御ができます。
類似サービスとしては、「ネットワークACL」があります。
SGとネットワークACLの違いについては下記にまとめています。
項目 | セキュリティグループ | ネットワークACL |
---|---|---|
適用範囲 | インスタンス単位 | サブネット単位 |
デフォルト動作 | インバウンド:すべて拒否 アウトバウンド:すべて許可 |
インバウンド:すべて許可 アウトバウンド:すべて許可 |
ルールの評価 | 全てのルールが適用 | ルールの番号順で適用 |
ステータス | ステートフル | ステートレス |
ステートフルなら以前の状態を保持したまま以後の処理に役立てますが、ステートレスでは以前の状態を保持せずにその都度の処理を要求します。
3.セキュリティグループ構成図
-
ALB用のものはRoute53のパブリックホストゾーンからのトラフィックを受け入れる必要があるので、ソースは0.0.0.0/0とします。通信は暗号化されている必要があるのでタイプはHTTPSにします。
パブリックホストゾーンには、トラフィックをインターネットでどのようにルーティングするかを指定するレコードが含まれています -
EC2用のものはALBからのトラフィックを受け入れる必要がありますのでソースはALB用のSGを指定します。VPC内部の通信は暗号化されている必要がないのでタイプはHTTPにします。また、自分のPCよりEC2インスタンスと通信するために、SSHでソースはMYIPを指定します。
-
RDS用のものはEC2に対するDBサーバーとして扱います。EC2からのトラフィックを受け入れる必要がありますのでソースはEC2用のSGを指定します。タイプはDBにMYSQLを使用するのでMYSQL/Auroraを選びます。
-
EFS用のものはEC2のWordpressインストールファイルを共有するために使用するので、EEC2からのトラフィックを受け入れる必要があります。ソースはEC2用のSGを指定し、タイプNFSを選びます。
NFSとは、主にUNIX系OSで利用される分散ファイルシステム、および、そのための通信規約(プロトコル)です。
4.セキュリティグループの作成
ALB、EC2、RDS、EFS用に4つのSGを作成していきます。
SG全体のソースコードは下記の通りです。
#--------------------------------------
# セキュリティグループの作成
#----------------------------------------
#--------------------------------------
# higa-ALB-sgの作成
#----------------------------------------
resource "aws_security_group" "higa-ALB-sg" {
name = "higa-ALB-sg"
description = "higa-ALB-sg"
vpc_id = aws_vpc.higa-vpc.id
//HTTP
ingress {
from_port = 80
to_port = 80
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
egress {
from_port = 0
to_port = 0
#protocol = "-1" は "all" と同等
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
//HTTPS
ingress {
from_port = 443
to_port = 443
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
egress {
from_port = 0
to_port = 0
#protocol = "-1" は "all" と同等
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
tags = {
Name = "higa-ALB-sg"
}
}
#--------------------------------------
# higa-ec2-sgの作成
#----------------------------------------
resource "aws_security_group" "higa-ec2-sg" {
name = "higa-ec2-sg"
description = "higa-ec2-sg"
vpc_id = aws_vpc.higa-vpc.id
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
tags = {
Name = "higa-ec2-sg"
}
}
//80番ポート(http)許可のインバウンドルール
resource "aws_security_group_rule" "inbound_http" {
type = "ingress"
from_port = 80
to_port = 80
protocol = "tcp"
//higa-ALB-sgが紐づくリソースにアクセス許可
source_security_group_id = aws_security_group.higa-ALB-sg.id
//ec2セキュリティグループに紐付け
security_group_id = aws_security_group.higa-ec2-sg.id
}
//22番ポート(ssh)許可のインバウンドルール
resource "aws_security_group_rule" "inbound_ssh" {
type = "ingress"
from_port = 22
to_port = 22
protocol = "tcp"
//ソースにマイIPを指定
cidr_blocks = ["133.32.128.179/32"]
//ec2セキュリティグループに紐付け
security_group_id = aws_security_group.higa-ec2-sg.id
}
#--------------------------------------
# higa-RDS-sgの作成
#----------------------------------------
resource "aws_security_group" "higa-RDS-sg" {
name = "higa-RDS-sg"
description = "higa-RDS-sg"
vpc_id = aws_vpc.higa-vpc.id
ingress {
from_port = 3306
to_port = 3306
protocol = "tcp"
//ec2セキュリティグループが紐づくリソースにアクセス許可
security_groups = [aws_security_group.higa-ec2-sg.id]
}
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
tags = {
Name = "higa-RDS-sg"
}
}
#--------------------------------------
# higa-EFS-sgの作成
#----------------------------------------
resource "aws_security_group" "higa-EFS-sg" {
name = "higa-EFS-sg"
description = "higa-EFS-sg"
vpc_id = aws_vpc.higa-vpc.id
ingress {
from_port = 2049
to_port = 2049
protocol = "tcp"
//ec2セキュリティグループが紐づくリソースにアクセス許可
security_groups = [aws_security_group.higa-ec2-sg.id]
}
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
tags = {
Name = "higa-EFS-sg"
}
}
4-1.ALB用のSG作成
ALBのSGは下記のコードで作成します。(5~47行目)
#----------------------------------------
# higa-ALB-sgの作成
#----------------------------------------
resource "aws_security_group" "higa-ALB-sg" {
name = "higa-ALB-sg"
description = "higa-ALB-sg"
vpc_id = aws_vpc.higa-vpc.id
//HTTP
ingress {
from_port = 80
to_port = 80
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
egress {
from_port = 0
to_port = 0
#protocol = "-1" は "all" と同等
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
//HTTPS
ingress {
from_port = 443
to_port = 443
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
egress {
from_port = 0
to_port = 0
#protocol = "-1" は "all" と同等
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
tags = {
Name = "higa-ALB-sg"
}
}
設定項目は下記の通りです。
使用するオプション | 設定値 | 説明 |
---|---|---|
name | higa-ALB-sg | セキュリティグループ名 |
description | higa-ALB-sg | 説明 |
vpc_id | aws_vpc.higa-vpc.id | VPCの指定 |
tags | Name = "higa-ALB-sg" | Nameの表記を設定 |
設定項目 | 設定値 | 説明 |
---|---|---|
タイプ | HTTP HTTPS |
httpは一時的にhttpでアクセスするため設定(HTTPS構築後に削除します) httpsは通信を暗号化するため設定 |
ポート | 80 443 |
アクセスを許可したいプロトコルのポート範囲を入力 |
プロトコル | TCP | プロトコルを入力 |
protocol = "-1"
は「all」と同等の意味を表します。つまり、すべて許可しています。
4-2.EC2用のSG作成
EC2のSGは下記のコードで作成します。(49~94行目)
#----------------------------------------
# higa-ec2-sgの作成
#----------------------------------------
resource "aws_security_group" "higa-ec2-sg" {
name = "higa-ec2-sg"
description = "higa-ec2-sg"
vpc_id = aws_vpc.higa-vpc.id
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
tags = {
Name = "higa-ec2-sg"
}
}
//80番ポート(http)許可のインバウンドルール
resource "aws_security_group_rule" "inbound_http" {
type = "ingress"
from_port = 80
to_port = 80
protocol = "tcp"
//higa-ALB-sgが紐づくリソースにアクセス許可
source_security_group_id = aws_security_group.higa-ALB-sg.id
//ec2セキュリティグループに紐付け
security_group_id = aws_security_group.higa-ec2-sg.id
}
//22番ポート(ssh)許可のインバウンドルール
resource "aws_security_group_rule" "inbound_ssh" {
type = "ingress"
from_port = 22
to_port = 22
protocol = "tcp"
//ソースにマイIPを指定
cidr_blocks = ["133.32.128.179/32"]
//ec2セキュリティグループに紐付け
security_group_id = aws_security_group.higa-ec2-sg.id
}
設定項目は下記の通りです。
使用するオプション | 設定値 | 説明 |
---|---|---|
name | higa-ec2-sg | セキュリティグループ名 |
description | higa-ec2-sg | 説明 |
vpc_id | aws_vpc.higa-vpc.id | VPCの指定 |
tags | Name = "higa-ec2-sg" | Nameの表記を設定 |
設定項目 | 設定値 | 説明 |
---|---|---|
タイプ | HTTP SSH |
httpではALBのSGのみを許可 sshでは自分のIPからのみ接続を許可 |
ポート | 80 22 |
アクセスを許可したいプロトコルのポート範囲を入力 |
プロトコル | TCP | プロトコルを入力 |
4-3.RDS用のSG作成
RDSのSGは下記のコードで作成します。(96~120行目)
#----------------------------------------
# higa-RDS-sgの作成
#----------------------------------------
resource "aws_security_group" "higa-RDS-sg" {
name = "higa-RDS-sg"
description = "higa-RDS-sg"
vpc_id = aws_vpc.higa-vpc.id
ingress {
from_port = 3306
to_port = 3306
protocol = "tcp"
//ec2セキュリティグループが紐づくリソースにアクセス許可
security_groups = [aws_security_group.higa-ec2-sg.id]
}
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
tags = {
Name = "higa-RDS-sg"
}
}
設定項目は下記の通りです。
使用するオプション | 設定値 | 説明 |
---|---|---|
name | higa-RDS-sg | 説明 |
description | higa-RDS-sg | セキュリティグループ名 |
vpc_id | aws_vpc.higa-vpc.id | VPCの指定 |
tags | Name = "higa-RDS-sg" | Nameの表記を設定 |
設定項目 | 設定値 | 説明 |
---|---|---|
タイプ | MYSQL/Aurora | EC2のSGのみを許可 |
ポート | 3306 | アクセスを許可したいプロトコルのポート範囲を入力 |
プロトコル | TCP | プロトコルを入力 |
4-4.EFS用のSG作成
EFSのSGは下記のコードで作成します。(122~146行目)
#----------------------------------------
# higa-EFS-sgの作成
#----------------------------------------
resource "aws_security_group" "higa-EFS-sg" {
name = "higa-EFS-sg"
description = "higa-EFS-sg"
vpc_id = aws_vpc.higa-vpc.id
ingress {
from_port = 2049
to_port = 2049
protocol = "tcp"
//ec2セキュリティグループが紐づくリソースにアクセス許可
security_groups = [aws_security_group.higa-ec2-sg.id]
}
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
tags = {
Name = "higa-EFS-sg"
}
}
設定項目は下記の通りです。
使用するオプション | 設定値 | 説明 |
---|---|---|
name | higa-EFS-sg | セキュリティグループ名 |
description | higa-EFS-sg | 説明 |
vpc_id | aws_vpc.higa-vpc.id | VPCの指定 |
tags | Name = "higa-EFS-sg" | Nameの表記を設定 |
設定項目 | 設定値 | 説明 |
---|---|---|
タイプ | NFS | EC2のSGのみを許可 |
ポート | 2049 | アクセスを許可したいプロトコルのポート範囲を入力 |
プロトコル | TCP | プロトコルを入力 |
5.疎通確認
作成したEC2インスタンス(TerraformによるEC2作成方法)を起動させて、疎通確認を行います。
「自分のWindows PC」から「EC2インスタンス(higa-ec2-1)」に接続できるか確認します。
疎通確認はPowerShellで行います。
①.SSHの疎通確認を下記コマンドで確認します。
Test-NetConnection [作成したEC2のパブリックIPv4] -port 22
SSHは自分のIPアドレスを受け入れているので成功しました。
②.HTTPの疎通確認を下記コマンドで確認します。
Test-NetConnection [作成したEC2のパブリックIPv4] -port 80
HTTPはALBからの通信以外は失敗するはずなので、上記の通り失敗しました。
疎通確認からEC2のSGが正常に動作していることが確認できました。
コマンドプロンプトとPowerShellの違い
簡単に説明すると、PowerShellはコマンドプロンプトの上位互換です。
PowerShellは従来のコマンドプロンプトよりも複雑ですが、それと同時に非常にパワフルな機能も備わっています。
下記に比較した表をまとめました。
説明 | Powershell | コマンドプロンプト |
---|---|---|
特徴 | コマンドプロンプトの後期機能。Windows7移行で標準機能(無料) | 初期Windowsから標準機能(無料) |
機能 | 高機能。原則として「コマンドプロンプト」の機能はほとんど使える | 貧弱 |
使い分け | 複雑な処理を行いたい場合 | 簡単な処理を行いたい場合(cp,cdコマンド等) |
6.苦労した点
疎通確認を行う際、初めはTera termでsshログインをして実行しようとしたのですが、Test-NetConnection
コマンドを実行したところ、「Test-NetConnection: command not found」と表示されてしまい、悩んでいました。
PowerShellでTest-NetConnection
コマンドを実行することで疎通確認ができました。
7.まとめ
SGの設定ではIPアドレスの指定だけでなく、他のSGを指定できるところがすごいと思いました。
また、TerraformでSGを作成するにあたって、SG用のファイルで管理することで、SGの設定項目が分かりやすいと感じました。
8.参考文献
- terraformの公式ドキュメント
Docs overview | hashicorp/aws | Terraform Registry