別VPCのリソースをALBで扱う
AWS環境の整備を進めていく中で、一時的にALBで別VPCにあるリソースを扱い時があったとする。
そんな時は、どのような対応ができるのか試してみる。
複数VPC環境を構築
まずは、複数VPCにEC2インスタンスを立てる。
片方のVPCにはALBを立てておく。
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 3.0"
}
}
}
provider "aws" {
region = "ap-northeast-1"
}
# --------------------------------------------------
# VPC alpha
# --------------------------------------------------
module "vpc_alpha" {
source = "terraform-aws-modules/vpc/aws"
name = "my-vpc-alpha"
cidr = "10.0.0.0/16"
azs = ["ap-northeast-1a", "ap-northeast-1c"]
public_subnets = ["10.0.1.0/24", "10.0.2.0/24"]
}
resource "aws_security_group" "alpha" {
name = "my-sg-alpha"
vpc_id = module.vpc_alpha.vpc_id
}
resource "aws_security_group_rule" "ingress_alpha" {
security_group_id = aws_security_group.alpha.id
type = "ingress"
description = "Allow from Any HTTP"
from_port = 80
to_port = 80
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
resource "aws_security_group_rule" "egress_alpha" {
security_group_id = aws_security_group.alpha.id
type = "egress"
description = "Allow to Any"
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
resource "aws_instance" "alpha" {
ami = "ami-08a8688fb7eacb171"
instance_type = "t2.micro"
security_groups = [resource.aws_security_group.alpha.id]
subnet_id = module.vpc_alpha.public_subnets[0]
associate_public_ip_address = true
user_data = join("\n", [
"#!/bin/bash",
"sudo yum update -y",
"sudo amazon-linux-extras install nginx1 -y",
"sudo systemctl enable nginx",
"sudo systemctl start nginx",
])
tags = {
Name = "my-ec2-alpha"
}
}
# --------------------------------------------------
# VPC beta
# --------------------------------------------------
module "vpc_beta" {
source = "terraform-aws-modules/vpc/aws"
name = "my-vpc-beta"
cidr = "10.1.0.0/16"
azs = ["ap-northeast-1a", "ap-northeast-1c"]
public_subnets = ["10.1.1.0/24", "10.1.2.0/24"]
}
resource "aws_security_group" "beta" {
name = "my-sg-beta"
vpc_id = module.vpc_beta.vpc_id
}
resource "aws_security_group_rule" "ingress_beta" {
security_group_id = aws_security_group.beta.id
type = "ingress"
description = "Allow from Any HTTP"
from_port = 80
to_port = 80
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
resource "aws_security_group_rule" "egress_beta" {
security_group_id = aws_security_group.beta.id
type = "egress"
description = "Allow to Any"
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
resource "aws_instance" "beta" {
ami = "ami-08a8688fb7eacb171"
instance_type = "t2.micro"
security_groups = [resource.aws_security_group.beta.id]
subnet_id = module.vpc_beta.public_subnets[0]
associate_public_ip_address = true
user_data = join("\n", [
"#!/bin/bash",
"sudo yum update -y",
"sudo yum install httpd -y",
"sudo systemctl enable httpd",
"sudo systemctl start httpd",
])
tags = {
Name = "my-ec2-beta"
}
}
# --------------------------------------------------
# ALB
# --------------------------------------------------
resource "aws_lb" "alpha" {
name = "my-alb-alpha"
load_balancer_type = "application"
security_groups = [resource.aws_security_group.alpha.id]
subnets = module.vpc_alpha.public_subnets
}
resource "aws_lb_listener" "alpha" {
load_balancer_arn = aws_lb.alpha.arn
port = "80"
protocol = "HTTP"
default_action {
type = "fixed-response"
fixed_response {
content_type = "text/plain"
message_body = "503 Service Temporarily Unavailable"
status_code = "503"
}
}
}
resource "aws_lb_target_group" "alpha" {
name = "my-tg-alpha"
port = 80
protocol = "HTTP"
vpc_id = module.vpc_alpha.vpc_id
}
resource "aws_lb_target_group_attachment" "alpha" {
target_group_arn = aws_lb_target_group.alpha.arn
target_id = aws_instance.alpha.id
port = 80
}
resource "aws_lb_listener_rule" "alpha" {
listener_arn = aws_lb_listener.alpha.arn
action {
type = "forward"
target_group_arn = aws_lb_target_group.alpha.arn
}
condition {
path_pattern { values = ["/*"] }
}
}
別VPCのTargetGroupをALBに設定できるか?
できない。
ALBのルールで指定しようと思っても選択できない。
PublicIPでTargetGroupを作成できるか?
できない。
TargetTypeとしてIPを選択し、PublicIPでリソースを指定しようと思っても設定できない。
PrivateIP以外は弾かれてしまう。
別VPCのPrivateIPでTargetGroupを作成できるか?
できる。
TargetTypeとしてIPを選択し、PrivateIPでリソースを指定すると作成できた。
ALBと同じVPCでTargetGroupを作成すれば、ALBのルールに設定することもできた。
ただし、Health statusがUnhealthyになっていて、このままでは使えない。
VPC peeringで繋いでみる
ヘルチェックを通すためには、別VPCのインスタンスに通信できる必要がある。
複数のVPCを繋げる、VPC peeringという機能がある。
その機能を使って、別VPCへと通信できる状態にしてみる。
まずは、Peering connectionを作成する。
作成したあとは、Acceptすることも忘れない。
次に、VPC間で通信するためのRoute tableを設定する。
Targetに作成したPeering connectionと、通信先VPCのIPレンジを指定する。
この状態でALBにアクセスしてみる。
別VPCのインスタンスに設定したApacheの画面が表示された。
ヘルスチェックにはHealth checks failed with these codes: [403]
と出ているが、Apacheのテストページが403で返ってくるので良しとする。
CIDRが同じ場合は?
できない。
Peering connectionが作成できない。
当たり前な感じがするが、同じ範囲のIPを使っている場合は、VPCを繋げられない。
この場合は、積んだのかもしれない。
まとめ
別VPCにあるリソースをALBで扱うことができる場合もある、ということがわかった。
ネットワーク設計せずに適当に構築すると、困る場面もあるんだなと思った。
VPCは量産せずに、1環境1VPCにしておくと良いのだろうか。
VPCとか気にせずに構築できるような状態になってくれると嬉しい。
Discussion