오늘은 Terraform을 이용해 코드로 EC2 Instance를 생성해봅시다. VPC가 생성된 상태에서 진행하며, Instance에 쓰일 Security group, IAM Role, key pair도 같이 만들겠습니다.
1. Security group
resource "aws_security_group" "bastion" {
name = "bastion_sg"
description = "Allow SSH traffic"
vpc_id = aws_vpc.main.id
ingress {
from_port = 22
to_port = 22
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
ipv6_cidr_blocks = ["::/0"]
}
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
ipv6_cidr_blocks = ["::/0"]
}
}
Inbound Rule로 SSH 접속에 쓰이는 포트인 22번을 Anywhere(0.0.0.0/0, ::/0)로 열어줬습니다. Outbound Rule로 포트를 0번, protocol을 -1로 지정하여 모든 트래픽이 나갈 수 있도록 했습니다.
2. IAM Role
EC2 Instance를 Admin의 역할로 사용하기 위해 AdministratorAccess Policy를 부착한 IAM Role을 사용하겠습니다. EC2 서비스가 사용할 수 있는 IAM Role부터 생성하겠습니다. jsonencode 함수를 사용하여 assume_role_policy를 작성할 수 있습니다.
resource "aws_iam_role" "admin" {
name = "AdminRole"
assume_role_policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Action = "sts:AssumeRole"
Effect = "Allow"
Sid = ""
Principal = {
Service = "ec2.amazonaws.com"
}
},
]
})
}
Policy를 만들지 않고, 이미 만들어진 Admin Policy를 IAM Role에 부착시켜줍니다.
resource "aws_iam_role_policy_attachment" "admin" {
role = aws_iam_role.admin.name
policy_arn = "arn:aws:iam::aws:policy/AdministratorAccess"
}
Instance가 IAM Role을 사용할 수 있게 Instance Profile까지 만들어줍니다.
resource "aws_iam_instance_profile" "admin" {
name = "AdminRole"
role = aws_iam_role.admin.name
}
3. EIP, Key Pair
EIP와 Key Pair 생성은 쉽습니다.
EIP는 추후에 생성할 instance에 장착하게 하며, VPC에서 사용된다고 명시해줍니다.
resource "aws_eip" "bastion" {
instance = aws_instance.bastion.id
domain = "vpc"
}
Key Pair 파일은 Windows, Mac 모두 홈 디렉토리의 .ssh/id_rsa.pub (public key)로 선택해주면 됩니다. 추후에 ssh로 접속할 때는 홈 디렉토리의 .ssh/id_rsa 키 (private key)를 이용해 접속하면 됩니다.
resource "aws_key_pair" "keypair" {
key_name = "bastion-key"
public_key = file("~/.ssh/id_rsa.pub")
}
4. Instance
인스턴스를 생성하기 전에 amazon linux의 최신 버전이 수시로 바뀌기 때문에 data를 이용하여 Amazon Linux 최신버전을 받아옵니다. (여기에서는 Amazon Linux 2를 사용했습니다.)
data "aws_ami" "amazon-linux-2" {
most_recent = true
filter {
name = "owner-alias"
values = ["amazon"]
}
filter {
name = "name"
values = ["amzn2-ami-hvm*"]
}
}
제일 중요한 인스턴스 생성 단계이기 때문에 옵션 하나하나 살펴봅시다.
- ami를 방금 받아온 Amazon Linux의 id로 지정합니다.
- associate_public_ip_address를 true로 설정하여 public ip를 받아올 수 있게 합니다. (사실 eip를 장착하여 의미는 없습니다.)
- instance type은 t3.small로 설정합니다.
- subnet_id는 public subnet의 id로 설정합니다.
- Admin Instance인만큼 중요한 인스턴스이기 때문에 disable_api_termination로 설정하여 AWS 콘솔에서 바로 인스턴스 종료를 못 시키도록 합니다.
- key_name은 아까 생성해준 key pair의 이름으로 설정해줍니다.
- 보안그룹은 여러 개가 설정될 수 있기 때문에 배열로 각각의 id를 받습니다.
- 아까 생성해준 iam instance profile의 이름을 지정하여 인스턴스가 IAM Role을 사용할 수 있게 합니다.
- User data script는 EOF 형식으로 받을 수 있습니다. '<<EOF' 다음줄부터 'EOF' 전 줄까지 스크립트를 작성하거나 파일 형식으로 받을 수 있습니다.
resource "aws_instance" "bastion" {
ami = data.aws_ami.amazon-linux-2.id
associate_public_ip_address = true
instance_type = "t3.small"
subnet_id = aws_subnet.public-a.id
disable_api_termination = true
key_name = aws_key_pair.keypair.key_name
vpc_security_group_ids = [aws_security_group.bastion.id]
iam_instance_profile = aws_iam_instance_profile.admin.name
user_data = <<EOF
#!/bin/bash
yum update -y
yum install -y jq
EOF
// user_data = file("./bastion/userdata.sh")
tags = {
Name = "bastion-ec2"
}
}
5. 인스턴스 생성
Apply를 통해 EC2 Instance를 생성합니다.
terraform apply
생성될 리소스들이 나오고, yes를 입력하면 실제로 생성이 시작됩니다.
Plan: 7 to add, 0 to change, 0 to destroy.
Do you want to perform these actions?
Terraform will perform the actions described above.
Only 'yes' will be accepted to approve.
Enter a value: yes
생성이 완료되었습니다. 실제로 생성된 것도 확인할 수 있습니다.
aws_eip.bastion: Creating...
aws_eip.bastion: Creation complete after 1s [id=eipalloc-0fbe2fa1f6a716c67]
Apply complete! Resources: 7 added, 0 changed, 0 destroyed.
ssh 접속도 잘 되는 것을 볼 수 있습니다.
C:\Users\kimjeongtae>ssh ec2-user@3.39.32.145 -i .ssh/id_rsa
, #_
~\_ ####_ Amazon Linux 2
~~ \_#####\
~~ \###| AL2 End of Life is 2025-06-30.
~~ \#/ ___
~~ V~' '->
~~~ / A newer version of Amazon Linux is available!
~~._. _/
_/ _/ Amazon Linux 2023, GA and supported until 2028-03-15.
_/m/' https://aws.amazon.com/linux/amazon-linux-2023/
[ec2-user@ip-172-31-35-104 ~]$
이제 Destroy를 이용해 실습을 마무리합시다.
terraform destroy
오늘의 글은 여기까지입니다. 감사합니다!
'AWS' 카테고리의 다른 글
[AWS] AWS Load Balancer Controller로 HTTPS가 적용된 ALB 생성하기 (0) | 2024.02.21 |
---|---|
[AWS] Managed Service for Apache Flink로 스트리밍 데이터 분석 - Studio notebooks (2) (2) | 2024.02.16 |
[AWS] AWS Config로 Security group 감시하기 (0) | 2024.01.02 |
[AWS] Github Actions로 ECS 서비스에 배포 (Blue / Green) (2) | 2023.12.31 |
[AWS] Github Actions로 ECS 서비스에 배포 (Rolling Update) (0) | 2023.12.29 |