본문 바로가기

AWS Cloud

[AWS - Terraform] Instance(EC2) 생성

반응형

* 참조 사항
- 필자는 학습을 목적으로 main.tf에 전체 인프라 구축 코드를 작성하였으며, 이에 대해 각기 설명함
- .tf 파일을 resource 별로 분할할 시, 필자와 코드가 다를 수 있음
- Terraform 기초부터 순차적으로 보길 권장 (1번 게시물의 이해가 매우 중요)

1. Architecture Create : https://isc9511.tistory.com/163

2. Bucket 생성 및 파일 업로드 : https://isc9511.tistory.com/164

3. IAM Role 생성 및 정책 Attachment : https://isc9511.tistory.com/165

4. Network Setting : https://isc9511.tistory.com/166

5. RDS 생성 : https://isc9511.tistory.com/167

 

 

 

* EC2(Elastic Computer Cloud) : 사용자가 직접 사용하는 클라우드상의 가상 컴퓨터

 

 

 

* Code 내용
- EC2 생성 시, 해당 인스턴스가 AWS Resource에 대한 특정 행위를 수행할 수 있도록 IAM Role을 Instance Profile로써 지정해 줘야함 (ex- EC2가 Bucket과 리소스 업/다운로드 행위 수행)

- 3번 게시물에서 생성했던 IAM Role을 Instance Profile로 Attachment

- 인스턴스 생성 및 생성과 더불어 User_data를 삽입하여 해당 OS에 맞는 적절한 명령어가 자동적으로 실행될 수 있도록 삽입

- 5번 게시물에서 생성한 RDS를 직접 제어할 수 있도록 MySQL 설치 및 로그인, 테이블 생성 등의 작업 수행

1) IAM Role을 Instance Profile로 부착

# 생성했던 IAM Role을 기반으로 Instance Profile 생성
resource "aws_iam_instance_profile" "three-tier-profile" {
  name = "instance-ssm-bucket-role" # 해당 인스턴스 Profile Name이 Instance 생성 코드에 필요
  role = aws_iam_role.instance-profile.name # .name으로 생성한 IAM Role 지정
}

2) Instance 생성

