# Terraform을 활용한 EC2 인스턴스 생성 후 아파치 웹서버를 설치하여 확인을 해보자.
1. 목표 아키텍처 확인하기
- 이해를 돕기 위해 주요 리소스에 넘버링을 하였다.
- EC2 인스턴그 관련 리소스만 설명을 하면 아래와 같다. (파란색 바탕의 넘버링 확인)
① EIP : EC2 인스턴스가 사용할 EIP를 생성한다.
② EC2 인스턴스 : 퍼블릭 망에 존재하는 EC2 인스턴스이다.
②-① : EC2 인스턴스에 구성될 Apache WebServer이다.
③ PrivateKey : RSA 알고리즘으로 구성된 TLS Private Key이다.
④ 보안그룹 : 해당 EC2 인스턴스에서 사용할 보안그룹을 생성한다. (인바운드와 아웃바운드도 설정)
⑤ KeyPair :. pem으로 구성된 Key_Pair 파일을 생성한다.
- 일단 1번에서 14번까지는 아래의 링크를 확인한다.
2023.02.28 - [Terraform(테라폼)/Module-VPC] - Terraform - Module을 활용한 VPC 설계
2. 구성한 Terraform Code 실행하기
- 구조를 보면 아래와 같다.
- Root 폴더 아래에 modules라는 폴더가 보인다. Root 폴더 아래에 변수로 정의된 리소스가 module폴더를 활용하여 리소스를 생성한다고 보면 된다.
├─modules
│ ├─module.ec2
│ └─module.vpc
└─Root
└─.terraform
├─modules
└─providers
└─registry.terraform.io
└─hashicorp
├─aws
│ └─4.56.0
│ └─windows_386
├─local
│ └─2.3.0
│ └─windows_386
└─tls
└─4.0.4
└─windows_386
- Terraform 폴더 구조는 아래와 같다.
Root 폴더아래에 정의된 ec2.tf와 vpc.tf 파일이 modules 폴더의 ec2와 vpc를 참조하여 리소스를 생성한다.
3. Root 폴더의 ec2.tf 파일과 vpc.tf 파일 내용
- ec2.tf 파일 내용
- source 경로는 해당 변수집합이 맵핑될 경로를 말한다.
- 나머지는 default 값으로 세팅하였다.
여기서 중요한 점은 module로 구성되었기 때문에 아래의 변수 값들만 변경하거나 추가하면 새로운 환경의 ec2를 생성할 수 있다는 점이다.
module "ec2" {
source = "../modules/module.ec2"
ami_number = "ami-0eddbd81024d3fbdd"
instance_type = "t2.micro"
key_name = "webserver"
public_subnet = module.vpc.public_subnet_id
public_subnet-a = module.vpc.public_subnet_id-a
private_subnet = module.vpc.private_subnet_id
private_subnet-a = module.vpc.private_subnet_id-a
vpc_id = module.vpc.vpc_id
}
- vpc.tf 파일내용은 아래와 같다.
module "vpc" {
source = "../modules/module.vpc"
vpc_cidr_block = "10.0.0.0/16"
public_subnet_cidr_block = "10.0.1.0/24"
public_subnet_cidr_block-a = "10.0.2.0/24"
private_subnet_cidr_block = "10.0.3.0/24"
private_subnet_cidr_block-a = "10.0.4.0/24"
vpc_name = "terraform_vpc_test"
public_subnet_name = "terraform_vpc_test_public_subnet-a"
public_subnet_name-a = "terraform_vpc_test_public_subnet-b"
private_subnet_name = "terraform_vpc_test_private_subnet-a"
private_subnet_name-a = "terraform_vpc_test_private_subnet-b"
}
4. Root 폴더에서 terraform plan 명령어를 사용하여 생성될 리소스를 확인한다.
- terraform plan을 했을 때 vpc.tf와 ec2.tf 파일을 참조하여 예상 리소스를 화면에 보여준다.
아래 "더 보기" 항목을 클릭하여 전체 리소스 코드를 확인할 수 있다.
PS \Terraform_New\Terraform_seung\Root> terraform plan
Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following
symbols:
+ create
Terraform will perform the following actions:
# module.ec2.aws_eip.webserver will be created
+ resource "aws_eip" "webserver" {
+ allocation_id = (known after apply)
+ association_id = (known after apply)
+ carrier_ip = (known after apply)
+ customer_owned_ip = (known after apply)
+ domain = (known after apply)
+ id = (known after apply)
+ instance = (known after apply)
+ network_border_group = (known after apply)
+ network_interface = (known after apply)
+ private_dns = (known after apply)
+ private_ip = (known after apply)
+ public_dns = (known after apply)
+ public_ip = (known after apply)
+ public_ipv4_pool = (known after apply)
+ tags_all = (known after apply)
+ vpc = true
}
# module.ec2.aws_instance.webserver will be created
+ resource "aws_instance" "webserver" {
+ ami = "ami-0eddbd81024d3fbdd"
+ arn = (known after apply)
+ associate_public_ip_address = (known after apply)
+ availability_zone = (known after apply)
+ cpu_core_count = (known after apply)
+ cpu_threads_per_core = (known after apply)
+ disable_api_stop = (known after apply)
+ disable_api_termination = (known after apply)
+ ebs_optimized = (known after apply)
+ get_password_data = false
+ host_id = (known after apply)
+ host_resource_group_arn = (known after apply)
+ iam_instance_profile = (known after apply)
+ id = (known after apply)
+ instance_initiated_shutdown_behavior = (known after apply)
+ instance_state = (known after apply)
+ instance_type = "t2.micro"
+ ipv6_address_count = (known after apply)
+ ipv6_addresses = (known after apply)
+ key_name = "webserver"
+ monitoring = (known after apply)
+ outpost_arn = (known after apply)
+ password_data = (known after apply)
+ placement_group = (known after apply)
+ placement_partition_number = (known after apply)
+ primary_network_interface_id = (known after apply)
+ private_dns = (known after apply)
+ private_ip = (known after apply)
+ public_dns = (known after apply)
+ public_ip = (known after apply)
+ secondary_private_ips = (known after apply)
+ security_groups = (known after apply)
+ source_dest_check = true
+ subnet_id = (known after apply)
+ tags = {
+ "Name" = "webserver"
}
+ tags_all = {
+ "Name" = "webserver"
}
+ tenancy = (known after apply)
+ user_data = "27df6bf3f9185d6b06dd3276d82b060b35533ead"
+ user_data_base64 = (known after apply)
+ user_data_replace_on_change = false
+ vpc_security_group_ids = (known after apply)
+ capacity_reservation_specification {
+ capacity_reservation_preference = (known after apply)
+ capacity_reservation_target {
+ capacity_reservation_id = (known after apply)
+ capacity_reservation_resource_group_arn = (known after apply)
}
}
+ ebs_block_device {
+ delete_on_termination = (known after apply)
+ device_name = (known after apply)
+ encrypted = (known after apply)
+ iops = (known after apply)
+ kms_key_id = (known after apply)
+ snapshot_id = (known after apply)
+ tags = (known after apply)
+ throughput = (known after apply)
+ volume_id = (known after apply)
+ volume_size = (known after apply)
+ volume_type = (known after apply)
}
+ enclave_options {
+ enabled = (known after apply)
}
+ ephemeral_block_device {
+ device_name = (known after apply)
+ no_device = (known after apply)
+ virtual_name = (known after apply)
}
+ maintenance_options {
+ auto_recovery = (known after apply)
}
+ metadata_options {
+ http_endpoint = (known after apply)
+ http_put_response_hop_limit = (known after apply)
+ http_tokens = (known after apply)
+ instance_metadata_tags = (known after apply)
}
+ network_interface {
+ delete_on_termination = (known after apply)
+ device_index = (known after apply)
+ network_card_index = (known after apply)
+ network_interface_id = (known after apply)
}
+ private_dns_name_options {
+ enable_resource_name_dns_a_record = (known after apply)
+ enable_resource_name_dns_aaaa_record = (known after apply)
+ hostname_type = (known after apply)
}
+ root_block_device {
+ delete_on_termination = (known after apply)
+ device_name = (known after apply)
+ encrypted = (known after apply)
+ iops = (known after apply)
+ kms_key_id = (known after apply)
+ tags = (known after apply)
+ throughput = (known after apply)
+ volume_id = (known after apply)
+ volume_size = (known after apply)
+ volume_type = (known after apply)
}
}
# module.ec2.aws_key_pair.kp will be created
+ resource "aws_key_pair" "kp" {
+ arn = (known after apply)
+ fingerprint = (known after apply)
+ id = (known after apply)
+ key_name = "webserver"
+ key_name_prefix = (known after apply)
+ key_pair_id = (known after apply)
+ key_type = (known after apply)
+ public_key = (known after apply)
+ tags_all = (known after apply)
}
# module.ec2.aws_security_group.webserversg will be created
+ resource "aws_security_group" "webserversg" {
+ arn = (known after apply)
+ description = "allow 22, 80"
+ egress = (known after apply)
+ id = (known after apply)
+ ingress = (known after apply)
+ name = "webserversg"
+ name_prefix = (known after apply)
+ owner_id = (known after apply)
+ revoke_rules_on_delete = false
+ tags_all = (known after apply)
+ vpc_id = (known after apply)
}
# module.ec2.aws_security_group_rule.websg_http will be created
+ resource "aws_security_group_rule" "websg_http" {
+ cidr_blocks = [
+ "0.0.0.0/0",
]
+ description = "http"
+ from_port = 80
+ id = (known after apply)
+ protocol = "tcp"
+ security_group_id = (known after apply)
+ security_group_rule_id = (known after apply)
+ self = false
+ source_security_group_id = (known after apply)
+ to_port = 80
+ type = "ingress"
}
# module.ec2.aws_security_group_rule.websg_outbound will be created
+ resource "aws_security_group_rule" "websg_outbound" {
+ cidr_blocks = [
+ "0.0.0.0/0",
]
+ description = "outbound"
+ from_port = 0
+ id = (known after apply)
+ protocol = "-1"
+ security_group_id = (known after apply)
+ security_group_rule_id = (known after apply)
+ self = false
+ source_security_group_id = (known after apply)
+ to_port = 0
+ type = "egress"
}
# module.ec2.aws_security_group_rule.websg_ssh will be created
+ resource "aws_security_group_rule" "websg_ssh" {
+ cidr_blocks = [
+ "0.0.0.0/0",
]
+ description = "ssh"
+ from_port = 22
+ id = (known after apply)
+ protocol = "tcp"
+ security_group_id = (known after apply)
+ security_group_rule_id = (known after apply)
+ self = false
+ source_security_group_id = (known after apply)
+ to_port = 22
+ type = "ingress"
}
# module.ec2.local_file.ssh_key will be created
+ resource "local_file" "ssh_key" {
+ content = (sensitive value)
+ directory_permission = "0777"
+ file_permission = "0777"
+ filename = "webserver.pem"
+ id = (known after apply)
}
# module.ec2.tls_private_key.pk will be created
+ resource "tls_private_key" "pk" {
+ algorithm = "RSA"
+ ecdsa_curve = "P224"
+ id = (known after apply)
+ private_key_openssh = (sensitive value)
+ private_key_pem = (sensitive value)
+ private_key_pem_pkcs8 = (sensitive value)
+ public_key_fingerprint_md5 = (known after apply)
+ public_key_fingerprint_sha256 = (known after apply)
+ public_key_openssh = (known after apply)
+ public_key_pem = (known after apply)
+ rsa_bits = 4096
}
# module.vpc.aws_eip.nat will be created
+ resource "aws_eip" "nat" {
+ allocation_id = (known after apply)
+ association_id = (known after apply)
+ carrier_ip = (known after apply)
+ customer_owned_ip = (known after apply)
+ domain = (known after apply)
+ id = (known after apply)
+ instance = (known after apply)
+ network_border_group = (known after apply)
+ network_interface = (known after apply)
+ private_dns = (known after apply)
+ private_ip = (known after apply)
+ public_dns = (known after apply)
+ public_ip = (known after apply)
+ public_ipv4_pool = (known after apply)
+ tags = {
+ "Name" = "terraform_vpc_test_eip"
}
+ tags_all = {
+ "Name" = "terraform_vpc_test_eip"
}
+ vpc = true
}
# module.vpc.aws_internet_gateway.main will be created
+ resource "aws_internet_gateway" "main" {
+ arn = (known after apply)
+ id = (known after apply)
+ owner_id = (known after apply)
+ tags = {
+ "Name" = "terraform_vpc_test_igw"
}
+ tags_all = {
+ "Name" = "terraform_vpc_test_igw"
}
+ vpc_id = (known after apply)
}
# module.vpc.aws_nat_gateway.main will be created
+ resource "aws_nat_gateway" "main" {
+ allocation_id = (known after apply)
+ connectivity_type = "public"
+ id = (known after apply)
+ network_interface_id = (known after apply)
+ private_ip = (known after apply)
+ public_ip = (known after apply)
+ subnet_id = (known after apply)
+ tags = {
+ "Name" = "terraform_vpc_test_nat"
}
+ tags_all = {
+ "Name" = "terraform_vpc_test_nat"
}
}
# module.vpc.aws_route_table.private will be created
+ resource "aws_route_table" "private" {
+ arn = (known after apply)
+ id = (known after apply)
+ owner_id = (known after apply)
+ propagating_vgws = (known after apply)
+ route = [
+ {
+ carrier_gateway_id = ""
+ cidr_block = "0.0.0.0/0"
+ core_network_arn = ""
+ destination_prefix_list_id = ""
+ egress_only_gateway_id = ""
+ gateway_id = ""
+ instance_id = ""
+ ipv6_cidr_block = ""
+ local_gateway_id = ""
+ nat_gateway_id = (known after apply)
+ network_interface_id = ""
+ transit_gateway_id = ""
+ vpc_endpoint_id = ""
+ vpc_peering_connection_id = ""
},
]
+ tags = {
+ "Name" = "terraform_vpc_test_private-route-table"
}
+ tags_all = {
+ "Name" = "terraform_vpc_test_private-route-table"
}
+ vpc_id = (known after apply)
}
# module.vpc.aws_route_table.public will be created
+ resource "aws_route_table" "public" {
+ arn = (known after apply)
+ id = (known after apply)
+ owner_id = (known after apply)
+ propagating_vgws = (known after apply)
+ route = [
+ {
+ carrier_gateway_id = ""
+ cidr_block = "0.0.0.0/0"
+ core_network_arn = ""
+ destination_prefix_list_id = ""
+ egress_only_gateway_id = ""
+ gateway_id = (known after apply)
+ instance_id = ""
+ ipv6_cidr_block = ""
+ local_gateway_id = ""
+ nat_gateway_id = ""
+ network_interface_id = ""
+ transit_gateway_id = ""
+ vpc_endpoint_id = ""
+ vpc_peering_connection_id = ""
},
]
+ tags = {
+ "Name" = "terraform_vpc_test_public-route-table"
}
+ tags_all = {
+ "Name" = "terraform_vpc_test_public-route-table"
}
+ vpc_id = (known after apply)
}
# module.vpc.aws_route_table_association.private will be created
+ resource "aws_route_table_association" "private" {
+ id = (known after apply)
+ route_table_id = (known after apply)
+ subnet_id = (known after apply)
}
# module.vpc.aws_route_table_association.private-a will be created
+ resource "aws_route_table_association" "private-a" {
+ id = (known after apply)
+ route_table_id = (known after apply)
+ subnet_id = (known after apply)
}
# module.vpc.aws_route_table_association.public will be created
+ resource "aws_route_table_association" "public" {
+ id = (known after apply)
+ route_table_id = (known after apply)
+ subnet_id = (known after apply)
}
# module.vpc.aws_route_table_association.public-a will be created
+ resource "aws_route_table_association" "public-a" {
+ id = (known after apply)
+ route_table_id = (known after apply)
+ subnet_id = (known after apply)
}
# module.vpc.aws_subnet.private will be created
+ resource "aws_subnet" "private" {
+ arn = (known after apply)
+ assign_ipv6_address_on_creation = false
+ availability_zone = "ap-northeast-2a"
+ availability_zone_id = (known after apply)
+ cidr_block = "10.0.3.0/24"
+ enable_dns64 = false
+ enable_resource_name_dns_a_record_on_launch = false
+ enable_resource_name_dns_aaaa_record_on_launch = false
+ id = (known after apply)
+ ipv6_cidr_block_association_id = (known after apply)
+ ipv6_native = false
+ map_public_ip_on_launch = false
+ owner_id = (known after apply)
+ private_dns_hostname_type_on_launch = (known after apply)
+ tags = {
+ "Name" = "terraform_vpc_test_private_subnet-a"
}
+ tags_all = {
+ "Name" = "terraform_vpc_test_private_subnet-a"
}
+ vpc_id = (known after apply)
}
# module.vpc.aws_subnet.private-a will be created
+ resource "aws_subnet" "private-a" {
+ arn = (known after apply)
+ assign_ipv6_address_on_creation = false
+ availability_zone = "ap-northeast-2c"
+ availability_zone_id = (known after apply)
+ cidr_block = "10.0.4.0/24"
+ enable_dns64 = false
+ enable_resource_name_dns_a_record_on_launch = false
+ enable_resource_name_dns_aaaa_record_on_launch = false
+ id = (known after apply)
+ ipv6_cidr_block_association_id = (known after apply)
+ ipv6_native = false
+ map_public_ip_on_launch = false
+ owner_id = (known after apply)
+ private_dns_hostname_type_on_launch = (known after apply)
+ tags = {
+ "Name" = "terraform_vpc_test_private_subnet-b"
}
+ tags_all = {
+ "Name" = "terraform_vpc_test_private_subnet-b"
}
+ vpc_id = (known after apply)
}
# module.vpc.aws_subnet.public will be created
+ resource "aws_subnet" "public" {
+ arn = (known after apply)
+ assign_ipv6_address_on_creation = false
+ availability_zone = "ap-northeast-2a"
+ availability_zone_id = (known after apply)
+ cidr_block = "10.0.1.0/24"
+ enable_dns64 = false
+ enable_resource_name_dns_a_record_on_launch = false
+ enable_resource_name_dns_aaaa_record_on_launch = false
+ id = (known after apply)
+ ipv6_cidr_block_association_id = (known after apply)
+ ipv6_native = false
+ map_public_ip_on_launch = false
+ owner_id = (known after apply)
+ private_dns_hostname_type_on_launch = (known after apply)
+ tags = {
+ "Name" = "terraform_vpc_test_public_subnet-a"
}
+ tags_all = {
+ "Name" = "terraform_vpc_test_public_subnet-a"
}
+ vpc_id = (known after apply)
}
# module.vpc.aws_subnet.public-a will be created
+ resource "aws_subnet" "public-a" {
+ arn = (known after apply)
+ assign_ipv6_address_on_creation = false
+ availability_zone = "ap-northeast-2c"
+ availability_zone_id = (known after apply)
+ cidr_block = "10.0.2.0/24"
+ enable_dns64 = false
+ enable_resource_name_dns_a_record_on_launch = false
+ enable_resource_name_dns_aaaa_record_on_launch = false
+ id = (known after apply)
+ ipv6_cidr_block_association_id = (known after apply)
+ ipv6_native = false
+ map_public_ip_on_launch = false
+ owner_id = (known after apply)
+ private_dns_hostname_type_on_launch = (known after apply)
+ tags = {
+ "Name" = "terraform_vpc_test_public_subnet-b"
}
+ tags_all = {
+ "Name" = "terraform_vpc_test_public_subnet-b"
}
+ vpc_id = (known after apply)
}
# module.vpc.aws_vpc.main will be created
+ resource "aws_vpc" "main" {
+ arn = (known after apply)
+ cidr_block = "10.0.0.0/16"
+ default_network_acl_id = (known after apply)
+ default_route_table_id = (known after apply)
+ default_security_group_id = (known after apply)
+ dhcp_options_id = (known after apply)
+ enable_classiclink = (known after apply)
+ enable_classiclink_dns_support = (known after apply)
+ enable_dns_hostnames = (known after apply)
+ enable_dns_support = true
+ enable_network_address_usage_metrics = (known after apply)
+ id = (known after apply)
+ instance_tenancy = "default"
+ ipv6_association_id = (known after apply)
+ ipv6_cidr_block = (known after apply)
+ ipv6_cidr_block_network_border_group = (known after apply)
+ main_route_table_id = (known after apply)
+ owner_id = (known after apply)
+ tags = {
+ "Name" = "terraform_vpc_test"
}
+ tags_all = {
+ "Name" = "terraform_vpc_test"
}
}
Plan: 23 to add, 0 to change, 0 to destroy.
Changes to Outputs:
+ private_subnet_id = (known after apply)
+ private_subnet_id-a = (known after apply)
+ public_subnet_id = (known after apply)
+ public_subnet_id-a = (known after apply)
────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
Note: You didn't use the -out option to save this plan, so Terraform can't guarantee to take exactly these actions if you run "terraform
apply" now.
- terraform apply를 활용한 aws 리소스 생성
리소스 생성에는 약 5분 이내 소요된다. 아래는 생성 중인 모습.
- 결과 확인
outputs는 outputs.tf에 정의한 내용을 표출해 준다.
Apply complete! Resources: 23 added, 0 changed, 0 destroyed.
Outputs:
private_subnet_id = "subnet-0"
private_subnet_id-a = "subnet-0"
public_subnet_id = "subnet-0"
public_subnet_id-a = "subnet-0"
5. 생성된 리소스를 AWS Console에서 직접 확인해 보자.
- 일단 아파치 웹서버를 생성하였으므로 웹서버에 정상적으로 접근이 되는지 확인하자.
- EIP를 생성하였으므로, EIP:80으로 접근하면 아래와 같이 내용을 확인할 수 있다.
- 위의 목표 아키텍처의 1~5번까지의 리소스를 확인해 보자.
① EIP : 정상 생성 완료
② ec2 인스턴스 : 정상 생성 완료
②-① 아파치 웹서버 : 정상 생성 완료
③, ⑤ PublicKey와 KeyPair : 정상 생성 완료
④ 보안그룹 : 정상 생성 완료
- 보안그룹의 인바운드와 아웃바운드 확인
: 인바운드
: 아웃바운드
- 이로써 목표 아키텍처의 리소스들은 정상적으로 생성이 된 것을 확인할 수 있다.
- 끝 -
'♻ Terraform(테라폼) > Module-EC2' 카테고리의 다른 글
테라폼 모듈을 2개 사용하는 방법 (0) | 2023.02.28 |
---|