return 값과 같음
https://www.terraform.io/language/values/outputs
https://learn.hashicorp.com/tutorials/terraform/aws-outputs?in=terraform/aws-get-started
output "instance_id" {
description = "ID of the EC2 instance"
value = aws_instance.app_server.id
}
output "instance_public_ip" {
description = "Public IP address of the EC2 instance"
value = aws_instance.app_server.public_ip
}
블록추가
리소스가 수십개가 되었을 때, EC2 인스턴스에 Eip부여 Eip가 몇번인지 알고 싶을때
apply 한 이 후에 쉽게 확인할 수 있도록
terrafrom output
value 값은 테라폼 쇼에서 볼 수 있는 특정 속성
sensitive
= true 직접적으로 보이지 않음
함수 내에서 사용하는 지역 변수
locals {
service_name = "forum"
owner = "Community Team"
}
resource "aws_instance" "example" {
# ...
tags = local.service_name
변수 정의
# variable.tf
variable "project_name" {
descriptioin = "Projdect Name"
type = string
default = "My first Projdect"
}
variable "project_environment" {
description = "Project Environment"
type = string
default = "Local Develoment"
}
$ code local.tf
locals {
common_tags = {
project_name=var.project_name
project_env=var.project_environment
}
}
main.tf
tags = local.common_tags
tag의 관한내용
태그는 맵이들어감
공통 태그를 붙일 수 있는 장점
프로비저너를 보기전에 사용자데이터를 살펴보고 넘어가자
Userdata
aws_instance 항목
user_data
resource "aws_instance" "app_web" {
...
# 입력값이 멀티라인 이므로
user_data = <<-EOF
#!/bin/sh
yum -y install httpd
systemctl enable --now httpd
echo "hello world" > /var/www/html/index.html
EOF
...
}
EOF
리눅스 시스템에서
vi귀찮거나 멀티라인 작업할때 하는거[vagrant@controller 01]$ cat <<EOF > a.txt a b c d EOF [vagrant@controller 01]$ cat a.txt a b c d
꼭
EOF
? -> no 처음과 끝만 맞으면 됨 EOF 대신 ABC 써도 됨
+ user_data = "0d55d007af9af29d11ac99333a0050b14927d6df"
user_data 값이 이상한데❓
base64로 인코딩했기때문에 -> 명령어가 중간에서 잘못실행되는 것을 방지하기 위해서
user_data.sh
#!/bin/sh
yum -y install httpd
systemctl enable --now httpd
echo "hello world" > /var/www/html/index.html
main.tf
에서 user_data = file("user_data.sh")
로 선언
terraform은 사용자가 함수로 직접 만들 수는 없음
security_group.tf
resource "aws_sercurity_group" "app_server_sg" {
name= "Allow SSh & http"
ingress {
from_port = 80
to_port = 80
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
egress {
from_port = 0
to_port = 0
protocol = "-1" # -1은 모든 프로토콜을 의미
cidr_blocks = ["0.0.0.0/0"]
}
tags = local.common.tags
}
resource "aws_instance" "app_server" {
...
vpc_security_group_ids = [aws_secruity_group.app_server_sg.id] # list of
...
}
로컬이나 원격머신에서 명령어를 실행할 수 있도록 하는 기능
변수를 참조할 땐 ${ name }
의 형식으로 참조
self
는 리소스 자신 -> 자바의 [this](https://www.terraform.io/language/resources/provisioners/syntax#the-self-object)
와 비슷
resource "aws_instance" "web" {
# ...
provisioner "local-exec" {
command = "echo The server's IP address is ${self.private_ip}"
}
}
resource "aws_instance" "web" {
# ...
# Copies the myapp.conf file to /etc/myapp.conf
provisioner "file" {
source = "conf/myapp.conf"
destination = "/etc/myapp.conf"
}
}
resource "aws_instance" "web" {
# ...
provisioner "local-exec" {
command = "echo ${self.private_ip} >> private_ips.txt"
}
}
resource "aws_instance" "web" {
# ...
# Establishes connection to be used by all
# generic remote provisioners (i.e. file/remote-exec)
connection {
type = "ssh"
user = "root"
password = var.root_password
host = self.public_ip
}
provisioner "remote-exec" {
inline = [
"puppet apply",
"consul join ${aws_instance.web.private_ip}",
]
}
}
아래 두 프로비저너는 SSH 연결이 필요함
provisioner "file" {
connection {
type = "ssh"
user = "root"
password = "${var.root_password}"
host = "${var.host}"
}
}
provisioner "file" {
}
provisioner "file" {
}
connection {
}
ssh 연결 시 필요한 키를 리소스에 정의
resource "aws_key_pair" "deployer" {
key_name = "deployer-key"
public_key = file("/home/vagrant/.ssh/id_rsa.pub")
}
resosurce "aws_instance" "app_server" {
connection {
user = "ec2-user"
host = self.public_ip
private_key = file("/home/vagrant/.ssh/id_rsa")
timeout = "1m" # 타임아웃 1분지나서까지 안되면 실패
}
provisioner "file" {
source = "index.html"
destination = "/var/www/html/index.html"
}
key_name = aws_key_pair.deployer.key_name
"
오염되다, 문제있다, 오류
리소스를 생성/변경 하다가 오류가 생기면, 해당 리소스를 Taint 처리
terraform taint <RESOURCE>
terraform untaint <RESOURCE>
Taint 처리된 리소스는 다음 작업시 무조건 재생성
유저데이터를 사용할 수 있다면 유저데이터 사용
프로비저너는 마지막 수단
유저데이터와 프로비저너를 동시에 쓰는경우
유저데이터 - httpd 패키지설치
프로비저너 - file 프로비저너로 index.html 복사
-> 프로비저너가 먼저 실행되어 httpd패키지가 설치되지 않아 에러
provisioner "file" {
source = "index.html"
destination = "/tmp/html/index.html"
}
provisioner "remote_exec" {
inline = [
"sudo yum install -y",
"sudo systemctl enable --now httpd",
"sudo cp /tmp/html/index.html /var/www/html/index.html"
]
유저데이터를 사용하지 않고 구현
connection {
user = "ec2-user"
host = self.public_ip
private_key = file("/home/vagrant/.ssh/id_rsa")
timeout = "1m"
}
provisioner "local-exec" {
command = "echo ${self.public_ip} ansible_user=ec2-user > inven.ini"
}
provisioner "local-exec" {
command = "ansible-playbook -i inven.ini web_install.yaml -b"
}
ansible -c Connection 기본값이 ssh -> 키 기반인증을 하려함 -> 자기 자신도 인증이 필요합
ssh-copy-id localhost로 키를 복사하거나
->-c local
옵션으로 로 하면됨 -> ssh를 쓰지않고 로컬 접속을 하겠다
앤서블의 역할과 비슷
자주사용되는 리소스 들의 모음
module "myvpc" {
source =
...입력 변수...
}
resource "aws_instance" "web" {
subnet_id = module.myvpc.<출력값>
}
모듈을 사용하여 코드를 짠 경우 초기화를 진행시켜 모듈을 다운받아야 함
terraform init
aws의 vpc를 생성하기 위한 모듈
module "vpc" {
source = "terraform-aws-modules/vpc/aws"
name = "my-vpc"
cidr = "10.0.0.0/16"
azs = ["eu-west-1a", "eu-west-1b", "eu-west-1c"]
private_subnets = ["10.0.1.0/24", "10.0.2.0/24", "10.0.3.0/24"]
public_subnets = ["10.0.101.0/24", "10.0.102.0/24", "10.0.103.0/24"]
enable_nat_gateway = true
enable_vpn_gateway = true
tags = {
Terraform = "true"
Environment = "dev"
}
}
보안그룹이 같은 VPC에 있는지 확인할 것