# Application Instance (Middle Tier) 생성
resource "aws_instance" "applayer" {
  ami = "ami-0ff56409a6e8ea2a0"
  instance_type = "t2.micro"
  key_name = "" # 해당 값이 비워져 있을 시, 인스턴스 인증키 값 없이 진행함을 의미
  iam_instance_profile = "instance-ssm-bucket-role" # aws_iam_instance_profile에서 지정한 name 인자에 해당하는 role 이름 지정
    # Instance Profile은 EC2가 Role을 할당 받아서 특정 작업을 수행할 수 있도록 함
  vpc_security_group_ids = [aws_security_group.private-instance-sg.id]
  subnet_id = aws_subnet.private-subnet-az1.id
  
  depends_on = [aws_rds_cluster_instance.aurora-mysql-db-instance]
    # depends_on의 경우 특정 resource 코드가 완전히 구동된 후, 다음으로 구동시키기 위해 필요한 코드
    # 해당 코드에서는 rds_cluster_instance 생성 코드가 완료된 후 applayer 인스턴스 생성을 시작함


user_data = <<EOF
#!/bin/bash
sudo -su ec2-user <<EOS
sudo yum install mysql -y
sudo mysql -h ${aws_rds_cluster.aurora-mysql-db.endpoint} -u RDS유저명 -pRDS유저패스워드 <<MYSQL_SCRIPT
CREATE DATABASE webappdb;
use webappdb;
CREATE TABLE IF NOT EXISTS transactions(id INT NOT NULL AUTO_INCREMENT, amount DECIMAL(10,2), description VARCHAR(100), PRIMARY KEY(id));
INSERT INTO transactions (amount,description) VALUES ('400','groceries');
MYSQL_SCRIPT
cd /home/ec2-user
sudo aws s3 cp s3://three-tier-code-bucket/app-tier/ app-tier --recursive
sudo chmod 777 app-tier/

# Create DbConfig.js file
cat << EOT > /home/ec2-user/app-tier/DbConfig.js
module.exports = Object.freeze({
    DB_HOST : '${aws_rds_cluster.aurora-mysql-db.endpoint}',
    DB_USER : '${aws_rds_cluster.aurora-mysql-db.master_username}',
    DB_PWD : '${aws_rds_cluster.aurora-mysql-db.master_password}',
    DB_DATABASE : 'webappdb'
});
EOT

sudo curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.38.0/install.sh | bash
source ~/.bashrc
nvm install 16
nvm use 16
npm install -g pm2
sudo chmod 777 /home/ec2-user/app-tier/*
cd /home/ec2-user/app-tier
npm install -y
pm2 start index.js
sudo env PATH=$PATH:/home/ec2-user/.nvm/versions/node/v16.19.1/bin /home/ec2-user/.nvm/versions/node/v16.19.1/lib/node_modules/pm2/bin/pm2 startup systemd -u ec2-user --hp /home/ec2-user
pm2 save
pm2 list >> statusfile
curl http://localhost:4000/health >> statusfile
curl http://localhost:4000/transaction >> statusfile
EOS
EOF

/* EOF, EOS, EOT는 Seperator(구분자) 역할을 수행 (값은 사용자 임의값으로 시작과 끝 부분만 동일하면 사용 가능)
  위 코드에서 EOF는 User_data 전체의 코드를 감싸도록 지정
    EOS는 sudo -su ec2-user 권한을 계속 유지하면서 명령어가 실행 될 수 있도록 구분자로 엮음
      EOT는 특정 파일 생성 명령어에 사용할 수 있도록 배치(DbConfig.js)
        <<MYSQL_SCRIPT도 일종의 구분자이나, 해당 구분자는 고정값으로 MYSQL 명령어 사용 시 필수적으로 지정되어야함

Mysql 로그인 시, -u 계정명 -p패스워드 입력이 필요한데 -p 이후에 값을 띄워버리면 시스템이 입력값을 받는데 공백을 넣어서 붙여줘야함

나머지는 명령어를 읽으면 알수있는 수준
  - 중요한점은 별도 ec2에서 동일 계정, 동일 권한으로 테스트를 하면서 수행해 보길 권장 (명령어만 작성해서 테스트 해버리면 권한에 막혀서 트러블 슈팅 힘들 수 있음)
*/

  tags = {
    Name = "Applayer"
  }
}

 

 

 

* 주의 사항

1) depends_on 코드 사용
- Terraform을 사용하여 IaC를 구현 시, 리소스간의 종속성이 굉장히 중요하며 순차 실행이 필요한 리소스간 종속성을 지정해 주는 코드가 depends_on
ex) 특정 리소스가 생성된 후, 특정 다음 리소스가 순차적으로 생성되는게 필연적인 경우 반드시 종속성 지정

RDS instance로 새로 생성하는 EC2가 종속성을 가지도록 depends_on 설정

2) EC2 user_data
- user_data를 별도 파일로 분리하여 지정할 수도 있지만, 가독성과 학습을 위해 한 파일에 몰아서 코드 나열

- user_data의 경우, 코드를 실행하는 동안 완전히 수행되는 시간과 권한 등의 문제를 꼼꼼히 체크하여야 하기 때문에, 실제로 코드는 정상적으로 동작하더라도, 인스턴스 접속하여 확인 시 의도와 다르게 수행되지 않은 명령어가 존재할 수 있음
(실제로 수많은 apply와 destroy를 하게만든 주범)

- user_data에 어플리케이션, 특정 명령어 분기점, 특정 계정의 권한 지속 등을 위해 구분자를 사용

의도와 다르게 구동되는 Case가 굉장히 많으므로 명령어 수행이 정상적으로 되었는지 지속적인 확인이 필요

 

 

 

 

반응형