Привет всем!
Как у вас дела сегодня? Надеюсь, у вас все отлично. Мне очень хочется изучить Terraform, поэтому я пишу эту статью, чтобы задокументировать свой опыт и заметки.
Меня зовут Бервианто Лео Пратама. Я инженер-программист, который хочет узнать больше о мире DevOps. Я надеюсь, что вам понравится моя статья, а также дайте совет и прокомментируйте мой контент. Я не являюсь экспертом в мире DevOps, особенно IAC (Infrastructure as Code). Я считаю, что мне еще нужно узнать больше о DevOps.
Подготовка
Вам понадобится инструмент (Terraform), если вы хотите попробовать код. Вы можете скачать Terraform CLI здесь. В любом случае, моя версия Terraform CLI — 1.11.7.
Подготовьте пользователя
Поскольку я только изучаю и хочу узнать больше о Terraform и AWS. Пока что я использую наивысшие привилегии. Я использую AdministratorAccess. Пожалуйста, всегда используйте наименьшие привилегии для производственного использования.
Дополнительно
Вам может понадобиться использовать Terraform Cloud. Если вы используете Terraform Cloud, пожалуйста, воспользуйтесь этим руководством. Однако сейчас это не требуется.
Давайте начнем
TLDR о моей цели. В качестве сервиса я использую Nginx
. Кроме того, я использую Amazon ECS Fargate и ALB (Application Load Balancer). В общем, я хочу получить доступ к своим сервисам с помощью Load Balancer и использовать Nginx для выборки.
1. Подготовьте main.tf
и добавьте AWS в качестве провайдера.
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 3.0"
}
}
}
Примечание: Вы можете настроить состояние облака там. Когда я исследую, я использую локальное состояние. Но после этого я перешел на использование облачного состояния в моем репозитории Github.
2. Настройте нашего провайдера AWS
provider "aws" {
alias = "ap-southeast-1"
region = "ap-southeast-1"
}
Примечание: Пожалуйста, настройте желаемый регион. Я использую ap-southeast-1 (Сингапур).
3. Настройка сети
resource "aws_default_vpc" "my-personal-web" {
provider = aws.ap-southeast-1
tags = {
env = "dev"
}
}
resource "aws_default_subnet" "my-personal-web" {
provider = aws.ap-southeast-1
availability_zone = "ap-southeast-1a"
tags = {
env = "dev"
}
}
resource "aws_default_subnet" "my-personal-web-1" {
provider = aws.ap-southeast-1
availability_zone = "ap-southeast-1b"
tags = {
env = "dev"
}
}
resource "aws_security_group" "my-personal-web" {
provider = aws.ap-southeast-1
name = "allow_http"
description = "Allow HTTP inbound traffic"
vpc_id = aws_default_vpc.my-personal-web.id
ingress {
description = "Allow HTTP for all"
from_port = 80
to_port = 80
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
}
Примечание: Я использую vpc & подсеть по умолчанию и настроил новую группу безопасности, чтобы открыть только порт 80. Поскольку я буду использовать nginx
в качестве службы. Вам нужно будет правильно настроить vpc & subnet для производственного использования.
4. Настройка балансировщика нагрузки
resource "aws_lb" "my-personal-web" {
provider = aws.ap-southeast-1
name = "my-personal-web-lb-tf"
internal = false
load_balancer_type = "application"
security_groups = [aws_security_group.my-personal-web.id]
subnets = [aws_default_subnet.my-personal-web.id, aws_default_subnet.my-personal-web-1.id]
tags = {
env = "dev"
}
}
resource "aws_lb_target_group" "my-personal-web" {
provider = aws.ap-southeast-1
name = "tf-my-personal-web-lb-tg"
port = 80
protocol = "HTTP"
target_type = "ip"
vpc_id = aws_default_vpc.my-personal-web.id
}
resource "aws_lb_listener" "my-personal-web" {
provider = aws.ap-southeast-1
load_balancer_arn = aws_lb.my-personal-web.arn
port = "80"
protocol = "HTTP"
default_action {
type = "forward"
target_group_arn = aws_lb_target_group.my-personal-web.arn
}
}
Примечание: Я просто использую порт 80. Возможно, для производственного использования вам понадобится 443.
5. Настройте Amazon ECS
resource "aws_ecs_cluster" "my-personal-web" {
provider = aws.ap-southeast-1
name = "my-personal-web-api-cluster"
}
resource "aws_ecs_cluster_capacity_providers" "my-personal-web" {
provider = aws.ap-southeast-1
cluster_name = aws_ecs_cluster.my-personal-web.name
capacity_providers = ["FARGATE"]
}
resource "aws_ecs_task_definition" "my-personal-web" {
provider = aws.ap-southeast-1
family = "service"
requires_compatibilities = ["FARGATE"]
network_mode = "awsvpc"
cpu = 1024
memory = 2048
container_definitions = jsonencode([
{
name = "my-personal-web-api"
image = "nginx"
cpu = 1024
memory = 2048
essential = true
portMappings = [
{
containerPort = 80
hostPort = 80
}
]
}
])
}
resource "aws_ecs_service" "my-personal-web" {
provider = aws.ap-southeast-1
name = "my-personal-web"
cluster = aws_ecs_cluster.my-personal-web.id
task_definition = aws_ecs_task_definition.my-personal-web.arn
desired_count = 2
launch_type = "FARGATE"
network_configuration {
subnets = [aws_default_subnet.my-personal-web.id, aws_default_subnet.my-personal-web-1.id]
security_groups = [aws_security_group.my-personal-web.id]
assign_public_ip = true
}
load_balancer {
target_group_arn = aws_lb_target_group.my-personal-web.arn
container_name = "my-personal-web-api"
container_port = 80
}
tags = {
env = "dev"
}
}
Полный код
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 3.0"
}
}
}
# Configure the AWS Provider
provider "aws" {
alias = "ap-southeast-1"
region = "ap-southeast-1"
}
resource "aws_default_vpc" "my-personal-web" {
provider = aws.ap-southeast-1
tags = {
env = "dev"
}
}
resource "aws_default_subnet" "my-personal-web" {
provider = aws.ap-southeast-1
availability_zone = "ap-southeast-1a"
tags = {
env = "dev"
}
}
resource "aws_default_subnet" "my-personal-web-1" {
provider = aws.ap-southeast-1
availability_zone = "ap-southeast-1b"
tags = {
env = "dev"
}
}
resource "aws_security_group" "my-personal-web" {
provider = aws.ap-southeast-1
name = "allow_http"
description = "Allow HTTP inbound traffic"
vpc_id = aws_default_vpc.my-personal-web.id
ingress {
description = "Allow HTTP for all"
from_port = 80
to_port = 80
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
}
resource "aws_lb" "my-personal-web" {
provider = aws.ap-southeast-1
name = "my-personal-web-lb-tf"
internal = false
load_balancer_type = "application"
security_groups = [aws_security_group.my-personal-web.id]
subnets = [aws_default_subnet.my-personal-web.id, aws_default_subnet.my-personal-web-1.id]
tags = {
env = "dev"
}
}
resource "aws_lb_target_group" "my-personal-web" {
provider = aws.ap-southeast-1
name = "tf-my-personal-web-lb-tg"
port = 80
protocol = "HTTP"
target_type = "ip"
vpc_id = aws_default_vpc.my-personal-web.id
}
resource "aws_lb_listener" "my-personal-web" {
provider = aws.ap-southeast-1
load_balancer_arn = aws_lb.my-personal-web.arn
port = "80"
protocol = "HTTP"
default_action {
type = "forward"
target_group_arn = aws_lb_target_group.my-personal-web.arn
}
}
resource "aws_ecs_cluster" "my-personal-web" {
provider = aws.ap-southeast-1
name = "my-personal-web-api-cluster"
}
resource "aws_ecs_cluster_capacity_providers" "my-personal-web" {
provider = aws.ap-southeast-1
cluster_name = aws_ecs_cluster.my-personal-web.name
capacity_providers = ["FARGATE"]
}
resource "aws_ecs_task_definition" "my-personal-web" {
provider = aws.ap-southeast-1
family = "service"
requires_compatibilities = ["FARGATE"]
network_mode = "awsvpc"
cpu = 1024
memory = 2048
container_definitions = jsonencode([
{
name = "my-personal-web-api"
image = "nginx"
cpu = 1024
memory = 2048
essential = true
portMappings = [
{
containerPort = 80
hostPort = 80
}
]
}
])
}
resource "aws_ecs_service" "my-personal-web" {
provider = aws.ap-southeast-1
name = "my-personal-web"
cluster = aws_ecs_cluster.my-personal-web.id
task_definition = aws_ecs_task_definition.my-personal-web.arn
desired_count = 2
launch_type = "FARGATE"
network_configuration {
subnets = [aws_default_subnet.my-personal-web.id, aws_default_subnet.my-personal-web-1.id]
security_groups = [aws_security_group.my-personal-web.id]
assign_public_ip = true
}
load_balancer {
target_group_arn = aws_lb_target_group.my-personal-web.arn
container_name = "my-personal-web-api"
container_port = 80
}
tags = {
env = "dev"
}
}
berviantoleo / my-aws
Мой AWS IAC
Мой AWS IAC (Инфраструктура как код)
Мой AWS IAC.
Модуль ECS является частью поста
ЛИЦЕНЗИЯ
MIT
Давайте обеспечим его!
- Запустите
terraform init
. - Запустите
terraform plan
. Вы можете проверить, что изменилось на этом шаге. - Запустите
terraform apply
. Введитеyes
и Enter. - Подождите, пока не завершится развертывание всех ресурсов. Это может занять много времени.
- После завершения и успешного завершения попробуйте получить доступ к нему с помощью вашего публичного балансировщика нагрузки. В качестве примера, вот мой.
Спасибо
Спасибо, что прочитали. Я очень ценю, когда вы читаете эту длинную (потому что код) статью.