aws(terraform)(1)

강찬우·2024년 2월 21일

aws

목록 보기
1/2

terraform을 이용한 aws배포와 github action을 이용한 배포를 연습해보려한다. 일단 aws의 계정 생성과 admin유저를 만들고 권한을 주는 과정을 생략하였다.

연습한 프로젝트 주소: https://github.com/chanw12/sb_2024_02_20

AWS CLI 설치

curl "https://awscli.amazonaws.com/AWSCLIV2.pkg" -o "AWSCLIV2.pkg"
sudo installer -pkg AWSCLIV2.pkg -target /

AWS CLI 명령어

  • aws configure list
    - AWS 엑세스키가 등록되어 있는지 확인
  • aws configure
    - AWS 엑세스키 등록
    - 엑세스 키, 시크릿 엑세스키 등록
    - 재등록도 가능
    • 리전 : ap-northeast-2
      • ap-northeast-2 : AWS 서울
        - Default output format 에서는 그냥 엔터
    • aws s3 ls
      • 아무 결과가 안나오면 성공적으로 로그인 되었다고 볼 수 있습니다.
  • 엑세스키 삭제하는 방법
    - 콘솔 -> IAM USER -> admin 유저 선택 -> 보안자격증명 -> 액세스 키 -> 비활성화 -> 삭제
  • AWS CLI에 입력된 엑세스키 삭제하는 방법
    - 윈도우 터미널
    - rmdir /s /q "%USERPROFILE%/.aws"
    - 윈도우 파워쉘
    - rm -force -recurse $HOME\.aws
    - MAC
    - rm -rf ~/.aws

테라폼 CLI 설치

main.tf

terraform {
  // aws 라이브러리 불러옴
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 4.0"
    }
  }
}

# AWS 설정 시작
provider "aws" {
  region = var.region
}
# AWS 설정 끝

# VPC 설정 시작
resource "aws_vpc" "vpc_1" {
  cidr_block = "10.0.0.0/16"

  # 무조건 켜세요.
  enable_dns_support   = true
  # 무조건 켜세요.
  enable_dns_hostnames = true

  tags = {
    Name = "${var.prefix}-vpc-1"
  }
}

resource "aws_subnet" "subnet_1" {
  vpc_id                  = aws_vpc.vpc_1.id
  cidr_block              = "10.0.1.0/24"
  availability_zone       = "${var.region}a"
  map_public_ip_on_launch = true

  tags = {
    Name = "${var.prefix}-subnet-1"
  }
}

resource "aws_subnet" "subnet_2" {
  vpc_id                  = aws_vpc.vpc_1.id
  cidr_block              = "10.0.2.0/24"
  availability_zone       = "${var.region}b"
  map_public_ip_on_launch = true

  tags = {
    Name = "${var.prefix}-subnet-2"
  }
}

resource "aws_subnet" "subnet_3" {
  vpc_id                  = aws_vpc.vpc_1.id
  cidr_block              = "10.0.3.0/24"
  availability_zone       = "${var.region}c"
  map_public_ip_on_launch = true

  tags = {
    Name = "${var.prefix}-subnet-3"
  }
}

resource "aws_internet_gateway" "igw_1" {
  vpc_id = aws_vpc.vpc_1.id

  tags = {
    Name = "${var.prefix}-igw-1"
  }
}

resource "aws_route_table" "rt_1" {
  vpc_id = aws_vpc.vpc_1.id

  route {
    cidr_block = "0.0.0.0/0"
    gateway_id = aws_internet_gateway.igw_1.id
  }

  tags = {
    Name = "${var.prefix}-rt-1"
  }
}

resource "aws_route_table_association" "association_1" {
  subnet_id      = aws_subnet.subnet_1.id
  route_table_id = aws_route_table.rt_1.id
}

resource "aws_route_table_association" "association_2" {
  subnet_id      = aws_subnet.subnet_2.id
  route_table_id = aws_route_table.rt_1.id
}

resource "aws_route_table_association" "association_3" {
  subnet_id      = aws_subnet.subnet_3.id
  route_table_id = aws_route_table.rt_1.id
}

resource "aws_security_group" "sg_1" {
  name = "${var.prefix}-sg-1"

  ingress {
    from_port   = 0
    to_port     = 0
    protocol    = "all"
    cidr_blocks = ["0.0.0.0/0"]
  }

  egress {
    from_port   = 0
    to_port     = 0
    protocol    = "all"
    cidr_blocks = ["0.0.0.0/0"]
  }

  vpc_id = aws_vpc.vpc_1.id

  tags = {
    Name = "${var.prefix}-sg-1"
  }
}

# EC2 설정 시작

# EC2 역할 생성
resource "aws_iam_role" "ec2_role_1" {
  name = "${var.prefix}-ec2-role-1"

  # 이 역할에 대한 신뢰 정책 설정. EC2 서비스가 이 역할을 가정할 수 있도록 설정
  assume_role_policy = <<EOF
  {
    "Version": "2012-10-17",
    "Statement": [
      {
        "Sid": "",
        "Action": "sts:AssumeRole",
        "Principal": {
            "Service": "ec2.amazonaws.com"
        },
        "Effect": "Allow"
      }
    ]
  }
  EOF
}

