인프런 송주영님 강의를 듣고 나름대로 요약한 내용 입니다.
Terraform
- Terraform이란 서버 인프라를 코드로서 관리하는 프로그램이다.
- 실습은 AWS 리소스를 Terraform 코드로 작성하여 서버 인프라를 구성 하는 내용 입니다.
내 실습 환경
MacOSAWS CLI 2Terraform
1
2
3
4
5 | curl -sO https://releases.hashicorp.com/terraform/0.12.24/terraform_0.12.24_darwin_amd64.zip
unzip terraform_0.12.24_darwin_amd64.zip
mv terraform /usr/local/bin
terraform --version
Terraform v0.12.24
|
1
2
3 | brew install terraform
terraform --version
Terraform v0.12.24
|
Terraform 기본 개념
-
provider : 인프라 제공자. (ex. AWS, AZURE)
- resource : 실제로 생성할 provider의 인프라 자원. (ex. aws_lb)
- state: terraform 실행으로 생성된 인프라의 state.
-
output : terraform으로 state 파일을 생서하여 저장하는 것을 의미.
-
backend : terraform 실행으로 생성된 state를 저장할 공간. (ex. S3)
- module : 공통적으로 사용할 인프라 코드 묶음.
- remote state : 다른 경로의 state를 참조하는 것을 의미.
Terraform 기본 명령어
- init : 해당 폴더를 terraform base로 초기화
- plan : 작성한 코드로 인프라가 어떻게 변경될지 미리 보기
- apply : 작성한 코드 실행
- import
- state
- destroy
모든 실행은 아래 순서로 진행
1. 해당 폴더를 terraform base로 초기화 하고
$> terraform init
2. 코드 작성 후
3. 코드의 plan을 미리보기
$> terraform plan
4. 코드 적용
$> terraform apply
실습 1
- VPC 생성
- Subnet 구성
- Internet Gateway 생성
- Route Table 구성
- Private Subnet
- NAT Gateway 구성
vpc.tf
cidr_block 필수
1
2
3
4
5
6
7
8
9
10 | provider "aws" {
region = "ap-northeast-2"
}
resource "aws_vpc" "main" {
cidr_block = "10.0.0.0/16"
tags = {
Name = "terraform-101"
}
}
|
subnet.tf
cidr_block은 위에 생성한 vpc에 속한 IP 여야 한다.
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
32
33 | provider "aws" {
region = "ap-northeast-2"
}
resource "aws_vpc" "main" {
cidr_block = "10.0.0.0/16"
tags = {
Name = "terraform-101"
}
}
resource "aws_subnet" "first_subnet" {
vpc_id = aws_vpc.main.id
cidr_block = "10.0.1.0/24"
availability_zone = "ap-northeast-2a"
tags = {
Name = "101subnet-1"
}
}
resource "aws_subnet" "second_subnet" {
vpc_id = aws_vpc.main.id
cidr_block = "10.0.2.0/24"
availability_zone = "ap-northeast-2b"
tags = {
Name = "101subnet-2"
}
}
|
internet_gateway.tf
1
2
3
4
5
6
7 | resource "aws_internet_gateway" "igw" {
vpc_id = aws_vpc.main.id
tags = {
Name = "main"
}
}
|
route.tf
생성된 aws_route_table은 aws_route_table_association으로 연결 한다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 | resource "aws_route_table" "route_table" {
vpc_id = aws_vpc.main.id
tags = {
Name = "main"
}
}
resource "aws_route_table_association" "route_talbe_association_1" {
subnet_id = aws_subnet.first_subnet.id
route_table_id = aws_route_table.route_table.id
}
resource "aws_route_table_association" "route_talbe_association_2" {
subnet_id = aws_subnet.second_subnet.id
route_talbe_id = aws_route_table.route_table.id
}
|
private_subnet.tf
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 | resource "aws_subnet" "first_private_subnet" {
vpc_id = aws_vpc.main.id
cidr_block = "10.0.3.0/24"
availability_zone = "ap-northeast-2a"
tags = {
Name = "101subnet-private-1"
}
}
resource "aws_subnet" "second_private_subnet" {
vpc_id = aws_vpc.main.id
cidr_block = "10.0.4.0/24"
availability_zone = "ap-northeast-2b"
tags = {
Name = "101subnet-private-2"
}
}
|
nat.tf
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
32
33
34
35
36 | resource "aws_eip" "nat_1" {
vpc = true
lifecycle {
create_before_destroy = true
}
}
resource "aws_eip" "nat_2" {
vpc = true
lifecycle {
create_before_destroy = true
}
}
resource "aws_nat_gateway" "nat_gateway_1" {
allocation_id = aws_eip.nat_1.id
# Private subnet이 아니라 public subnet을 연결하셔야 합니다.
subnet_id = aws_subnet.first_subnet.id
tags = {
Name = "NAT-GW-1"
}
}
resource "aws_nat_gateway" "nat_gateway_2" {
allocation_id = aws_eip.nat_2.id
subnet_id = aws_subnet.second_subnet.id
tags = {
Name = "NAT-GW-2"
}
}
|
nat_association.tf
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
32
33
34
35
36
37 | resource "aws_route_table" "route_table_private_1" {
vpc_id = aws_vpc.main.id
tags = {
Name = "main-private-1"
}
}
resource "aws_route_table" "route_table_private_2" {
vpc_id = aws_vpc.main.id
tags = {
Name = "main-private-2"
}
}
resource "aws_route_table_association" "route_table_association_private_1" {
subnet_id = aws_subnet.first_private_subnet.id
route_table_id = aws_route_table.route_table_private_1.id
}
resource "aws_route_table_association" "route_table_association_private_2" {
subnet_id = aws_subnet.second_private_subnet.id
route_table_id = aws_route_table.route_table_private_2.id
}
resource "aws_route" "private_nat_1" {
route_table_id = aws_route_table.route_table_private_1.id
destination_cidr_block = "0.0.0.0/0"
nat_gateway_id = aws_nat_gateway.nat_gateway_1.id
}
resource "aws_route" "private_nat_2" {
route_table_id = aws_route_table.route_table_private_2.id
destination_cidr_block = "0.0.0.0/0"
nat_gateway_id = aws_nat_gateway.nat_gateway_2.id
}
|
실습 2
s3.tf
1
2
3
4
5
6
7
8
9
10
11 | provider "aws" {
region = "ap-northeast-2"
}
resource "aws_s3_bucket" "main" {
bucket = "devopsart-terraform-101"
tags = {
Name = "devopsart-terraform-101"
}
}
|
실습 3
- IAM User 생성
- IAM Group 생성
- User를 Group에 등록
- IAM Role 생성
- IAM Policy 생성
user.tf
1
2
3
4
5
6
7
| provider "aws" {
region = "ap-northeast-2"
}
resource "aws_iam_user" "gildong_hong" {
name = "gildong.hong"
}
|
group.tf
1
2
3
4
5
6
7 | provider "aws" {
region = "ap-northeast-2"
}
resource "aws_iam_group" "devops_group" {
name = "devops"
}
|
register.tf
1
2
3
4
5
6
7
8
9 | resource "aws_iam_group_membership" "devops" {
name = aws_iam_group.devops_group.name
users = [
aws_iam_user.gildong_hong.name
]
group = aws_iam_group.devops_group.name
}
|
s3_role.tf
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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47 | resource "aws_iam_role" "hello" {
name = "hello-iam-role"
path = "/"
assume_role_policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "",
"Effect": "Allow",
"Principal": {
"Service": "ec2.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
EOF
}
resource "aws_iam_role_policy" "hello_s3" {
name = "hello-s3-download"
role = aws_iam_role.hello.id
policy = <<EOF
{
"Statement": [
{
"Sid": "AllowAppArtifactsReadAccess",
"Action": [
"s3:GetObject"
],
"Resource": [
"*"
],
"Effect": "Allow"
}
]
}
EOF
}
resource "aws_iam_instance_profile" "hello" {
name = "hello-profile"
role = aws_iam_role.hello.name
}
|
policy.tf
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 | resource "aws_iam_user" "gildong_hong" {
name = "gildong.hong"
}
resource "aws_iam_user_policy" "art_devops_black" {
name = "super-admin"
user = aws_iam_user.gildong_hong.name
policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"*"
],
"Resource": [
"*"
]
}
]
}
EOF
}
|
Terraform 고도화
1. Backend 활용하기
2. Variable 활용하기
3. Function 활용하기
4. GitHub로 협업하기
댓글
댓글 쓰기