vi new-vpc.yaml
AWSTemplateFormatVersion: 2010-09-09 Resources: VPC: #VPC 생성 Type: AWS::EC2::VPC Properties: CidrBlock: 192.168.0.0/16 EnableDnsSupport: true #DNS주소 활성화 EnableDnsHostnames: true #DNS 호스트이름 활성화 InstanceTenancy: default Tags: - Key: Name Value: NEW-VPC SubnetA: Type: AWS::EC2::Subnet Properties: AvailabilityZone: ap-northeast-2a VpcId: !Ref VPC CidrBlock: 192.168.0.0/20 MapPublicIpOnLaunch: true Tags: - Key: Name Value: NEW-PUBLIC-SUBNET-2A SubnetB: Type: AWS::EC2::Subnet Properties: AvailabilityZone: ap-northeast-2b VpcId: !Ref VPC CidrBlock: 192.168.16.0/20 MapPublicIpOnLaunch: true Tags: - Key: Name Value: NEW-PUBLIC-SUBNET-2B SubnetC: Type: AWS::EC2::Subnet Properties: AvailabilityZone: ap-northeast-2c VpcId: !Ref VPC CidrBlock: 192.168.32.0/20 MapPublicIpOnLaunch: true Tags: - Key: Name Value: NEW-PUBLIC-SUBNET-2C SubnetD: Type: AWS::EC2::Subnet Properties: AvailabilityZone: ap-northeast-2d VpcId: !Ref VPC CidrBlock: 192.168.48.0/20 MapPublicIpOnLaunch: true Tags: - Key: Name Value: NEW-PUBLIC-SUBNET-2D InternetGateway: # 인터넷 게이트웨이 생성 Type: AWS::EC2::InternetGateway Properties: Tags: - Key: Name Value: NEW-IGW VPCGatewayAttachment: # 인터넷 게이트웨이 VPC와 연결(Attach, Associate) Type: AWS::EC2::VPCGatewayAttachment Properties: VpcId: !Ref VPC InternetGatewayId: !Ref InternetGateway RouteTableA: Type: AWS::EC2::RouteTable Properties: VpcId: !Ref VPC Tags: - Key: Name Value: NEW-PUBLIC-RTB InternetRoute: Type: AWS::EC2::Route DependsOn: InternetGateway Properties: DestinationCidrBlock: 0.0.0.0/0 GatewayId: !Ref InternetGateway RouteTableId: !Ref RouteTableA SubnetARouteTableAssociation: Type: AWS::EC2::SubnetRouteTableAssociation Properties: RouteTableId: !Ref RouteTableA SubnetId: !Ref SubnetA SubnetBRouteTableAssociation: Type: AWS::EC2::SubnetRouteTableAssociation Properties: RouteTableId: !Ref RouteTableA SubnetId: !Ref SubnetB SubnetCRouteTableAssociation: Type: AWS::EC2::SubnetRouteTableAssociation Properties: RouteTableId: !Ref RouteTableA SubnetId: !Ref SubnetC SubnetDRouteTableAssociation: Type: AWS::EC2::SubnetRouteTableAssociation Properties: RouteTableId: !Ref RouteTableA SubnetId: !Ref SubnetD Mappings: RegionMap: # 여기 식별자 이름은 별로 자유롭게 설정 가능하다. ap-northeast-2: # 리전별로 특화된 AMI의 ID를 미리 정의해 놓는다. 같은 yaml파일로 다른 리전에서 사용가능하다. AMIID: ami-0fd0765afb77bcca7 ap-northeast-1: AMIID: ami-0b7546e839d7ace12 Parameters: # 입력받는 부분 InstanceTypeParameter: #인스턴스 타입을 입력받을 것이다. Type: String Default: t2.micro #기본값은 t2.micro Description: Enter instance size. Default is t2.micro # VPC: # Type: String # Default: vpc-01a276b266db7833b # Description: VPC ID. # 아래 설명은, 배포했을때의 사용자가 정보를 제대로 입력할 수 있게 도와준다. # Subnet: # Subnet ID를 위에서 참조해서 사용해본다. # Type: String # Default: subnet-01132b9dddcf71d3d # Description: Subnet ID. AMI: Type: String Default: AMIID Description: The Linux AMI to use. Key: Type: String Default: new-key Description: The key used to access the instance. Resources: InstanceSecurityGroup: Type: AWS::EC2::SecurityGroup Properties: GroupName: "NEW-SG-WEB" GroupDescription: "SSH and web traffic in, all traffic out." VpcId: !Ref VPC SecurityGroupIngress: - IpProtocol: tcp FromPort: '80' ToPort: '80' CidrIp: 0.0.0.0/0 - IpProtocol: tcp FromPort: '22' ToPort: '22' CidrIp: 123.142.252.25/32 - IpProtocol: icmp #icmp를 추가하였다. FromPort: '-1' ToPort: '-1' CidrI[: 0.0.0.0/0 SecurityGroupEgress: - IpProtocol: -1 CidrIp: 0.0.0.0/0 EC2Instance: Type: 'AWS::EC2::Instance' Properties: SubnetId: !Ref SubnetA # 위에서 SubnetA가 정의되어 있으니 이걸 사용해본다. # ImageId: !Ref AMI ImageId: !FindInMap [ RegionMap, !Ref "AWS::Region", !Ref AMI ] # AWS의 Region을 참조해서 위 RegionMap에서 AMI ID를 가져올 것이다. InstanceType: # 위 !Ref InstanceTypeParameter로 사용할 수 있지만 아래와같이 사용할 수 있다. Ref: InstanceTypeParameter KeyName: !Ref Key SecurityGroupIds: - Ref: InstanceSecurityGroup BlockDeviceMappings: - DeviceName: /dev/xvda Ebs: VolumeSize: 8 - DeviceName: /dev/xvdb # 추가로 붙힌 볼륨은 Mount를 해줘야 한다. Ebs: VolumeSize: 8 Tags: - Key: Name Value: NEW-EC2 UserData: # 사용자 명령어 Fn::Base64: | # 사용자 명령어가 깨질 수 있으니 안정적으로 넣어주기 위한 함수이다. #cloud-boothook #!/bin/bash yum install -y httpd systemctl enable --now httpd echo "Hello World!" > /var/www/html/index.html Outputs: PublicIp: Description: PublicIp Output # output으로 출력할 것 Value: {"Fn::GetAtt": ["EC2Instance","PublicIp"]} # EC2Instance부분의 PublicIp를 가져올 것이다.
- 현재 어제 실습했던 Yaml파일 두개를 합쳤다.
- 그런데 Resorce가 두개가 정의되어 있어 에러가 난다.
- Mapping을 하나로 하고, Resources도 합쳐본다.
vi new-vpc.yaml Ver2
AWSTemplateFormatVersion: 2010-09-09 Mappings: RegionMap: ap-northeast-2: AMIID: ami-0fd0765afb77bcca7 ap-northeast-1: AMIID: ami-0b7546e839d7ace12 Parameters: InstanceTypeParameter: Type: String Default: t2.micro Description: Enter instance size. Default is t2.micro # VPC: # Type: String # Default: vpc-01a276b266db7833b # Description: VPC ID. # Subnet: # Type: String # Default: subnet-01132b9dddcf71d3d # Description: Subnet ID. AMI: Type: String Default: AMIID Description: The Linux AMI to use. Key: Type: String Default: new-key Description: The key used to access the instance. Resources: VPC: Type: AWS::EC2::VPC Properties: CidrBlock: 192.168.0.0/16 EnableDnsSupport: true EnableDnsHostnames: true InstanceTenancy: default Tags: - Key: Name Value: NEW-VPC SubnetA: Type: AWS::EC2::Subnet Properties: AvailabilityZone: ap-northeast-2a VpcId: !Ref VPC CidrBlock: 192.168.0.0/20 MapPublicIpOnLaunch: true Tags: - Key: Name Value: NEW-PUBLIC-SUBNET-2A SubnetB: Type: AWS::EC2::Subnet Properties: AvailabilityZone: ap-northeast-2b VpcId: !Ref VPC CidrBlock: 192.168.16.0/20 MapPublicIpOnLaunch: true Tags: - Key: Name Value: NEW-PUBLIC-SUBNET-2B SubnetC: Type: AWS::EC2::Subnet Properties: AvailabilityZone: ap-northeast-2c VpcId: !Ref VPC CidrBlock: 192.168.32.0/20 MapPublicIpOnLaunch: true Tags: - Key: Name Value: NEW-PUBLIC-SUBNET-2C SubnetD: Type: AWS::EC2::Subnet Properties: AvailabilityZone: ap-northeast-2d VpcId: !Ref VPC CidrBlock: 192.168.48.0/20 MapPublicIpOnLaunch: true Tags: - Key: Name Value: NEW-PUBLIC-SUBNET-2D InternetGateway: Type: AWS::EC2::InternetGateway Properties: Tags: - Key: Name Value: NEW-IGW VPCGatewayAttachment: Type: AWS::EC2::VPCGatewayAttachment Properties: VpcId: !Ref VPC InternetGatewayId: !Ref InternetGateway RouteTableA: Type: AWS::EC2::RouteTable Properties: VpcId: !Ref VPC Tags: - Key: Name Value: NEW-PUBLIC-RTB InternetRoute: Type: AWS::EC2::Route DependsOn: InternetGateway Properties: DestinationCidrBlock: 0.0.0.0/0 GatewayId: !Ref InternetGateway RouteTableId: !Ref RouteTableA SubnetARouteTableAssociation: Type: AWS::EC2::SubnetRouteTableAssociation Properties: RouteTableId: !Ref RouteTableA SubnetId: !Ref SubnetA SubnetBRouteTableAssociation: Type: AWS::EC2::SubnetRouteTableAssociation Properties: RouteTableId: !Ref RouteTableA SubnetId: !Ref SubnetB SubnetCRouteTableAssociation: Type: AWS::EC2::SubnetRouteTableAssociation Properties: RouteTableId: !Ref RouteTableA SubnetId: !Ref SubnetC SubnetDRouteTableAssociation: Type: AWS::EC2::SubnetRouteTableAssociation Properties: RouteTableId: !Ref RouteTableA SubnetId: !Ref SubnetD InstanceSecurityGroup: Type: AWS::EC2::SecurityGroup Properties: GroupName: "NEW-SG-WEB" GroupDescription: "SSH and web traffic in, all traffic out." VpcId: !Ref VPC SecurityGroupIngress: - IpProtocol: tcp FromPort: '80' ToPort: '80' CidrIp: 0.0.0.0/0 - IpProtocol: tcp FromPort: '22' ToPort: '22' CidrIp: 123.142.252.25/32 - IpProtocol: icmp FromPort: '-1' ToPort: '-1' CidrIp: 0.0.0.0/0 SecurityGroupEgress: - IpProtocol: -1 CidrIp: 0.0.0.0/0 EC2Instance: Type: 'AWS::EC2::Instance' Properties: SubnetId: !Ref SubnetA # ImageId: !Ref AMI ImageId: !FindInMap [ RegionMap, !Ref "AWS::Region", !Ref AMI ] InstanceType: Ref: InstanceTypeParameter KeyName: !Ref Key SecurityGroupIds: - Ref: InstanceSecurityGroup BlockDeviceMappings: - DeviceName: /dev/xvda Ebs: VolumeSize: 8 - DeviceName: /dev/xvdb Ebs: VolumeSize: 8 Tags: - Key: Name Value: NEW-EC2 UserData: Fn::Base64: | #cloud-boothook #!/bin/bash yum install -y httpd systemctl enable --now httpd echo "Hello World!" > /var/www/html/index.html Outputs: PublicIp: Description: PublicIp Output Value: {"Fn::GetAtt": ["EC2Instance","PublicIp"]}
- 에러가 발견되지 않았다.
- 잘 완성되어 퍼블릭IP주소가 출력되었다.
- 확인했다면 지워준다.
- 삭제 완료
provider "aws" {
region = "ap-northeast-2"
}
data "aws_availability_zones" "available" { # 가용영역중에 available한 가용역역의 리스트를 가져올 것이다.
state = "available"
}
resource "aws_vpc" "new_vpc" {
cidr_block = "192.168.0.0/16"
enable_dns_hostnames = true
enable_dns_support = true
instance_tenancy = "default"
tags = {
Name = "NEW-VPC"
}
}
resource "aws_subnet" "new_public_subnet_2a" {
vpc_id = aws_vpc.new_vpc.id # 이름에 `_`를 넣어보았다.
cidr_block = "192.168.0.0/20"
map_public_ip_on_launch = true #퍼블릭 IP자동할당을 활성화한다.
availability_zone = data.aws_availability_zones.available.names[0] # 0의 의미는 a의 의미다. 즉 가용영역 a라는 소리다.
tags = { # tags 와 `{`사이에 `=`이 있어야 한다. 이는 1.2.3버전에서 새로 변경된 사항이다.
Name = "NEW-PUBLIC-SUBNET-2A" # 이름을 넣어준다.
}
}
resource "aws_subnet" "new_public_subnet_2b" {
vpc_id = aws_vpc.new_vpc.id
cidr_block = "192.168.16.0/20"
map_public_ip_on_launch = true
availability_zone = data.aws_availability_zones.available.names[1]
tags = {
Name = "NEW-PUBLIC-SUBNET-2B"
}
}
resource "aws_subnet" "new_public_subnet_2c" {
vpc_id = aws_vpc.new_vpc.id
cidr_block = "192.168.32.0/20"
map_public_ip_on_launch = true
availability_zone = data.aws_availability_zones.available.names[2]
tags = {
Name = "NEW-PUBLIC-SUBNET-2C"
}
}
resource "aws_subnet" "new_public_subnet_2d" {
vpc_id = aws_vpc.new_vpc.id
cidr_block = "192.168.48.0/20"
map_public_ip_on_launch = true
availability_zone = data.aws_availability_zones.available.names[3]
tags = {
Name = "NEW-PUBLIC-SUBNET-2D"
}
}
resource "aws_internet_gateway" "new_igw" { # 인터넷게이트풰이 정의
vpc_id = aws_vpc.new_vpc.id # 인터넷게이트웨이를 생성하면서 동시에 VPC와 Attachment한다.
tags = {
Name = "NEW-IGW"
}
}
resource "aws_route_table" "new_public_rtb" { # 라우팅테이블 생성
vpc_id = aws_vpc.new_vpc.id # aws_vpc의 new_vpc의 id를 가져온다.
route {
cidr_block = "0.0.0.0/0"
gateway_id = aws_internet_gateway.new_igw.id
}
tags = { # 태그를 붙혀준다
Name = "NEW-PUBLIC-RTB"
}
}
resource "aws_route_table_association" "new_public_subnet_2a_association" { # 라우팅테이블과 sub넷을 연결해준다.
subnet_id = aws_subnet.new_public_subnet_2a.id
route_table_id = aws_route_table.new_public_rtb.id
}
resource "aws_route_table_association" "new_public_subnet_2b_association" {
subnet_id = aws_subnet.new_public_subnet_2b.id
route_table_id = aws_route_table.new_public_rtb.id
}
resource "aws_route_table_association" "new_public_subnet_2c_association" {
subnet_id = aws_subnet.new_public_subnet_2c.id
route_table_id = aws_route_table.new_public_rtb.id
}
resource "aws_route_table_association" "new_public_subnet_2d_association" {
subnet_id = aws_subnet.new_public_subnet_2d.id
route_table_id = aws_route_table.new_public_rtb.id
}
timedatectl
로 확인한다.data
yum install -y rdate
rdate -s time.bora.net
vi new-vpc.tf
data "aws_availability_zones" "available" { state = "available" } resource "aws_vpc" "new_vpc" { cidr_block = "192.168.0.0/16" enable_dns_hostnames = true enable_dns_support = true instance_tenancy = "default" tags = { Name = "NEW-VPC" } } resource "aws_subnet" "new_public_subnet_2a" { vpc_id = aws_vpc.new_vpc.id cidr_block = "192.168.0.0/20" map_public_ip_on_launch = true availability_zone = data.aws_availability_zones.available.names[0] tags = { Name = "NEW-PUBLIC-SUBNET-2A" } } resource "aws_subnet" "new_public_subnet_2b" { vpc_id = aws_vpc.new_vpc.id cidr_block = "192.168.16.0/20" map_public_ip_on_launch = true availability_zone = data.aws_availability_zones.available.names[1] tags = { Name = "NEW-PUBLIC-SUBNET-2B" } } resource "aws_subnet" "new_public_subnet_2c" { vpc_id = aws_vpc.new_vpc.id cidr_block = "192.168.32.0/20" map_public_ip_on_launch = true availability_zone = data.aws_availability_zones.available.names[2] tags = { Name = "NEW-PUBLIC-SUBNET-2C" } } resource "aws_subnet" "new_public_subnet_2d" { vpc_id = aws_vpc.new_vpc.id cidr_block = "192.168.48.0/20" map_public_ip_on_launch = true availability_zone = data.aws_availability_zones.available.names[3] tags = { Name = "NEW-PUBLIC-SUBNET-2D" } } resource "aws_internet_gateway" "new_igw" { vpc_id = aws_vpc.new_vpc.id tags = { Name = "NEW-IGW" } } resource "aws_route_table" "new_public_rtb" { vpc_id = aws_vpc.new_vpc.id route { cidr_block = "0.0.0.0/0" gateway_id = aws_internet_gateway.new_igw.id } tags = { Name = "NEW-PUBLIC-RTB" } } resource "aws_route_table_association" "new_public_subnet_2a_association" { subnet_id = aws_subnet.new_public_subnet_2a.id route_table_id = aws_route_table.new_public_rtb.id } resource "aws_route_table_association" "new_public_subnet_2b_association" { subnet_id = aws_subnet.new_public_subnet_2b.id route_table_id = aws_route_table.new_public_rtb.id } resource "aws_route_table_association" "new_public_subnet_2c_association" { subnet_id = aws_subnet.new_public_subnet_2c.id route_table_id = aws_route_table.new_public_rtb.id } resource "aws_route_table_association" "new_public_subnet_2d_association" { subnet_id = aws_subnet.new_public_subnet_2d.id route_table_id = aws_route_table.new_public_rtb.id } resource "aws_instance" "example" { # 인스턴스 생성 ami = "ami-0fd0765afb77bcca7" instance_type = "t2.micro" # 직접 입력할수도, 데이터를 가져올수도 있다. subnet_id = aws_subnet.new_public_subnet_2a.id # 서브넷ID를 추가해주었다. vpc_security_group_ids = [aws_security_group.instance.id] #aws_security_group에서 instance.id를 가져올 것이다. 가져올떄는 `[` 괄호를 사용해야 한다. key_name = "new-key" # 그렇다면 aws_security_group을 정의해야 하는데 이는 아래에 있다. user_data = <<-EOF #!/bin/bash yum install -y httpd systemctl enable --now httpd echo "Hello, Terraform" > /var/www/html/index.html EOF tags = { Name = "terraform-example" } } resource "aws_security_group" "instance" { # 보안그룹 생성, instance라는 이름으로 정의한다. vpc_id = data.aws_vpc.new_npc.id name = var.security_group_name ingress { from_port = 80 to_port = 80 protocol = "tcp" cidr_blocks = ["0.0.0.0/0"] } ingress { from_port = 22 to_port = 22 protocol = "tcp" cidr_blocks = ["123.142.252.25/32"] } ingress { from_port = -1 to_port = -1 protocol = "icmp" cidr_blocks = ["0.0.0.0/0"] } egress { from_port = 0 to_port = 0 protocol = "-1" cidr_blocks = ["0.0.0.0/0"] } tags = { Name = "terraform-sg" } } variable "security_group_name" { # 변수 security_group_name을 정의한다. description = "The name of the security group" type = string default = "terraform-example-instance" } output "public_ip" { # public IP 출력 value = aws_instance.example.public_ip description = "The public IP of the Instance" } output "public_dns" { # Public_dns 출력 value = aws_instance.example.public_dns description = "The Public dns of the Instance" } output "private_ip" { # private ip출력 value = aws_instance.example.private_ip description = "The Private_ip of the Instance" } # terraform init # terraform plan # terraform apply # terraform output public_ip # terraform destroy
- 전 VPC생성 코드에 EC2 생성코드를 추가하였다.
terraform plan
- 2개가 추가되고 변경사항은 없다.
- 인스턴스 생성, 보안그룹 생성
- terraform init은 자주하면 좋지만 너무 자주할 필요는 없다. 업데이트 점검용으로 사용한다.
terraform apply
- 에러가 났다.
- 서브넷의 네트워크와 보안그룹의 네트워크가 달르다는 에러인 것 같다.
subnet_id = aws_subnet.new_public_subnet_2a.id
이 부분에서 subnetID를 가져오지 못한다.
subnet_id = data.aws_subnet.apne2_az1.id
로 바꿔주고, 아래를 선언해준다.data "aws_vpc" "new_vpc" { tags = { Name = "NEW-VPC" } } data "aws_subnet" "apne2_az1" { tags = { Name = "NEW-PUBLIC-SUBNET-2A" } }
- 위 부분을 넣어준다.
- aws_vpc에서 new_vpc라는 이름으로 Name=NEW-VPC라는 태그가 있는 애들을 가져온다.
- 또, aws_subnet에서 apne2_az1이라는 이름으로 NEW-PUBLIC-SUBNET-2A태그가 있는 애들을 가져온다.
- 마지막으로 보안그룹 설정에
vpc_id = data.aws_vpc.new_npc.id
를 넣어서 vpc_id를 사용할 수 있게 해준다.
- 위와 같이 넣어준다.
terraform apply
- apply까지 잘 되었다.
terraform destroy
- 테라폼 작업한것들을 정리해준다.
vi main.tf
provider "aws" { # Privider 정의 region = "ap-northeast-2" } data "aws_vpc" "new_vpc" { tags = { # 사용할 VPC Name = "NEW-VPC" } } data "aws_subnet" "apne2_az1" { # 프리티어에서 가용영역 b, d는 사용할 수 없기 때문에 A, C만 정의해준다. tags = { Name = "NEW-PUBLIC-SUBNET-2A" } } data "aws_subnet" "apne2_az3" { tags = { Name = "NEW-PUBLIC-SUBNET-2C" } } variable "security_group_name" { # 보안그룹 이름 정의 description = "The name of the security group" type = string default = "NEW-SG-ALB" } resource "aws_security_group" "new_sg_alb" { name = var.security_group_name vpc_id = data.aws_vpc.new_vpc.id # 보안그룹의 VPC ID는 data에서 정의한 aws_vpc의 new_Vpc의 id를 가져온다. ingress { # 보안그룹에서 80번포트만 사용한다. from_port = 80 to_port = 80 protocol = "tcp" cidr_blocks = ["0.0.0.0/0"] } egress { from_port = 0 to_port = 0 protocol = "-1" cidr_blocks = ["0.0.0.0/0"] } tags = { Name = "NEW-SG-ALB" } } resource "aws_lb" "frontend" { # aws_lb는 ELB를 말한다. 예전 버전에서는 aws_elb로 사용했지만 최근 버전은 lb로 사용한다. name = "alb_example" internal = false # 인터넷 경계 설정, 내부가 아니다. load_balancer_type = "application" #ALB를 뜻한다. security_groups = aws_security_group.new_sg_alb.id subnets = [ data.aws_subnet.apne2_az1.id, data.aws_subnet.apne2_az3.id ] tags = { Name = "NEW-ALB" } lifecycle { create_before_destroy = true } # 지우기전에 생성한다는 의미다. EC2를 지우기전에 만들어라. } resource "aws_instance" "alb_vm_01" { ami = "ami-0fd0765afb77bcca7" instance_type = "t2.micro" subnet_id = data.aws_subnet.apne2_az1.id vpc_security_group_ids = aws_security_group.new_sg_alb.id key_name = "new-key" user_data = #! /bin/bash yum install -y httpd systemctl enable --now httpd echo "Hello, Terraform01" > /var/www/html/index.html EOF tags = { Name = "ALB01" } } resource "aws_instance" "alb_vm_02" { ami = "ami-0fd0765afb77bcca7" instance_type = "t2.micro" subnet_id = data.aws_subnet.apne2_az3.id vpc_security_group_ids = aws_security_group.new_sg_alb.id key_name = "new-key" user_data = <<-EOF #! /bin/bash yum install -y httpd systemctl enable --now httpd echo "Hello, Terraform02" > /var/www/html/index.html EOF
tags = {
Name = "ALB02"
}
}
resource "aws_lb_target_group" "tg" { # 타겟 그룹 설정
name = "TargetGroup"
port = 80 # 80번 포트를 사용한다. 백엔드에서 인스턴스들에게 80번포트로 통신 할 것이다.
target_type = "instance" # 타겟의 타입은 instance
protocol = "HTTP" # HTTP를 사용할 것이다.
vpc_id = data.aws_vpc.new_vpc.id # data에서 정의한 aws_vpc의 new_vpc의 id를 가져온다.health_check {
path = "/" # 패스틑 루트폴더로 하지만, 특별한 패스를 줄 수 있고, 여기에 index.html이 반드시 존재해야 한다.
protocol = "HTTP"
matcher = "200" # 200 코드를 반환해야지만 성공으로 본다.
interval = 15 # 상태확인을 15초 간격으로 한다.
timeout = 3 # 3초 이내의 응답해야 성공이다.
healthy_threshold = 2 # 2번 이상 성공하면 정상화되었다고 판단한다.
unhealthy_threshold = 2 # 반대로 2번이상 실패하면 Fail 상태라고 판단한다.
}
}
resource "aws_alb_target_group_attachment" "tgattachment01" { # 타겟 그룹이다.
target_group_arn = aws_lb_target_group.tg.arn # arn(Amazon Resource Number)
target_id = aws_instance.alb-vm-01.id
port = 80
}
resource "aws_alb_target_group_attachment" "tgattachment02" {
target_group_arn = aws_lb_target_group.tg.arn
target_id = aws_instance.alb-vm-02.id
port = 80
}resource "aws_lb_listener" "front_end" {
load_balancer_arn = aws_lb.frontend.arn
port = "80"
protocol = "HTTP"default_action {
type = "forward"
target_group_arn = aws_lb_target_group.tg.arn
}
}
output "lb_dns_name" {
description = "The DNS name of the load balancer."
value = aws_lb.frontend.dns_name
}
- 위의 ALB생성 부분에 VPC생성 코드를 합쳐본다.
vi main.tf ver2
provider "aws" { region = "ap-northeast-2" } data "aws_vpc" "new_vpc" { tags = { Name = "NEW-VPC" } } data "aws_subnet" "apne2_az1" { tags = { Name = "NEW-PUBLIC-SUBNET-2A" } } data "aws_subnet" "apne2_az3" { tags = { Name = "NEW-PUBLIC-SUBNET-2C" } } data "aws_availability_zones" "available" { state = "available" } resource "aws_vpc" "new_vpc" { cidr_block = "192.168.0.0/16" enable_dns_hostnames = true enable_dns_support = true instance_tenancy = "default" tags = { Name = "NEW-VPC" } } resource "aws_subnet" "new_public_subnet_2a" { vpc_id = aws_vpc.new_vpc.id cidr_block = "192.168.0.0/20" map_public_ip_on_launch = true availability_zone = data.aws_availability_zones.available.names[0] tags = { Name = "NEW-PUBLIC-SUBNET-2A" } } resource "aws_subnet" "new_public_subnet_2b" { vpc_id = aws_vpc.new_vpc.id cidr_block = "192.168.16.0/20" map_public_ip_on_launch = true availability_zone = data.aws_availability_zones.available.names[1] tags = { Name = "NEW-PUBLIC-SUBNET-2B" } } resource "aws_subnet" "new_public_subnet_2c" { vpc_id = aws_vpc.new_vpc.id cidr_block = "192.168.32.0/20" map_public_ip_on_launch = true availability_zone = data.aws_availability_zones.available.names[2] tags = { Name = "NEW-PUBLIC-SUBNET-2C" } } resource "aws_subnet" "new_public_subnet_2d" { vpc_id = aws_vpc.new_vpc.id cidr_block = "192.168.48.0/20" map_public_ip_on_launch = true availability_zone = data.aws_availability_zones.available.names[3] tags = { Name = "NEW-PUBLIC-SUBNET-2D" } } resource "aws_internet_gateway" "new_igw" { vpc_id = aws_vpc.new_vpc.id tags = { Name = "NEW-IGW" } } resource "aws_route_table" "new_public_rtb" { vpc_id = aws_vpc.new_vpc.id route { cidr_block = "0.0.0.0/0" gateway_id = aws_internet_gateway.new_igw.id } tags = { Name = "NEW-PUBLIC-RTB" } } resource "aws_route_table_association" "new_public_subnet_2a_association" { subnet_id = aws_subnet.new_public_subnet_2a.id route_table_id = aws_route_table.new_public_rtb.id } resource "aws_route_table_association" "new_public_subnet_2b_association" { subnet_id = aws_subnet.new_public_subnet_2b.id route_table_id = aws_route_table.new_public_rtb.id } resource "aws_route_table_association" "new_public_subnet_2c_association" { subnet_id = aws_subnet.new_public_subnet_2c.id route_table_id = aws_route_table.new_public_rtb.id } resource "aws_route_table_association" "new_public_subnet_2d_association" { subnet_id = aws_subnet.new_public_subnet_2d.id route_table_id = aws_route_table.new_public_rtb.id } variable "security_group_name" { description = "The name of the security group" type = string default = "NEW-SG-ALB" } resource "aws_security_group" "new_sg_alb" { name = var.security_group_name vpc_id = data.aws_vpc.new_vpc.id 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" cidr_blocks = ["0.0.0.0/0"] } tags = { Name = "NEW-SG-ALB" } } resource "aws_lb" "frontend" { name = "alb_example" internal = false load_balancer_type = "application" security_groups = aws_security_group.new_sg_alb.id subnets = [ data.aws_subnet.apne2_az1.id, data.aws_subnet.apne2_az3.id ] tags = { Name = "NEW-ALB" } lifecycle { create_before_destroy = true } } resource "aws_instance" "alb_vm_01" { ami = "ami-0fd0765afb77bcca7" instance_type = "t2.micro" subnet_id = data.aws_subnet.apne2_az1.id vpc_security_group_ids = aws_security_group.new_sg_alb.id key_name = "new-key" user_data = #! /bin/bash yum install -y httpd systemctl enable --now httpd echo "Hello, Terraform01" > /var/www/html/index.html EOF tags = { Name = "ALB01" } } resource "aws_instance" "alb_vm_02" { ami = "ami-0fd0765afb77bcca7" instance_type = "t2.micro" subnet_id = data.aws_subnet.apne2_az3.id vpc_security_group_ids = aws_security_group.new_sg_alb.id key_name = "new-key" user_data = <<-EOF #! /bin/bash yum install -y httpd systemctl enable --now httpd echo "Hello, Terraform02" > /var/www/html/index.html EOF tags = { Name = "ALB02" } } resource "aws_lb_target_group" "tg" { name = "TargetGroup" port = 80 target_type = "instance" protocol = "HTTP" vpc_id = data.aws_vpc.new_vpc.id health_check { path = "/" protocol = "HTTP" matcher = "200" interval = 15 timeout = 3 healthy_threshold = 2 unhealthy_threshold = 2 } } resource "aws_alb_target_group_attachment" "tgattachment01" { target_group_arn = aws_lb_target_group.tg.arn target_id = aws_instance.alb-vm-01.id port = 80 } resource "aws_alb_target_group_attachment" "tgattachment02" { target_group_arn = aws_lb_target_group.tg.arn target_id = aws_instance.alb-vm-02.id port = 80 } resource "aws_lb_listener" "front_end" { load_balancer_arn = aws_lb.frontend.arn port = "80" protocol = "HTTP" default_action { type = "forward" target_group_arn = aws_lb_target_group.tg.arn } } output "lb_dns_name" { description = "The DNS name of the load balancer." value = aws_lb.frontend.dns_name }
- 위 코드로 terraform plan을 돌려본다.
terraform plan
- EOF에서 에러가 나왔다.
- 아까 EOF를 제거했었는데, 제거하면 안된다는 사실을 알았다.
- 또 그외에도 에러가 많아 다시 수정한다.
provider "aws" { region = "ap-northeast-2" } data "aws_availability_zones" "available" { state = "available" } resource "aws_vpc" "new_vpc" { cidr_block = "192.168.0.0/16" enable_dns_hostnames = true enable_dns_support = true instance_tenancy = "default"
tags = {
Name = "NEW-VPC"
}
}
resource "aws_subnet" "new_public_subnet_2a" {
vpc_id = aws_vpc.new_vpc.id
cidr_block = "192.168.0.0/20"
map_public_ip_on_launch = true
availability_zone = data.aws_availability_zones.available.names[0]
tags = {
Name = "NEW-PUBLIC-SUBNET-2A"
}
}
resource "aws_subnet" "new_public_subnet_2b" {
vpc_id = aws_vpc.new_vpc.id
cidr_block = "192.168.16.0/20"
map_public_ip_on_launch = true
availability_zone = data.aws_availability_zones.available.names[1]
tags = {
Name = "NEW-PUBLIC-SUBNET-2B"
}
}
resource "aws_subnet" "new_public_subnet_2c" {
vpc_id = aws_vpc.new_vpc.id
cidr_block = "192.168.32.0/20"
map_public_ip_on_launch = true
availability_zone = data.aws_availability_zones.available.names[2]
tags = {
Name = "NEW-PUBLIC-SUBNET-2C"
}
}
resource "aws_subnet" "new_public_subnet_2d" {
vpc_id = aws_vpc.new_vpc.id
cidr_block = "192.168.48.0/20"
map_public_ip_on_launch = true
availability_zone = data.aws_availability_zones.available.names[3]
tags = {
Name = "NEW-PUBLIC-SUBNET-2D"
}
}
resource "aws_internet_gateway" "new_igw" {
vpc_id = aws_vpc.new_vpc.id
tags = {
Name = "NEW-IGW"
}
}
resource "aws_route_table" "new_public_rtb" {
vpc_id = aws_vpc.new_vpc.id
route {
cidr_block = "0.0.0.0/0"
gateway_id = aws_internet_gateway.new_igw.id
}
tags = {
Name = "NEW-PUBLIC-RTB"
}
}
resource "aws_route_table_association" "new_public_subnet_2a_association" {
subnet_id = aws_subnet.new_public_subnet_2a.id
route_table_id = aws_route_table.new_public_rtb.id
}
resource "aws_route_table_association" "new_public_subnet_2b_association" {
subnet_id = aws_subnet.new_public_subnet_2b.id
route_table_id = aws_route_table.new_public_rtb.id
}
resource "aws_route_table_association" "new_public_subnet_2c_association" {
subnet_id = aws_subnet.new_public_subnet_2c.id
route_table_id = aws_route_table.new_public_rtb.id
}
resource "aws_route_table_association" "new_public_subnet_2d_association" {
subnet_id = aws_subnet.new_public_subnet_2d.id
route_table_id = aws_route_table.new_public_rtb.id
}
#data "aws_vpc" "new_vpc" {
tags = {
Name = "NEW-VPC"
}
#}
#data "aws_subnet" "apne2_az1" {tags = {
Name = "NEW-PUBLIC-SUBNET-2A"
}
#}
#data "aws_subnet" "apne2_az3" {tags = {
Name = "NEW-PUBLIC-SUBNET-2C"
}
#}
variable "security_group_name" {
description = "The name of the security group"
type = string
default = "NEW-SG-ALB"
}resource "aws_security_group" "new_sg_alb" {
name = var.security_group_namevpc_id = data.aws_vpc.new_vpc.id
vpc_id = aws_vpc.new_vpc.id
ingress {
from_port = 80
to_port = 80
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
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"
cidr_blocks = ["0.0.0.0/0"]
}
tags = {
Name = "NEW-SG-ALB"
}
}resource "aws_lb" "frontend" {
name = "alb-example"
internal = false
load_balancer_type = "application"
security_groups = [aws_security_group.new_sg_alb.id]
subnets = [
aws_subnet.new_public_subnet_2a.id,
aws_subnet.new_public_subnet_2c.id
]tags = {
Name = "NEW-ALB"
}lifecycle { create_before_destroy = true }
}resource "aws_instance" "alb_vm_01" {
ami = "ami-0fd0765afb77bcca7"
instance_type = "t2.micro"
subnet_id = aws_subnet.new_public_subnet_2a.id
vpc_security_group_ids = [aws_security_group.new_sg_alb.id]
key_name = "new-key"
user_data = <<-EOF
#! /bin/bash
yum install -y httpd
systemctl enable --now httpd
echo "Hello, Terraform01" > /var/www/html/index.html
EOFtags = {
Name = "ALB01"
}
}resource "aws_instance" "alb_vm_02" {
ami = "ami-0fd0765afb77bcca7"
instance_type = "t2.micro"
subnet_id = aws_subnet.new_public_subnet_2c.id
vpc_security_group_ids = [aws_security_group.new_sg_alb.id]
key_name = "new-key"
user_data = <<-EOF
#! /bin/bash
yum install -y httpd
systemctl enable --now httpd
echo "Hello, Terraform02" > /var/www/html/index.html
EOF
tags = {
Name = "ALB02"
}
}
resource "aws_lb_target_group" "tg" {
name = "TargetGroup"
port = 80
target_type = "instance"
protocol = "HTTP"
vpc_id = aws_vpc.new_vpc.idhealth_check {
path = "/"
protocol = "HTTP"
matcher = "200"
interval = 15
timeout = 3
healthy_threshold = 2
unhealthy_threshold = 2
}
}
resource "aws_alb_target_group_attachment" "tgattachment01" {
target_group_arn = aws_lb_target_group.tg.arn
target_id = aws_instance.alb_vm_01.id
port = 80
}
resource "aws_alb_target_group_attachment" "tgattachment02" {
target_group_arn = aws_lb_target_group.tg.arn
target_id = aws_instance.alb_vm_02.id
port = 80
}resource "aws_lb_listener" "front_end" {
load_balancer_arn = aws_lb.frontend.arn
port = "80"
protocol = "HTTP"default_action {
type = "forward"
target_group_arn = aws_lb_target_group.tg.arn
}
}
output "lb_dns_name" {
description = "The DNS name of the load balancer."
value = aws_lb.frontend.dns_name
}
- 위와같이 수정하고, terraform plan을 해본다.
terraform plan
- VPC, SUBNET, INTERNET GATEWAY, INSTANCE, ELB까지 19개가 생성될 것이다.
terraform apply
- plan 진행 후, yes를 입력받는다.
- 이후 인스턴스 생성 및 ELB생성때문에 대략 2분의 시간이 걸릴 것이다.
- 성공했다. output으로 지정한 lb_dns_name도 잘 출력되었다.
- 01 인스턴스에 들어왔다.
- 인스턴스는 2개가 잘 생성되었다.
vi varibles.tf
variable "security_group_name" { # 자주 사용하는 Security_group_name을 미리 varibles 파일로 정의해놓는다. description = "The name of the security group" type = string # 문자열로 default = "terraform-example-instance" # 이 이름을 정의한다. } variable "http_port" { # http_port를 80으로 정의해놓는다. description = "The port the server will use for HTTP requests" type = number default = 80 } variable "ssh_port" { # ssh_port로 22를 미리 정의해놓는다. description = "The port the server will use for SSH requests" type = number default = 22 }
- varibles만 따로 모아두고, 모듈처럼 사용할 수 있다.
vi main.tf
provider "aws" { region = "ap-northeast-2" } resource "aws_instance" "example" { ami = "ami-0fd0765afb77bcca7" instance_type = "t2.micro" vpc_security_group_ids = [aws_security_group.instance.id] key_name = "new-key" user_data = <<-EOF #! /bin/bash yum install -y httpd systemctl enable --now httpd echo "Hello, Terraform" > /var/www/html/index.html EOF tags = { Name = "terraform-example" } } resource "aws_security_group" "instance" { name = var.security_group_name ingress { from_port = var.http_port to_port = var.http_port protocol = "tcp" cidr_blocks = ["0.0.0.0/0"] } ingress { from_port = var.ssh_port to_port = var.ssh_port protocol = "tcp" cidr_blocks = ["0.0.0.0/0"] } ingress { from_port = -1 to_port = -1 protocol = "icmp" cidr_blocks = ["0.0.0.0/0"] } egress { from_port = 0 to_port = 0 protocol = "-1" cidr_blocks = ["0.0.0.0/0"] } tags = { Name = "terraform-sg" } }
- 인스턴스를 생성하는 부분이다. terraform은 폴더단위로 작업을 진행한다.
디렉토리 만들어서 tf파일 생성하기
cd ~
: ~디렉토리로 이동한다.mkdir test && cd $_
: test디렉토리를 만들고, 그 폴더로 이동한다.- vi 명령어로 variables와 main tf파일을 생성한다.
vi ourputs.tf
output "public_ip" { value = aws_instance.example.public_ip description = "The public IP of the Instance" } output "public_dns" { value = aws_instance.example.public_dns description = "The Public dns of the Instance" } output "private_ip" { value = aws_instance.example.private_ip description = "The Private_ip of the Instance" } # terraform init # terraform validate # terraform plan # terraform apply # terraform output public_ip # terraform destroy
- output도 따로 정의해준다.
- 파일 3개가 만들어져 있어야 한다.
terraform init
- init이 잘 됬다.
terraform validate
- 잘 동작하는지 검증하는 기능이다.
- 그러나 plan처럼 직접 apply할때 생기는 에러가 아직 존재한다.
terraform apply
- 잘 돌아간다.
- output 정보도 잘 나왔다.
terraform output
- 출력 데이터를 다시 출력해볼 수 잇다.
vi variables.tf
variable "instance_security_group_name" { description = "The name of the security group for the EC2 Instances" type = string default = "terraform-example-instance" } variable "http_port" { description = "The port the server will use for HTTP requests" type = number default = 80 } variable "ssh_port" { description = "The port the server will use for SSH requests" type = number default = 22 } variable "alb_name" { description = "The name of the ALB" type = string default = "terraform-asg-example" } variable "alb_security_group_name" { description = "The name of the security group for the ALB" type = string default = "terraform-example-alb" }
main.tf
provider "aws" { region = "ap-northeast-2" } resource "aws_launch_configuration" "example" { # 보안그룹을 AWS_escurity_group의 인스턴스.id로 불러올 것이다. image_id = "ami-0cbec04a61be382d9" instance_type = "t2.micro" security_groups = [aws_security_group.instance.id] user_data = <<-EOF #! /bin/bash yum install -y httpd systemctl enable --now httpd echo "Hello, Terraform" > /var/www/html/index.html EOF # Required when using a launch configuration with an auto scaling group. lifecycle { create_before_destroy = true } } resource "aws_autoscaling_group" "example" { # 위 보안그룹 정의와 이름이 같다.(example) 그러나 괜찮다. 앞에 aws_autoscaling_group처럼 자원 이름이 다르기 때문이다. launch_configuration = aws_launch_configuration.example.name # 시작구성 vpc_zone_identifier = data.aws_subnets.NEW-VPC.ids # data로 정의한 부분에서 aws의 서브넷들 중에 NEW-VPC의 id들을 가져온다. (서브넷의 ID기 때문에 여러개일 수 있다.) target_group_arns = [aws_lb_target_group.asg.arn] #아마존 resource numbers health_check_type = "ELB" # 헬스체크 타입은 ELB로 한다. min_size = 2 max_size = 4 tag { key = "Name" value = "terraform-asg-example" propagate_at_launch = true } } resource "aws_security_group" "instance" { name = var.instance_security_group_name ingress { from_port = var.http_port to_port = var.http_port protocol = "tcp" cidr_blocks = ["0.0.0.0/0"] } } data "aws_vpc" "NEW-VPC" { default = true # 디폴트 VPC를 사용한다....? } data "aws_subnets" "NEW-VPC" { filter { # 기본 VPC안에 있는 서브넷들을 가져올 것이다. name = "vpc-id" values = [data.aws_vpc.NEW-VPC.id] } } resource "aws_lb" "example" { name = var.alb_name load_balancer_type = "application" subnets = data.aws_subnets.NEW-VPC.ids #위에서 서브넷 4개를 가져온다. security_groups = [aws_security_group.alb.id] # 보안그룹, aws_security_group도 아래에서 선언될 것이다. 그 안의 alb의 id를 가져올 것이다. } resource "aws_lb_listener" "http" { load_balancer_arn = aws_lb.example.arn port = var.http_port protocol = "HTTP" # By default, return a simple 404 page default_action { type = "fixed-response" fixed_response { content_type = "text/plain" message_body = "404: page not found" status_code = 404 } } } resource "aws_lb_target_group" "asg" { name = var.alb_name port = var.http_port protocol = "HTTP" vpc_id = data.aws_vpc.NEW-VPC.id health_check { path = "/" protocol = "HTTP" matcher = "200" interval = 15 timeout = 3 healthy_threshold = 2 unhealthy_threshold = 2 } } resource "aws_lb_listener_rule" "asg" { listener_arn = aws_lb_listener.http.arn priority = 100 condition { path_pattern { values = ["*"] } } action { type = "forward" target_group_arn = aws_lb_target_group.asg.arn } } resource "aws_security_group" "alb" { name = var.alb_security_group_name # Allow inbound HTTP requests ingress { from_port = var.http_port to_port = var.http_port protocol = "tcp" cidr_blocks = ["0.0.0.0/0"] } # Allow all outbound requests egress { from_port = 0 to_port = 0 protocol = "-1" cidr_blocks = ["0.0.0.0/0"] } }