# EC2 역할에 AmazonS3FullAccess 정책을 부착
resource "aws_iam_role_policy_attachment" "s3_full_access" {
  role       = aws_iam_role.ec2_role_1.name
  policy_arn = "arn:aws:iam::aws:policy/AmazonS3FullAccess"
}

# EC2 역할에 AmazonEC2RoleforSSM 정책을 부착
resource "aws_iam_role_policy_attachment" "ec2_ssm" {
  role       = aws_iam_role.ec2_role_1.name
  policy_arn = "arn:aws:iam::aws:policy/service-role/AmazonEC2RoleforSSM"
}

# IAM 인스턴스 프로파일 생성
resource "aws_iam_instance_profile" "instance_profile_1" {
  name = "${var.prefix}-instance-profile-1"
  role = aws_iam_role.ec2_role_1.name
}

locals {
  ec2_user_data_base = <<-END_OF_FILE
#!/bin/bash
yum install docker -y
systemctl enable docker
systemctl start docker

curl -L https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m) -o /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose

yum install git -y

sudo dd if=/dev/zero of=/swapfile bs=128M count=32
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile
sudo swapon -s
sudo sh -c 'echo "/swapfile swap swap defaults 0 0" >> /etc/fstab'

END_OF_FILE
}

# EC2 인스턴스 생성
resource "aws_instance" "ec2_1" {
  # 사용할 AMI ID
  ami                         = "ami-07eff2bc4837a9e01"
  # EC2 인스턴스 유형
  instance_type               = "t2.micro"
  # 사용할 서브넷 ID
  subnet_id                   = aws_subnet.subnet_1.id
  # 적용할 보안 그룹 ID
  vpc_security_group_ids      = [aws_security_group.sg_1.id]
  # 퍼블릭 IP 연결 설정
  associate_public_ip_address = true

  # 인스턴스에 IAM 역할 연결
  iam_instance_profile = aws_iam_instance_profile.instance_profile_1.name

  # 인스턴스에 태그 설정
  tags = {
    Name = "${var.prefix}-ec2-1"
  }

  # 루트 볼륨 설정
  root_block_device {
    volume_type = "gp3"
    volume_size = 32  # 볼륨 크기를 32GB로 설정
  }

  # User data script for ec2_1
  user_data = <<-EOF
${local.ec2_user_data_base}

mkdir -p /docker_projects/sb_2024_02_19_1/source
cd /docker_projects/sb_2024_02_19_1/source
git clone https://github.com/jhs512/sb-2024-02-19 .

# 도커 이미지 생성
docker build -t sb_2024_02_19_1:1 .

# 생성된 이미지 실행
docker run \
    --name=sb_2024_02_19_1_1 \
    -p 8080:8080 \
    -v /docker_projects/sb_2024_02_19_1/volumes/gen:/gen \
    --restart unless-stopped \
    -e TZ=Asia/Seoul \
    -d \
    sb_2024_02_19_1:1
EOF
}

# EC2 인스턴스 생성
resource "aws_instance" "ec2_2" {
  # 사용할 AMI ID
  ami                         = "ami-07eff2bc4837a9e01"
  # EC2 인스턴스 유형
  instance_type               = "t2.micro"
  # 사용할 서브넷 ID
  subnet_id                   = aws_subnet.subnet_3.id
  # 적용할 보안 그룹 ID
  vpc_security_group_ids      = [aws_security_group.sg_1.id]
  # 퍼블릭 IP 연결 설정
  associate_public_ip_address = true

  # 인스턴스에 IAM 역할 연결
  iam_instance_profile = aws_iam_instance_profile.instance_profile_1.name

  # 인스턴스에 태그 설정
  tags = {
    Name = "${var.prefix}-ec2-2"
  }

  # 루트 볼륨 설정
  root_block_device {
    volume_type = "gp3"
    volume_size = 32  # 볼륨 크기를 32GB로 설정
  }

  # User data script for ec2_2
  user_data = <<-EOF
${local.ec2_user_data_base}

docker run \
    --name=nginx_1 \
    -p 80:80 \
    --restart unless-stopped \
    -e TZ=Asia/Seoul \
    -d \
    nginx
EOF
}

vpc설정,서브넷 설정,인터넷 게이트웨이 설정, ec2인스턴스 설정후 생성 등등의 작업을 main.tf파일에서 할 수 있다.

이 파일을 생성후 파일이 있는 경로에서 테라폼 명령어를 이용한다.

테라폼 명령어

  • terraform init
    - 라이브러리 다운로드
    • 라이브러리 관련 소스코드가 바뀔 때 마다 실행해야 한다.
  • terraform plan
    - 실제 리소스 생성을 하는것은 아니고
    • 현재 소스코드가 실행가능한지 검사
  • terraform apply
    - 리소스 생성
    - yes 입력
  • terraform destroy
    - 리소스 삭제
    - yes 입력

명령어를 이용해 init후 apply하면 인스턴스가 생성되는 것을 볼 수 있다.

0개의 댓글