-
aws ec2 인스턴스 생성에 대한 고찰AWS 2023. 7. 26. 17:03
https://www.yes24.com/Product/Goods/119179333
위에책을 보다보니, https://github.com/terraform101/terraform-aws-collaboration
예제가 있어서 잘 작동되게 조금 바꿔봤다.
위에 main.tf에서 문제가 몇개 있었다.
1. aws provider에서 access_key와 secret_key를 넣어줬다.
IAM에서 사용자 하나 만들고, AmazonEC2FullAccess 정책을 연결해준다.
2. 프리티어를 사용하기위해, AMI를 ubuntu 20.04나 22.04로 하고, t2.micro로 바꿔야한다.
하지만 예제는 AMI가 ubuntu 18버전이어서, 이부분을 바꿔줬다.
3. subnet에서 availability_zone옵션을 주지 않으면 ap-northeast-2a ~ ap-northeast-2d 중에 무작위로 하나 골라지는데, 여기서 2b와 2d가 걸리게 되면, t2.micro 로 인스턴스를 생성하지 못한다.
resource "aws_subnet" "hashicat" { vpc_id = aws_vpc.hashicat.id cidr_block = var.subnet_prefix availability_zone = "ap-northeast-2c" tags = { name = "${var.prefix}-subnet" } }
위에처럼 availbility_zone를 추가했다.
4. eip 에서 vpc = true가 deprecated되어서 문서를 보고 바꿨다.
resource "aws_eip" "hashicat" { instance = aws_instance.hashicat.id domain = "vpc" }
5. 키페어를 만들고, ssh로 ec2에 접속하기 위해 private pem 을 얻어서 파일로 저장해야하는데, 이부분을 추가했다.
resource "local_file" "terraform-pem" { content = tls_private_key.hashicat.private_key_pem filename = "${path.module}/terraform.pem" depends_on = [ tls_private_key.hashicat ] }
6. main.tf에 provisioner "file" 이 있는데, local 컴퓨터에서 files/ 경로에 있는 파일을 ec2의 /home/ubuntu로 옮겨주는 거여서, local에서 file디렉터리를 만들고, 파일 하나 만들었다.
우분투 이미지를 찾는 방법이다.
1. aws cli를 설치한다.
https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html
2. aws ec2 탭에 가서 인스턴스 시작을 눌러서 원하는 이미지의 ami 를 찾는다.
3. cmd 를 열어서 아래의 명령어를 입력한다.
aws ec2 describe-images --region ap-northeast-2 --image-ids ami-04341a215040f91bb
이렇게 2개를 써주면 된다.
바꾼 main.tf 이다.
access_key와 secret_key는 알아서 적어주자.
terraform { required_providers { aws = { source = "hashicorp/aws" version = "~> 5.0" } } required_version = ">= 1.0" #terraform 버전 } provider "aws" { region = "ap-northeast-2" access_key = "INPUT YOUR ACCESS KEY" secret_key = "INPUT YOUR SECRET KEY" } resource "aws_security_group" "hashicat" { name = "${var.prefix}-security-group" vpc_id = aws_vpc.hashicat.id ingress { from_port = 22 to_port = 22 protocol = "tcp" cidr_blocks = ["0.0.0.0/0"] } 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"] prefix_list_ids = [] } tags = { Name = "${var.prefix}-security-group" } } resource "aws_vpc" "hashicat" { cidr_block = var.address_space enable_dns_hostnames = true tags = { name = "${var.prefix}-vpc-${var.region}" environment = "Production" } } resource "aws_subnet" "hashicat" { vpc_id = aws_vpc.hashicat.id cidr_block = var.subnet_prefix availability_zone = "ap-northeast-2c" tags = { name = "${var.prefix}-subnet" } } resource "aws_internet_gateway" "hashicat" { vpc_id = aws_vpc.hashicat.id tags = { Name = "${var.prefix}-internet-gateway" } } resource "aws_route_table" "hashicat" { vpc_id = aws_vpc.hashicat.id route { cidr_block = "0.0.0.0/0" gateway_id = aws_internet_gateway.hashicat.id } } resource "aws_route_table_association" "hashicat" { subnet_id = aws_subnet.hashicat.id route_table_id = aws_route_table.hashicat.id } data "aws_ami" "ubuntu" { most_recent = true filter { name = "name" values = ["ubuntu/images/hvm-ssd/ubuntu-focal-20.04-amd64-server-20230517"] } filter { name = "virtualization-type" values = ["hvm"] } owners = ["099720109477"] # Canonical } resource "tls_private_key" "hashicat" { algorithm = "RSA" } locals { private_key_filename = "${var.prefix}-ssh-key.pem" } resource "local_file" "terraform-pem" { content = tls_private_key.hashicat.private_key_pem filename = "${path.module}/terraform.pem" depends_on = [ tls_private_key.hashicat ] } resource "aws_key_pair" "hashicat" { key_name = local.private_key_filename public_key = tls_private_key.hashicat.public_key_openssh } resource "aws_eip" "hashicat" { instance = aws_instance.hashicat.id domain = "vpc" } resource "aws_eip_association" "hashicat" { instance_id = aws_instance.hashicat.id allocation_id = aws_eip.hashicat.id } resource "aws_instance" "hashicat" { ami = data.aws_ami.ubuntu.id instance_type = var.instance_type key_name = aws_key_pair.hashicat.key_name associate_public_ip_address = true subnet_id = aws_subnet.hashicat.id vpc_security_group_ids = [aws_security_group.hashicat.id] tags = { Name = "${var.prefix}-hashicat-instance" } } resource "null_resource" "configure-cat-app" { depends_on = [aws_eip_association.hashicat] // triggers = { // build_number = timestamp() // } provisioner "file" { source = "files/" destination = "/home/ubuntu/" connection { type = "ssh" user = "ubuntu" private_key = tls_private_key.hashicat.private_key_pem host = aws_eip.hashicat.public_ip } } provisioner "remote-exec" { inline = [ "sudo apt -y update", "sleep 15", "sudo apt -y update", "sudo apt -y install apache2", "sudo systemctl start apache2", "sudo chown -R ubuntu:ubuntu /var/www/html", "chmod +x *.sh", "PLACEHOLDER=${var.placeholder} WIDTH=${var.width} HEIGHT=${var.height} PREFIX=${var.prefix} ./deploy_app.sh", "sudo apt -y install cowsay", "cowsay Mooooooooooo!", ] connection { type = "ssh" user = "ubuntu" private_key = tls_private_key.hashicat.private_key_pem host = aws_eip.hashicat.public_ip } } }
우리가 ec2를 생성할때, vpc 에 관해서는 기본값으로 두고 넘어갔었다.
이번에 알게된거는, ec2가 올라가기 위해서는
1. vpc 를 하나 만든다.
2. 만든 vpc 의 subnet을 하나 만든다.
3. ec2가 외부랑 통신하기 위해 인터넷 게이트웨이를 만든다.
4. 인터넷 게이트웨이가 사용할 라우팅 테이블을 만들어준다.
5. 서브넷과 라우팅테이블을 연결시켜준다.
이렇게 하면 ec2가 외부 인터넷과 통신할 수 있게 네트워크를 구성해준것이다.
나머지는 테라폼 파일을 보면 이해할 수 있다.
한가지 null_resource 부분에 대해 설명하자면
eip 를 생성하고, ec2에 연결한다면, ec2를 사용할 준비가 끝났으므로, 나머지는 ec2에 명령을 내리는 부분이어서 null_resource를 사용한거로 추측한다. null_resource 대신 terraform_data를 사용해도 동작한다.
다음은, null_resource와 terraform_data의 차이에 대해 알아보겠다.
'AWS' 카테고리의 다른 글
ec2에서 jenkins 빌드서버 만들어보기 3편 (0) 2023.04.10 github actions, kustomize와 argocd를 EKS에서 kafka랑 사용하기 8부 (0) 2023.04.08 github actions, kustomize와 argocd를 EKS에서 kafka랑 사용하기 7부 (0) 2023.04.05 github actions, kustomize와 argocd를 EKS에서 kafka랑 사용하기 6부 (0) 2023.04.05 github actions, kustomize와 argocd를 EKS에서 kafka랑 사용하기 5부 (0) 2023.04.03