2. Parameters(입력) : 명령줄 도구에 입력하는 매개변수와 동일하게 스택을 만들거나 업데이트할 때 정의하는 입력값입니다. 파라미터는 템플릿의 변경 없이도 스택을 커스터마이즈할 수 있게 해줍니다. AMI ID, VPC ID, Subnet ID등과 같은 매개변수를 사용할 수 있습니다.
3. Output(출력) : 스택이 완료된 후에 결과물을 출력하려고 할때 유용합니다. 예를 들어 ELB의 퍼블릭 URL이나 EC2의 퍼블릭 IP를 출력할 수 있습니다.
4. Mapping(지정) : 리전의 특화된 템플릿에서 어떠한 요소를 참조할 때 필요합니다. 예를 들어 템플릿에 EC2 AMI ID에 대한 매핑을 지정하는 것입니다. AMI ID가 리전에 특화된 리소스이기 때문에 유효한 AMI ID를 리전별로 지정하려고 할때 사용합니다.
새 메모장에
AWSTemplateFormatVersion: 2010-09-09
Resources:
VPC:
Type: AWS::EC2::VPC
Properties:
CidrBlock: 192.168.0.0/16
EnableDnsSupport: true //true하지 않으면 ping 안나감
EnableDnsHostnames: true
InstanceTenancy: default
Tags:
- Key: Name
Value: NEW-VPC
InternetGateway:
Type: AWS::EC2::InternetGateway
Properties:
Tags:
- Key: Name
Value: NEW-IGW
VPCGatewayAttachment:
Type: AWS::EC2::VPCGatewayAttachment
Properties:
VpcId: !Ref VPC
InternetGatewayId: !Ref InternetGateway
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
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
new-vpc.yaml로 저장
VPC 확인
DNS 호스트 이름 편집 / DNS 확인 편집 중요
인터넷 게이트웨이는 attached만 확인하면 됨
라우팅 테이블 명시적 연결
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:
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
SecurityGroupEgress:
- IpProtocol: -1
CidrIp: 0.0.0.0/0
Linux:
Type: 'AWS::EC2::Instance'
Properties:
SubnetId: !Ref Subnet
# 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": ["Linux","PublicIp"]}
키페어 생성
이름 : tokyo
프라이빗 키 파일 형식 : .pem
CloudFormation > 스택 생성
템플릿 준비 : 준비된 템플릿
템플릿 소스 : 템플릿 파일 업로드 - new-ec2.yaml
스택 이름 : tokyo
subnet : 본인 subnet ID (subnet 2a)
VPC : default VPC ID
구성관리 도구 : Ansible
서버템블릿 도구 : Docker
오케스트레이션 도구 : Kubernetes
프로비전 도구 : Terraform
[root@localhost ~]# wget https://releases.hashicorp.com/terraform/1.2.3/terraform_1.2.3_linux_amd64.zip
--2022-06-30 15:43:50-- https://releases.hashicorp.com/terraform/1.2.3/terraform_1.2.3_linux_amd64.zip
Resolving releases.hashicorp.com (releases.hashicorp.com)... 146.75.50.49
Connecting to releases.hashicorp.com (releases.hashicorp.com)|146.75.50.49|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 19891436 (19M) [application/zip]
Saving to: ‘terraform_1.2.3_linux_amd64.zip’
100%[===========================================>] 19,891,436 54.8MB/s in 0.3s
2022-06-30 15:43:50 (54.8 MB/s) - ‘terraform_1.2.3_linux_amd64.zip’ saved [19891436/19891436]
[root@localhost ~]# unzip terraform_1.2.3_linux_amd64.zip
Archive: terraform_1.2.3_linux_amd64.zip
inflating: terraform
[root@localhost ~]# mv terraform /usr/local/bin/
AWS Terraform ec2 인스턴스 생성
[root@localhost ~]# mkdir aws && cd $_
[root@localhost aws]# vi main.tf
provider "aws" {
region = "ap-northeast-2"
}
resource "aws_instance" "example" {
ami = "ami-0fd0765afb77bcca7"
instance_type = "t2.micro"
}
[root@localhost aws]# terraform init
Initializing the backend...
Initializing provider plugins...
- Finding latest version of hashicorp/aws...
- Installing hashicorp/aws v4.20.1...
- Installed hashicorp/aws v4.20.1 (signed by HashiCorp)
Terraform has created a lock file .terraform.lock.hcl to record the provider
selections it made above. Include this file in your version control repository
so that Terraform can guarantee to make the same selections by default when
you run "terraform init" in the future.
Terraform has been successfully initialized!
You may now begin working with Terraform. Try running "terraform plan" to see
any changes that are required for your infrastructure. All Terraform commands
should now work.
If you ever set or change modules or backend configuration for Terraform,
rerun this command to reinitialize your working directory. If you forget, other
commands will detect it and remind you to do so if necessary.
[root@localhost aws]# 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:
# aws_instance.example will be created
+ resource "aws_instance" "example" {
+ ami = "ami-0fd0765afb77bcca7"
+ 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)
+ 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 = (known after apply)
+ 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_all = (known after apply)
+ tenancy = (known after apply)
+ user_data = (known after apply)
+ 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)
}
}
Plan: 1 to add, 0 to change, 0 to destroy.
────────────────────────────────────────────────────────────────────────────────────
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.
[root@localhost aws]# terraform destroy
aws_instance.example: Refreshing state... [id=i-0d93c31f523cf6619]
Terraform used the selected providers to generate the following execution plan.
Resource actions are indicated with the following symbols:
- destroy
Terraform will perform the following actions:
# aws_instance.example will be destroyed
- resource "aws_instance" "example" {
- ami = "ami-0fd0765afb77bcca7" -> null
- arn = "arn:aws:ec2:ap-northeast-2:050722723154:instance/i-0d93c31f523cf6619" -> null
- associate_public_ip_address = true -> null
- availability_zone = "ap-northeast-2a" -> null
- cpu_core_count = 1 -> null
- cpu_threads_per_core = 1 -> null
- disable_api_stop = false -> null
- disable_api_termination = false -> null
- ebs_optimized = false -> null
- get_password_data = false -> null
- hibernation = false -> null
- id = "i-0d93c31f523cf6619" -> null
- instance_initiated_shutdown_behavior = "stop" -> null
- instance_state = "running" -> null
- instance_type = "t2.micro" -> null
- ipv6_address_count = 0 -> null
- ipv6_addresses = [] -> null
- monitoring = false -> null
- primary_network_interface_id = "eni-054ed38e749cffae5" -> null
- private_dns = "ip-172-31-8-139.ap-northeast-2.compute.internal" -> null
- private_ip = "172.31.8.139" -> null
- public_dns = "ec2-3-38-151-163.ap-northeast-2.compute.amazonaws.com" -> null
- public_ip = "3.38.151.163" -> null
- secondary_private_ips = [] -> null
- security_groups = [
- "default",
] -> null
- source_dest_check = true -> null
- subnet_id = "subnet-0014153bbc7e20894" -> null
- tags = {
- "Name" = "terraform-example"
} -> null
- tags_all = {
- "Name" = "terraform-example"
} -> null
- tenancy = "default" -> null
- user_data_replace_on_change = false -> null
- vpc_security_group_ids = [
- "sg-0f378736735ead05a",
] -> null
- capacity_reservation_specification {
- capacity_reservation_preference = "open" -> null
}
- credit_specification {
- cpu_credits = "standard" -> null
}
- enclave_options {
- enabled = false -> null
}
- maintenance_options {
- auto_recovery = "default" -> null
}
- metadata_options {
- http_endpoint = "enabled" -> null
- http_put_response_hop_limit = 1 -> null
- http_tokens = "optional" -> null
- instance_metadata_tags = "disabled" -> null
}
- private_dns_name_options {
- enable_resource_name_dns_a_record = false -> null
- enable_resource_name_dns_aaaa_record = false -> null
- hostname_type = "ip-name" -> null
}
- root_block_device {
- delete_on_termination = true -> null
- device_name = "/dev/xvda" -> null
- encrypted = false -> null
- iops = 100 -> null
- tags = {} -> null
- throughput = 0 -> null
- volume_id = "vol-095c22371f494763f" -> null
- volume_size = 8 -> null
- volume_type = "gp2" -> null
}
}
Plan: 0 to add, 0 to change, 1 to destroy.
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 = 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" {
description = "The name of the security group"
type = string
default = "terraform-example-instance"
}
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"
}
Outputs:
private_ip = "172.31.0.34"
public_dns = "ec2-13-209-14-133.ap-northeast-2.compute.amazonaws.com"
public_ip = "13.209.14.133"