terraform 코드에서 명시적으로 지정하려고 했는데 에러가 발생했다.
가장 쉬운 방법은 수동으로 터미널 진입해서 작성해주는건데, 일단 2차 프로젝트에서는 이렇게 진행하고, 3차에는 프로비저너 이용해서 쓰는 걸로 하자 ...
# 원본 코드
resource "aws_instance" "A_Public" {
ami = "ami-062cf18d655c0b1e8"
instance_type = "t2.medium"
subnet_id = aws_subnet.Public_A1.id
key_name = "KDT_Project2_AWS"
vpc_security_group_ids = [aws_security_group.default.id]
tags = {
Name = "A_Public"
}
user_data = <<-EOF
#!/bin/bash
# 로깅 확인 파일 생성
LOG_FILE=/var/log/user_data.log
exec > >(tee -a $LOG_FILE) 2>&1
# 호스트 이름 변경
hostnamectl set-hostname a-public
echo "127.0.1.1 a-public" >> /etc/hosts
echo "호스트 이름 변경 완료!"
# SSH 포트 변경
sed -i 's/#Port 22/Port 51228/' /etc/ssh/sshd_config
systemctl restart sshd
echo "SSH 포트 변경 성공!"
# PEM 파일 생성 및 권한 설정
echo "${var.key_pair_content}" > /home/ubuntu/KDT_Project2_AWS.pem
chmod 400 /home/ubuntu/KDT_Project2_AWS.pem
echo "키 페어 파일 생성 및 권한 설정 완료!"
# Nginx 및 OpenJDK 17 설치
sudo apt-get update
sudo apt-get install -y curl gnupg2 ca-certificates lsb-release
# ubuntu-keyring 패키지 설치
sudo apt-get install -y ubuntu-keyring
# nginx.list 파일 생성 : 공식 저장소에서 서명 키 가져오기
curl -s https://nginx.org/keys/nginx_signing.key | gpg --dearmor \
| sudo tee /usr/share/keyrings/nginx-archive-keyring.gpg >/dev/null
# 다운로드한 키가 올바른지 확인
gpg --dry-run --quiet --no-keyring --import --import-options import-show /usr/share/keyrings/nginx-archive-keyring.gpg
# 저장소 설정 (Stable version)
echo "deb [signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg] \
http://nginx.org/packages/ubuntu $(lsb_release -cs) nginx" \
| sudo tee /etc/apt/sources.list.d/nginx.list
# 저장소 업데이트
sudo apt-get update
# nginx 설치
sudo apt-get install -y nginx
# nginx 버전 확인
nginx -v
# nginx 가동 시작
sudo systemctl start nginx
# OpenJDK 17 설치
sudo apt update
sudo apt install -y openjdk-17-jdk
echo "Nginx와 JDK 17 설치 완료!"
# Nginx 리버스 프록시 설정
A_PRIVATE01_IP=$(aws ec2 describe-instances --instance-ids ${aws_instance.A_Private01.id} --query "Reservations[*].Instances[*].PrivateIpAddress" --output text)
B_PRIVATE01_IP=$(aws ec2 describe-instances --instance-ids ${aws_instance.B_Private01.id} --query "Reservations[*].Instances[*].PrivateIpAddress" --output text)
sudo sed -i '/http {/a \\
upstream inclass-spring-security {\\
server ${A_PRIVATE01_IP}:8080 weight=100 max_fails=3 fail_timeout=3s;\\
server ${B_PRIVATE01_IP}:8080 weight=100 max_fails=3 fail_timeout=3s;\\
}\\
server {\\
location / {\\
proxy_pass http://inclass-spring-security;\\
proxy_http_version 1.1;\\
proxy_set_header Upgrade $http_upgrade;\\
proxy_set_header Connection "upgrade";\\
proxy_set_header Host $host;\\
proxy_cache_bypass $http_upgrade;\\
}\\
}' /etc/nginx/nginx.conf
sudo systemctl restart nginx
echo "Nginx 리버스 프록시 설정 완료!"
EOF
}
resource "aws_eip" "a_public_eip" {
instance = aws_instance.A_Public.id
vpc = true
}
이 코드에서 수정 진행, 2차 플젝은 저기서 nginx 리버스 프록시 설정하는 버전 지우고, 수동으로 설정해줌
에러 코드 :
Error: Invalid reference
│
│ on ec2_instances.tf line 167, in resource "aws_instance" "A_Public":
│ 167: server ${A_PRIVATE01_IP}:8080 weight=100 max_fails=3 fail_timeout=3s;\\
│
│ A reference to a resource type must be followed by at least one attribute access, specifying the resource name.
╵
╷
│ Error: Invalid reference
│
│ on ec2_instances.tf line 168, in resource "aws_instance" "A_Public":
│ 168: server ${B_PRIVATE01_IP}:8080 weight=100 max_fails=3 fail_timeout=3s;\\
│
│ A reference to a resource type must be followed by at least one attribute access, specifying the resource name.
GPT의 대답 :
Terraform에서 인스턴스의 Private IP를 가져오기 위해서는 데이터 소스를 사용해야 합니다. aws_instance 리소스가 생성된 후에 IP 주소를 사용할 수 있기 때문에, user_data에서 바로 사용할 수 없습니다.
해결 방법:
local-exec 프로비저너를 사용하여 인스턴스 생성 후 IP 주소를 가져오고, 필요한 파일을 구성합니다. Terraform에서 변수와 데이터 소스를 사용하여 이를 수행할 수 있습니다.
1. 인스턴스 정의 수정
먼저, aws_instance 리소스 정의에서 user_data를 단순화하고, 이후에 local-exec 프로비저너를 사용하여 Nginx 설정을 구성합니다.
resource "aws_instance" "A_Public" {
ami = "ami-062cf18d655c0b1e8"
instance_type = "t2.medium"
subnet_id = aws_subnet.Public_A1.id
key_name = "KDT_Project2_AWS"
vpc_security_group_ids = [aws_security_group.default.id]
tags = {
Name = "A_Public"
}
user_data = <<-EOF
#!/bin/bash
# 로깅 확인 파일 생성
LOG_FILE=/var/log/user_data.log
exec > >(tee -a $LOG_FILE) 2>&1
# 호스트 이름 변경
hostnamectl set-hostname a-public
echo "127.0.1.1 a-public" >> /etc/hosts
echo "호스트 이름 변경 완료!"
# SSH 포트 변경
sed -i 's/#Port 22/Port 51228/' /etc/ssh/sshd_config
systemctl restart sshd
echo "SSH 포트 변경 성공!"
# PEM 파일 생성 및 권한 설정
echo "${var.key_pair_content}" > /home/ubuntu/KDT_Project2_AWS.pem
chmod 400 /home/ubuntu/KDT_Project2_AWS.pem
echo "키 페어 파일 생성 및 권한 설정 완료!"
# Nginx 및 OpenJDK 17 설치
sudo apt-get update
sudo apt-get install -y curl gnupg2 ca-certificates lsb-release
# ubuntu-keyring 패키지 설치
sudo apt-get install -y ubuntu-keyring
# nginx.list 파일 생성 : 공식 저장소에서 서명 키 가져오기
curl -s https://nginx.org/keys/nginx_signing.key | gpg --dearmor \
| sudo tee /usr/share/keyrings/nginx-archive-keyring.gpg >/dev/null
# 다운로드한 키가 올바른지 확인
gpg --dry-run --quiet --no-keyring --import --import-options import-show /usr/share/keyrings/nginx-archive-keyring.gpg
# 저장소 설정 (Stable version)
echo "deb [signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg] \
http://nginx.org/packages/ubuntu $(lsb_release -cs) nginx" \
| sudo tee /etc/apt/sources.list.d/nginx.list
# 저장소 업데이트
sudo apt-get update
# nginx 설치
sudo apt-get install -y nginx
# nginx 버전 확인
nginx -v
# nginx 가동 시작
sudo systemctl start nginx
# OpenJDK 17 설치
sudo apt update
sudo apt install -y openjdk-17-jdk
echo "Nginx와 JDK 17 설치 완료!"
EOF
provisioner "local-exec" {
command = <<-EOF
A_PRIVATE01_IP=$(aws ec2 describe-instances --instance-ids ${aws_instance.A_Private01.id} --query "Reservations[*].Instances[*].PrivateIpAddress" --output text)
B_PRIVATE01_IP=$(aws ec2 describe-instances --instance-ids ${aws_instance.B_Private01.id} --query "Reservations[*].Instances[*].PrivateIpAddress" --output text)
ssh -i /path/to/your/private/key ubuntu@${self.public_ip} << 'EOC'
sudo sed -i '/http {/a \\
upstream inclass-spring-security {\\
server ${A_PRIVATE01_IP}:8080 weight=100 max_fails=3 fail_timeout=3s;\\
server ${B_PRIVATE01_IP}:8080 weight=100 max_fails=3 fail_timeout=3s;\\
}\\
server {\\
location / {\\
proxy_pass http://inclass-spring-security;\\
proxy_http_version 1.1;\\
proxy_set_header Upgrade $http_upgrade;\\
proxy_set_header Connection "upgrade";\\
proxy_set_header Host $host;\\
proxy_cache_bypass $http_upgrade;\\
}\\
}' /etc/nginx/nginx.conf
sudo systemctl restart nginx
EOC
EOF
}
}
resource "aws_eip" "a_public_eip" {
instance = aws_instance.A_Public.id
vpc = true
}
2. 데이터 소스를 사용하여 인스턴스 정보 가져오기
인스턴스 생성 후에 Private IP 주소를 가져오는 방법을 추가합니다.
data "aws_instance" "A_Private01" {
instance_id = aws_instance.A_Private01.id
}
data "aws_instance" "B_Private01" {
instance_id = aws_instance.B_Private01.id
}
이제 local-exec 프로비저너에서 data 블록을 사용하여 인스턴스의 Private IP 주소를 가져올 수 있습니다.
3. 통합된 코드
아래는 통합된 코드입니다.
provider "aws" {
region = "us-west-2"
}
resource "aws_vpc" "KDT_Project2" {
cidr_block = "10.0.0.0/16"
}
resource "aws_subnet" "Public_A1" {
vpc_id = aws_vpc.KDT_Project2.id
cidr_block = "10.0.1.0/24"
map_public_ip_on_launch = true
}
resource "aws_security_group" "default" {
vpc_id = aws_vpc.KDT_Project2.id
ingress {
from_port = 80
to_port = 80
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
ingress {
from_port = 51228
to_port = 51228
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 = "default"
}
}
resource "aws_instance" "A_Public" {
ami = "ami-062cf18d655c0b1e8"
instance_type = "t2.medium"
subnet_id = aws_subnet.Public_A1.id
key_name = "KDT_Project2_AWS"
vpc_security_group_ids = [aws_security_group.default.id]
tags = {
Name = "A_Public"
}
user_data = <<-EOF
#!/bin/bash
# 로깅 확인 파일 생성
LOG_FILE=/var/log/user_data.log
exec > >(tee -a $LOG_FILE) 2>&1
# 호스트 이름 변경
hostnamectl set-hostname a-public
echo "127.0.1.1 a-public" >> /etc/hosts
echo "호스트 이름 변경 완료!"
# SSH 포트 변경
sed -i 's/#Port 22/Port 51228/' /etc/ssh/sshd_config
systemctl restart sshd
echo "SSH 포트 변경 성공!"
# PEM 파일 생성 및 권한 설정
echo "${var.key_pair_content}" > /home/ubuntu/KDT_Project2_AWS.pem
chmod 400 /home/ubuntu/KDT_Project2_AWS.pem
echo "키 페어 파일 생성 및 권한 설정 완료!"
# Nginx 및 OpenJDK 17 설치
sudo apt-get update
sudo apt-get install -y curl gnupg2 ca-certificates lsb-release
# ubuntu-keyring 패키지 설치
sudo apt-get install -y ubuntu-keyring
# nginx.list 파일 생성 : 공식 저장소에서 서명 키 가져오기
curl -s https://nginx.org/keys/nginx_signing.key | gpg --dearmor \
| sudo tee /usr/share/keyrings/nginx-archive-keyring.gpg >/dev/null
# 다운로드한 키가 올바른지 확인
gpg --dry-run --quiet --no-keyring --import --import-options import-show /usr/share/keyrings/nginx-archive-keyring.gpg
# 저장소 설정 (Stable version)
echo "deb [signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg] \
http://nginx.org/packages/ubuntu $(lsb_release -cs) nginx" \
| sudo tee /etc/apt/sources.list.d/nginx.list
# 저장소 업데이트
sudo apt-get update
# nginx 설치
sudo apt-get install -y nginx
# nginx 버전 확인
nginx -v
# nginx 가동 시작
sudo systemctl start nginx
# OpenJDK 17 설치
sudo apt update
sudo apt install -y openjdk-17-jdk
echo "Nginx와 JDK 17 설치 완료!"
EOF
provisioner "local-exec" {
command = <<-EOF
A_PRIVATE01_IP=$(aws ec2 describe-instances --instance-ids ${aws_instance.A_Private01.id} --query "Reservations[*].Instances[*].PrivateIpAddress" --output text)
B_PRIVATE01_IP=$(aws ec2 describe-instances --instance-ids ${aws_instance.B_Private01.id} --query "Reservations[*].Instances[*].PrivateIpAddress" --output text)
ssh -i /path/to/your/private/key ubuntu@${self.public_ip} << 'EOC'
sudo sed -i '/http {/a \\
upstream inclass-spring-security {\\
server ${A_PRIVATE01_IP}:8080 weight=100 max_fails=3 fail_timeout=3s;\\
server ${B_PRIVATE01_IP}:8080 weight=100 max_fails=3 fail_timeout=3s;\\
}\\
server {\\
location / {\\
proxy_pass http://inclass-spring-security;\\
proxy_http_version 1.1;\\
proxy_set_header Upgrade $http_upgrade;\\
proxy_set_header Connection "upgrade";\\
proxy_set_header Host $host;\\
proxy_cache_bypass $http_upgrade;\\
}\\
}' /etc/nginx/nginx.conf
sudo systemctl restart nginx
EOC
EOF
}
}
resource "aws_eip" "a_public_eip" {
instance = aws_instance.A_Public.id
vpc = true
}
data "aws_instance" "A_Private01" {
instance_id = aws_instance.A_Private01.id
}
data "aws_instance" "B_Private01" {
instance_id = aws_instance.B_Private01.id
}
이제 aws_instance 리소스가 생성된 후에 local-exec 프로비저너를 사용하여 인스턴스의 Private IP 주소를 가져오고, 필요한 Nginx 설정을 수행할 수 있습니다.
'2024 KDT 📕 > Project' 카테고리의 다른 글
[ AWS Terraform ] SSH 포트 변경 설정 방법 (0) | 2024.07.22 |
---|---|
[ AWS Terraform ] 로깅 코드 추가 (0) | 2024.07.22 |
로드밸런싱 스샷 (0) | 2024.07.19 |
[ AWS ] 애플리케이션 배포 과정 (0) | 2024.07.15 |
2차 프로젝트 관련 . . (0) | 2024.07.15 |