Terraform Provisioner
→ terraform에서 제공해주는 syntex라고 보면 된다. 이는 3개의 문법이 존재한다.
file provisoner
- 이는 로컬에서 remote를 통해 파일을 복사하는 행위를 말하는 것이다.
local_exec provisioner
- 로컬에서 명령을 수행하는 문법이다.
remote_exec provisioner
- remote 환경에서 명령을 수행하는 문법이다.
예시 - Userdata
###################################################
# Userdata
###################################################
resource "aws_instance" "userdata" {
ami = data.aws_ami.ubuntu.image_id
instance_type = "t2.micro"
key_name = "fastcampus"
user_data = <<EOT
#!/bin/bash
sudo apt-get update
sudo apt-get install -y nginx
EOT
vpc_security_group_ids = [
module.security_group.id,
]
tags = {
Name = "fastcampus-userdata"
}
}
userdata부분은
user_data = <<EOT
부분 아래에 보면 script를 작성하는 란이 있다.
key_name
이란 ssh에 사용되는 key name이라고 보면 된다.
→ 이는 ec2페이지, 키페어 페이지에 해당하는 이름이라고 생각하면 된다.
###################################################
# Provisioner - in EC2
###################################################
resource "aws_instance" "provisioner" {
ami = data.aws_ami.ubuntu.image_id
instance_type = "t2.micro"
key_name = "fastcampus"
vpc_security_group_ids = [
module.security_group.id,
]
tags = {
Name = "fastcampus-provisioner"
}
provisioner "remote-exec" {
inline = [
"sudo apt-get update",
"sudo apt-get install -y nginx",
]
connection {
type = "ssh"
user = "ubuntu"
host = self.public_ip
# 해당 필자가 ssh-agent를 사용하고 있기 때문에 별도의 password가 필요 없는것
# 혹여라도 사용하지 않는다면 paaword를 기입하도록 하자
}
}
}
provisioner에서는 특히 “remote-exec”
부분에서는 만들어진 ec2 머신에서 어떤 script를 바로 실행할 것인지에 대해서 적어도 된다.
provisioner에서 remote-exec에서 inline이라는 script로 생성하는 방법도 있으며 이외에도
script, scripts 2가지 방법이 있다.
inline
- inline은 명령어 리스트를 나열해서 명령어를 수행한다고 보면 된다.
script
- script파일을 업로드 해서 실행한다.
scripts
- 여러 script파일을 업로드 해서 실행한다고 보면 된다.
Null resource
AWS VPC OpenVPN 구성
현재의 실습 파일의 구성은 아래와 같다.
Network
- VPC와 Subnet을 구성하는 요소들을 제공하는 타입
ec2-instance
- openvpn과 사설 대역에 올라갈 private ec2에 구성되는 workspace이다.
Network
terraform.tf
terraform {
backend "remote" {
hostname = "app.terraform.io"
organization = "Test_Cloud_Devdubu"
workspaces {
name = "terraform-lab-network"
}
}
}
해당 부분에서 organization에서 본인의 terraform cloude의 organization으로 이름을 변경해주면 된다.
그리고 terraform cloud에서 새로 만들어진 workspace 설정에서 remote→local로 변경해주면 된다.
ec2-instance
terraform.tf
data "aws_ami" "ubuntu" {
most_recent = true
filter {
name = "name"
values = ["ubuntu/images/hvm-ssd/ubuntu-focal-20.04-amd64-server-*"]
}
filter {
name = "virtualization-type"
values = ["hvm"]
}
owners = ["099720109477"] # Canonical
}
# *****************************************************************************
# 키 페어 이름 바꿔야하는 곳
# *****************************************************************************
resource "aws_instance" "private" {
ami = data.aws_ami.ubuntu.image_id
instance_type = "t2.micro"
subnet_id = local.subnet_groups["private"].ids[0]
key_name = "JmServer"
vpc_security_group_ids = [
module.sg__ssh.id,
]
tags = {
Name = "${local.vpc.name}-private"
}
}
locals {
openvpn_userdata = templatefile("${path.module}/files/openvpn-userdata.sh", {
vpc_cidr = local.vpc.cidr_block
public_ip = aws_eip.openvpn.public_ip
})
common_tags = {
"Project" = "openvpn"
}
}
# *****************************************************************************
# 키 페어 이름 바꿔야하는 곳
# *****************************************************************************
resource "aws_instance" "openvpn" {
ami = data.aws_ami.ubuntu.image_id
instance_type = "t2.micro"
subnet_id = local.subnet_groups["public"].ids[0]
key_name = "JmServer"
user_data = local.openvpn_userdata
associate_public_ip_address = false
vpc_security_group_ids = [
module.sg__ssh.id,
module.sg__openvpn.id,
]
tags = {
Name = "${local.vpc.name}-openvpn"
}
}
context: {}
remote_states:
"network":
organization: "Test_Cloud_Devdubu" # 교체 해야하는 부분
workspace: "terraform-lab-network"
templatefile
- templatefile은 두가지 인자를 받는다.
- 파일 경로
- context값 → context값을 랜더링 하여 파일에 넣는다.
docker 설치 shell script
#!/bin/bash
sudo apt-get update
sudo apt-get install -y \
apt-transport-https \
ca-certificates \
curl \
gnupg \
lsb-release
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu \
$(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt-get update
sudo apt-get install -y docker-ce docker-ce-cli containerd.io
usermod -aG docker ubuntu
## Run openvpn-ldap-otp container
docker run \
--name openvpn \
--volume openvpn-data:/etc/openvpn \
--detach=true \
-p 1194:1194/udp \
--cap-add=NET_ADMIN \
-e "OVPN_SERVER_CN=${public_ip}" \
-e "OVPN_ENABLE_COMPRESSION=false" \
-e "OVPN_NETWORK=172.22.16.0 255.255.240.0" \
-e "OVPN_ROUTES=172.22.16.0 255.255.240.0, ${split("/", vpc_cidr)[0]} ${cidrnetmask(vpc_cidr)}" \
-e "OVPN_NAT=true" \
-e "OVPN_DNS_SERVERS=${cidrhost(vpc_cidr, 2)}" \
-e "USE_CLIENT_CERTIFICATE=true" \
wheelybird/openvpn-ldap-otp:v1.4
## Wait to ready OpenVPN Server
until echo "$(docker exec openvpn show-client-config)" | grep -q "END PRIVATE KEY" ;
do
sleep 1
echo "working..."
done
## Generate OpenVPN client configuration file
docker exec openvpn show-client-config > fastcampus.ovpn
→ docker 실행 명령어를 통해서 openvpn을 실행한다.
→ 1194 UDP 포트로 해당 컨테이너를 실행
→ 위에 templatefile에 랜더링한 값을 주입하는 칸이다 ${ }
→ vpc cidr을 앞부분으로 가져오고, 뒤에는 netmask 값을 가져왔다.
→ cidr 명령어는 vpc_cidr에서 2번째 ip를 가져오는 것이다.
→ CIDR : 10.222.0.0/24의 두번째 IP는 10.222.0.2이다. → 이는 내부 DNS 서버 역할을 한다.
→ 왼쪽은 docker openvpn이 실행될때 까지 기다린 후에
→ 만약 openvpn이 실행됐다면, fastcampus.ovpn을 생성하게 된다.
eip.tf
resource "aws_eip" "openvpn" {
tags = merge(
{
"Name" = "${local.vpc.name}-openvpn"
},
local.common_tags,
)
}
resource "aws_eip_association" "openvpn" {
instance_id = aws_instance.openvpn.id
allocation_id = aws_eip.openvpn.id
}
- 보통의 경우 ec2에서는 인스턴스를 종료하게 된다면, public ip는 유지가 되지 않고 갱신된다.
- 하지만, 이는 중요 도메인에 있어서는 그리 좋은 선택은 아니다.
- 그렇기 때문에, eip를 설정해놓게 되면, 공인 ip가 유지가 가능하기 때문에,
- ec2를 지속적으로 재생성해도 같은 ip를 유지한다.
Ec2 생성 후
ssh ubuntu@[publicIP]
sudo su
cat /var/log/cloud-init-output.log
docker ps
openvpn client 설치
맥에서는 간단하게 brew를 이용해서 설치가 가능하다.
brew install tunnelblick
openclient를 설치한 후에는 fastcampus.ovpn 파일을 해당 디렉토리에 만든다.
후에 fastcampus.ovpn을 더블클릭 후에 암호를 입력하게 된다면 상단에 이러한 마크가 뜨게 된다.
후에 Connection fastcampus를 누르게 된다면, private ip도 내 컴퓨터에서 접근이 가능해진다.
해당 명령어는 private dns에 쿼리를 날려주기 때문에 원래는 반응이 없어야하지만, 내부망 접속(open vpn)을 통해서 이를 받아올 수 있다.
'DevOps > Terraform' 카테고리의 다른 글
Terraform AWS Provider (0) | 2023.08.05 |
---|---|
Terraform Cloud (0) | 2023.08.05 |
TerraForm WorkSpace && Terraform Local Provider (0) | 2023.08.05 |
Terraform State (0) | 2023.08.05 |
HCL 문법 (0) | 2023.08.05 |