일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
- secret engines
- Vault
- 통합 풀 백업
- 자동화
- backend storage
- 백업
- 커널 파라미터
- 인프라
- Secret Engine
- 파일시스템
- 앤서블
- vault agent
- Role
- kv
- 유닉스
- VIRT
- key/value
- 차분 백업
- DATA 백업
- 리눅스
- SSH OTP
- 전체 백업
- 구성관리
- devops
- SHR
- REST API
- auth methods
- hashicorp
- IAC
- 시스템
- Today
- Total
클라우드 아카이브
[IaC] 테라폼의 개념과 특징 본문
개요
2000년대 초반에만 해도 시스템 관리자가 담당할 서버의 개수는 매우 적었습니다. 하지만 기술의 발전에 따라 기업의 인프라의 복잡성은 증대되고, 시스템 관리자가 관리해야할 개수 또한 비례하여 증가하게 됩니다. 이처럼 시스템의 복잡성이 증대되면서 DevOps 및 IaC와 같은 개념이 생겨나게 되는데요. 특히, 현대 인프라의 가용성을 유지하기 위해서는 IaC를 이용한 시스템 자동화가 필수가 되어가고 있습니다.
따라서 본 포스팅에서는 이러한 복잡성을 해결해줄 수 있는 프로비저닝 및 구성 관리 자동화 도구인 테라폼에 대해 알아보는 글을 쓰겠습니다.
테라폼이란?
2014년에 Hashicorp에서 최초로 배포된 오픈 소스 기반의 프로비저닝 및 구성 관리 자동화 툴입니다. 테라폼은 Go로 개발되었으며 Linux, MacOS, Windows 등 다양한 OS에서 사용 가능합니다. 2021년 10월 기준으로 테라폼의 안정화 버전은 2021년 6월 8일에 업그레이드된 1.0.0 버전입니다. 테라폼 사용자는 Hashicorp에서 개발한 선언형 언어 HCL(HashiCorp Configuration Language)를 사용하여 데이터 센터의 Infrastructure를 작성하고, 계획하고, 적용할 수 있습니다.
테라폼의 설계 의도
Write, Plan, Apply
작성하고, 계획하고, 적용한다.
테라폼의 본질은 퍼블릭/프라이빗 클라우드, 네트워크 어플라이언스, PaaS, SaaS 등과 같은 외부 리소스를 provider로 지정하여 관리할 수 있도록 하는 것입니다. IaaS/PaaS/SaaS 벤더는 테라폼에 공식 Provider를 등록함으로써 사용자가 해당 벤더의 제품을 테라폼으로 자동화할 수 있도록 합니다. 즉 AWS, GCP, Azure와 같은 클라우드 3사를 포함하여 ElasticStack, Kubernetes 등의 도구가 테라폼의 Official Provdiers로 등록되어 있기 때문에 테라폼으로 선언형 인프라 코드 작성이 가능한 것입니다. 사용자는 할당할 리소스를 코드로 작성하고 적용함으로써 Provider에 원하는 리소스를 생성할 수 있습니다.
테라폼 Official Provider는 여기를 클릭해주시면 확인이 가능합니다.
테라폼의 특징
1. Provider
- 테라폼으로 생성할 자원이 제공되는 주체가 누구인지
- AWS를 Provider로 지정하면 EC2, RDS, S3 등의 리소스 생성을 코드로 작성할 수 있게 됩니다.
2. Resource
- 테라폼으로 어떤 리소스를 생성할 것인지
- AWS에서 EC2, RDS와 같은 제품이 리소스에 해당합니다.
3. State
- 테라폼으로 생성한 자원의 상태가 어떤지
- Resource로 EC2를 생성했을 때, 실제로 AWS에 할당된 노드의 VPC, Subnet, IP 등의 상태를 의미합니다.
4. Module
- 공통적으로 활용되는 코드를 모듈로 정의
- 사용자가 EC2를 생성할 경우 해당 노드의 OS를 선택하는건 필수입니다.
- OS, CPU, Memory 등 모든 사용자가 공통적으로 사용할 수 밖에 없는 코드를 모듈화하여 추상화함으로써 유지보수성을 높입니다.
실습 : AWS에서 EC2를 생성
EC2 요구사항
- OS : CentOS 7.x
- SSH 통신 시, Key Pair 방식으로 사용자 인증 수행
생성 절차
- 테라폼에서 사용할 Provider를 지정
- 테라폼 프로젝트 초기화 (terraform init)
- EC2용 Key Pair 정의
- 리소스로 EC2를 정의
- 작성한 코드가 실제로 Provider에서 생성 가능한지 확인 (terraform plan)
- 해당 리소스를 실제로 생성 (terraform apply)
1. 테라폼에서 사용할 Provider를 지정
테라폼 프로젝트 셋팅을 위해 디렉터리를 생성하고 작성할 코드 파일을 생성합니다.
# 테라폼 프로젝트로 이용할 디렉토리 생성
$ mkdir infra
$ cd infra
# Provider를 지정할 파일 생성
$ touch provider.tf
# EC2를 선언할 파일 생성
$ ec2.tf
# Key Pair를 선언할 파일 생성
$ ec2-key.tf
테라폼으로 사용할 Provider를 provider.tf에 정의합니다.
provider는 아래와 같이 하신 다음, aws 계정에 대한 액세스키 및 시크릿키 등록은 .bash_profile에 등록하는게 보안상 좋습니다.
provider "aws" { }
~/.bash_profile 파일에 아래와 같이 3개의 환경변수를 등록해주면 provider.tf 파일에서 굳이 해당 내용을 등록하지 않아도 테라폼에서 자동으로 인식합니다.
export access_key="<MY_AWS_ACCESS_KEY>"
export secret_key="<MY_AWS_SECRET_KEY>"
export region="<MY_REGION>"
2. 테라폼 프로젝트 초기화 (terraform init)
infra 디렉토리에서 아래 명령어를 실행합니다.
$ terraform init
3. EC2용 Key Pair 정의
사용자는 SSH를 통해 EC2에 접근할 수 있습니다. SSH로 EC2에 접속 시, 인증 절차를 거쳐야하며 아래 2가지 방법을 통해 인증이 가능합니다.
1. EC2 에서 생성한 ID/PW로 사용자 인증
2. 비대칭키 통신 방식을 이용한 사용자 인증
~/.ssh/known_hosts에 아래 정보가 등록되어야 함
- 호스트 IP
- 호스트의 Public Key
본 포스팅에서는 비대칭키 통신 방식으로 인증을 수행할 것이기 때문에, EC2 생성 시 등록할 Key Pair를 지정해주어야 합니다. 먼저 호스트에서 비대칭키 통신에 사용할 Public Key와 Private Key를 생성해줍니다.
$ ssh-keygen -t rsa -b 4096 -C "123@hanwha.com" -f "$HOME/.ssh/ec2_admin"
# rsa 알고리즘으로 암호화/복호화
# 키는 4096 bit로 구성
# 생성자의 이메일은 123@hanwha.com
# ~/.ssh 디렉토리에 web_admin이라는 이름으로 생성
Key Pair 리소스를 생성할 수 있도록 ec2-key.tf에 아래와 같이 입력해줍니다.
resource "aws_key_pair" "ec2_admin" {
key_name = "ec2-admin-public-key"
public_key = file("~/.ssh/ec2_admin.pub")
tags = {
Name = "admin-key-pair"
}
}
4. 리소스로 EC2를 정의
ec2.tf 파일에서는 아래 3가지 작업을 수행하겠습니다.
1. 생성할 EC2 노드에 SSH 접속이 가능하도록 방화벽 정책 등록
"aws_security_group" 리소스가 AWS에서 방화벽 역할을 수행하는 Security Group을 의미합니다. 따라서 해당 리소스로 방화벽 정책을 생성합니다. 방화벽 정책으로는 ingress(EC2로 들어오는 트래픽) 또는 egress(EC2로 나가는 트래픽)이 존재합니다. 본 예제에서는 EC2를 생성하고 SSH 접속하는게 목표이기 때문에 ingress만 등록하겠습니다.
2. EC2에 대한 정보 입력
- OS 이미지는 Ubuntu 18:04, 인스턴스 타입은 t3.small 타입 (mem : 2G, vCPUs : 2 Core)
- associate_public_ip_address : EC2 노드에 공인 IP를 할당할 것인지 지정
3. Key Pair 및 방화벽 정책을 EC2에 연결하여 SSH 접속이 가능하게 만들기
- key_name : ec2-key.tf에서 생성한 aws_key_pair를 EC2 노드에 연결시켜줍니다.
- vpc_security_group_ids : 해당 EC2 노드에 Security Group을 연결시켜줍니다.
resource "aws_instance" "my_ec2_node" {
ami = "ami-0e67aff698cb24c1d" # Ubuntu 18:04 / KR
instance_type = "t3.small" # Memory 2 GB & vCPUs 2
key_name = aws_key_pair.ec2_admin.key_name
# 생성한 ec2 노드가 공인 IP를 받을 수 있도록 지정
associate_public_ip_address = true
# 아래 리소스로 지정한 aws_security_group의 allow_SSH 정책을 EC2에 적용
vpc_security_group_ids = [
aws_security_group.allow_SSH.id
]
tags = {
Name = "my-ec2-node"
}
}
# 방화벽 22번 포트 오픈
resource "aws_security_group" "allow_SSH" {
name = "allow_ssh_from_all"
description = "Allow SSH port from all"
ingress {
from_port = 22
to_port = 22
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
# 전체 포트 및 프로토콜 오픈
egress {
cidr_blocks = [ "0.0.0.0/0"]
from_port = 0
protocol = "-1"
to_port = 0
}
}
5. 작성한 코드가 실제로 Provider에서 생성 가능한지 확인 (terraform plan)
아래 명령어를 입력하여 작성한 tf 파일들이 실제 aws에 어떻게 적용이 되는지 확인해봅니다.
$ terraform plan
Terraform used the selected providers to generate the following execution plan.
Resource actions are indicated with the following symbols:
+ create
Terraform will perform the following actions:
# aws_instance.my_ec2_node will be created
+ resource "aws_instance" "my_ec2_node" {
+ ami = "ami-0e67aff698cb24c1d"
+ arn = (known after apply)
+ associate_public_ip_address = true
+ availability_zone = (known after apply)
+ cpu_core_count = (known after apply)
+ cpu_threads_per_core = (known after apply)
+ disable_api_termination = (known after apply)
+ ebs_optimized = (known after apply)
+ get_password_data = false
+ host_id = (known after apply)
+ id = (known after apply)
+ instance_initiated_shutdown_behavior = (known after apply)
+ instance_state = (known after apply)
+ instance_type = "t3.small"
+ ipv6_address_count = (known after apply)
+ ipv6_addresses = (known after apply)
+ key_name = "ec2_admin"
+ monitoring = (known after apply)
+ outpost_arn = (known after apply)
+ password_data = (known after apply)
+ placement_group = (known after apply)
+ primary_network_interface_id = (known after apply)
+ private_dns = (known after apply)
+ private_ip = (known after apply)
+ public_dns = (known after apply)
+ public_ip = (known after apply)
+ secondary_private_ips = (known after apply)
+ security_groups = (known after apply)
+ source_dest_check = true
+ subnet_id = (known after apply)
+ tags = {
+ "Name" = "my-ec2-node"
}
+ tags_all = {
+ "Name" = "my-ec2-node"
}
+ tenancy = (known after apply)
+ user_data = (known after apply)
+ user_data_base64 = (known after apply)
+ vpc_security_group_ids = (known after apply)
+ capacity_reservation_specification {
+ capacity_reservation_preference = (known after apply)
+ capacity_reservation_target {
+ capacity_reservation_id = (known after apply)
}
}
....
+ ebs_block_device {
+ delete_on_termination = (known after apply)
+ device_name = (known after apply)
+ encrypted = (known after apply)
+ iops = (known after apply)
+ kms_key_id = (known after apply)
+ snapshot_id = (known after apply)
+ tags = (known after apply)
+ throughput = (known after apply)
+ volume_id = (known after apply)
+ volume_size = (known after apply)
+ volume_type = (known after apply)
}
+ name = "allow_ssh_from_all"
+ name_prefix = (known after apply)
+ owner_id = (known after apply)
+ revoke_rules_on_delete = false
+ tags_all = (known after apply)
+ vpc_id = (known after apply)
}
Plan: 3 to add, 0 to change, 0 to destroy.
───────────────────────────────────────────────────────────────────────────────
Note: You didn't use the -out option to save this plan, so Terraform can't
guarantee to take exactly these actions if you run "terraform apply" now.
6. 해당 리소스를 실제로 생성 (terraform apply)
terraform plan이 잘 작동하는 것을 확인했습니다. 이제 AWS에 실제 리소스를 생성해보겠습니다.
$ terraform apply
Terraform used the selected providers to generate the following execution plan.
Resource actions are indicated with the following symbols:
+ create
Terraform will perform the following actions:
# aws_instance.my_ec2_node will be created
+ resource "aws_instance" "my_ec2_node" {
+ ami = "ami-0e67aff698cb24c1d"
+ arn = (known after apply)
+ associate_public_ip_address = true
+ availability_zone = (known after apply)
+ cpu_core_count = (known after apply)
+ cpu_threads_per_core = (known after apply)
+ disable_api_termination = (known after apply)
+ ebs_optimized = (known after apply)
+ get_password_data = false
+ host_id = (known after apply)
+ id = (known after apply)
+ instance_initiated_shutdown_behavior = (known after apply)
+ instance_state = (known after apply)
+ instance_type = "t3.small"
+ ipv6_address_count = (known after apply)
+ ipv6_addresses = (known after apply)
+ key_name = "ec2_admin"
+ monitoring = (known after apply)
+ outpost_arn = (known after apply)
+ password_data = (known after apply)
+ placement_group = (known after apply)
+ primary_network_interface_id = (known after apply)
+ private_dns = (known after apply)
+ private_ip = (known after apply)
+ public_dns = (known after apply)
+ public_ip = (known after apply)
+ secondary_private_ips = (known after apply)
+ security_groups = (known after apply)
+ source_dest_check = true
+ subnet_id = (known after apply)
+ tags = {
+ "Name" = "my-ec2-node"
}
+ tags_all = {
+ "Name" = "my-ec2-node"
}
+ tenancy = (known after apply)
+ user_data = (known after apply)
+ user_data_base64 = (known after apply)
+ vpc_security_group_ids = (known after apply)
...
+ name = "allow_ssh_from_all"
+ name_prefix = (known after apply)
+ owner_id = (known after apply)
+ revoke_rules_on_delete = false
+ tags_all = (known after apply)
+ vpc_id = (known after apply)
}
Plan: 3 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_key_pair.ec2_admin_key: Creating...
aws_security_group.allow_SSH: Creating...
aws_key_pair.ec2_admin_key: Creation complete after 1s [id=ec2_admin]
aws_security_group.allow_SSH: Creation complete after 2s [id=sg-08c6672e7be5d4192]
aws_instance.my_ec2_node: Creating...
aws_instance.my_ec2_node: Still creating... [10s elapsed]
aws_instance.my_ec2_node: Creation complete after 14s [id=i-0d665e57dbc242ff7]
Apply complete! Resources: 3 added, 0 changed, 0 destroyed.
인스턴스가 성공적으로 생성되었습니다! 이제 생성된 노드에 SSH 접근을 해보겠습니다.
➜ ec2-practice ssh -i ~/.ssh/ec2_admin ubuntu@3.35.177.182
The authenticity of host '3.35.177.182 (3.35.177.182)' can't be established.
ECDSA key fingerprint is SHA256:ㄴㅇㄹㅁㄴㅎㄴㅁㅎ
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '3.35.177.182' (ECDSA) to the list of known hosts.
Welcome to Ubuntu 18.04.5 LTS (GNU/Linux 5.4.0-1029-aws x86_64)
* Documentation: https://help.ubuntu.com
* Management: https://landscape.canonical.com
* Support: https://ubuntu.com/advantage
System information as of Mon Oct 4 11:43:05 UTC 2021
System load: 0.53 Processes: 111
Usage of /: 14.5% of 7.69GB Users logged in: 0
Memory usage: 9% IP address for ens5: 172.31.57.210
Swap usage: 0%
0 packages can be updated.
0 updates are security updates.
The programs included with the Ubuntu system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.
Ubuntu comes with ABSOLUTELY NO WARRANTY, to the extent permitted by
applicable law.
To run a command as administrator (user "root"), use "sudo <command>".
See "man sudo_root" for details.
ubuntu@ip-172-31-57-210:~$
마무리
테라폼에 개념과 특성에 대해 알아보고 실제 AWS에서 EC2를 생성하는 실습을 진행했습니다. 다음 포스팅에서는 EC2 노드를 생성 후 해당 노드에 파일시스템을 구성하는 실습을 진행하겠습니다.
[출처]
- https://en.wikipedia.org/wiki/Terraform_(software)
- https://docs.toast.com/ko/Compute/Instance/ko/terraform-guide/
- https://velog.io/@unihit/TIL-Terraform-%EA%B8%B0%EB%B3%B8%EA%B5%AC%EC%84%B1
- https://www.44bits.io/ko/post/terraform_introduction_infrastrucute_as_code
'Cloud Native Solution > [IaC] terraform' 카테고리의 다른 글
[변수] 테라폼 Variable, Output, Data 개념과 예제 및 활용 방법 (0) | 2022.03.10 |
---|