Diagrama as code com ChatGPT - Parte 2

Image: Infra as Code

Ainda com uma ajudinha do nosso estagiário de luxo vamos fazer um pedido novo pra ele. Agora que já temos o IaC do diagrama, já temos a imagem do diagrama, só falta uma coisa para completar essa história, o que seria? … o IaC da infraestrutura. Nããããão!! Não é p-o-s-s-í-v-e-l, ele faz isso? Faz sim jovem, esse estagiário é “danadênho” vocês não tão ligados, vejamos como pedir isso para ele.

Infraestrutura 1

Prompt 1

Leia o código a seguir e gere um script Terraform para ser executado
"#! /usr/bin/python3   
from diagrams import Diagram, Cluster 
from diagrams.k8s compute import Pod 
from diagrams.k8s.network import Service 
from diagrams.onprem.database import MySQL 
from diagrams.onprem.queue import RabbitMQ  with 

Diagram("Arquitetura com Kubernetes, MySQL e RabbitMQ", show=False):
   with Cluster("Kubernetes Cluster"):
	    svc = Service("Service") 
			pod1 = Pod("Microserviço 1")
			pod2 = Pod("Microserviço 2") 
			pod3 = Pod("Microserviço 3")
			svc >> [pod1, pod2, pod3]
	db = MySQL("Banco de Dados MySQL")
	queue = RabbitMQ("Filas de Mensagens")
	# Relacionamentos
	[pod1, pod2, pod3] >> db
	[pod1, pod2, pod3] >> queue

Terraform 1

  1  provider "aws" {
  2  region = "us-east-1"  # Altere para a região desejada
  3}
  4
  5resource "aws_vpc" "main" {
  6  cidr_block = "10.0.0.0/16"
  7}
  8
  9resource "aws_subnet" "subnet" {
 10  vpc_id     = aws_vpc.main.id
 11  cidr_block = "10.0.1.0/24"
 12}
 13
 14resource "aws_eks_cluster" "k8s_cluster" {
 15  name     = "k8s-cluster"
 16  role_arn = aws_iam_role.eks_role.arn
 17
 18  vpc_config {
 19    subnet_ids = [aws_subnet.subnet.id]
 20  }
 21}
 22
 23resource "aws_eks_node_group" "k8s_nodes" {
 24  cluster_name    = aws_eks_cluster.k8s_cluster.name
 25  node_group_name = "k8s-nodes"
 26  node_role_arn   = aws_iam_role.eks_role.arn
 27  subnet_ids      = [aws_subnet.subnet.id]
 28
 29  scaling_config {
 30    desired_size = 3
 31    max_size     = 4
 32    min_size     = 1
 33  }
 34}
 35
 36resource "aws_iam_role" "eks_role" {
 37  name = "eks-role"
 38
 39  assume_role_policy = data.aws_iam_policy_document.eks_trust_policy.json
 40}
 41
 42data "aws_iam_policy_document" "eks_trust_policy" {
 43  statement {
 44    actions = ["sts:AssumeRole"]
 45
 46    principals {
 47      type        = "Service"
 48      identifiers = ["eks.amazonaws.com"]
 49    }
 50  }
 51}
 52
 53resource "aws_rds_instance" "mysql_db" {
 54  allocated_storage    = 20
 55  engine               = "mysql"
 56  instance_class       = "db.t3.micro"
 57  name                 = "mydatabase"
 58  username             = "admin"
 59  password             = "password"
 60  skip_final_snapshot  = true
 61  publicly_accessible  = false
 62  vpc_security_group_ids = [aws_security_group.rds_sg.id]
 63
 64  db_subnet_group_name = aws_db_subnet_group.main.id
 65}
 66
 67resource "aws_db_subnet_group" "main" {
 68  name       = "main"
 69  subnet_ids = [aws_subnet.subnet.id]
 70}
 71
 72resource "aws_security_group" "rds_sg" {
 73  vpc_id = aws_vpc.main.id
 74
 75  ingress {
 76    from_port   = 3306
 77    to_port     = 3306
 78    protocol    = "tcp"
 79    cidr_blocks = ["10.0.0.0/16"]
 80  }
 81
 82  egress {
 83    from_port   = 0
 84    to_port     = 0
 85    protocol    = "-1"
 86    cidr_blocks = ["0.0.0.0/0"]
 87  }
 88}
 89
 90resource "aws_mq_broker" "rabbitmq" {
 91  broker_name = "rabbitmq"
 92  engine_type = "RabbitMQ"
 93  engine_version = "3.8.26"
 94  instance_type = "mq.t3.micro"
 95  subnet_ids = [aws_subnet.subnet.id]
 96  security_groups = [aws_security_group.mq_sg.id]
 97  
 98  user {
 99    username = "admin"
100    password = "password"
101  }
102}
103
104resource "aws_security_group" "mq_sg" {
105  vpc_id = aws_vpc.main.id
106
107  ingress {
108    from_port   = 5672
109    to_port     = 5672
110    protocol    = "tcp"
111    cidr_blocks = ["10.0.0.0/16"]
112  }
113
114  egress {
115    from_port   = 0
116    to_port     = 0
117    protocol    = "-1"
118    cidr_blocks = ["0.0.0.0/0"]
119  }
120}

Infraestrutura 2

Prompt 2

crie um script TerraForm a partir deste código de diagrama

"#! /usr/bin/python3

from diagrams import Diagram, Cluster
from diagrams.aws.compute import EKS
from diagrams.aws.database import RDS, ElasticacheRedis
from diagrams.aws.integration import SQS
from diagrams.aws.storage import S3
from diagrams.aws.network import ELB

with Diagram("Arquitetura AWS com EKS, RDS, SQS, S3 e Redis", show=False):
    with Cluster("AWS Cloud"):
        lb = ELB("Load Balancer")

        with Cluster("EKS Cluster"):
            svc = EKS("Service")
            pod1 = EKS("Microservice 1")
            pod2 = EKS("Microservice 2")
            pod3 = EKS("Microservice 3")
            svc >> [pod1, pod2, pod3]

        db = RDS("MySQL (RDS)")
        queue = SQS("RabbitMQ (Amazon MQ)")
        cache = ElasticacheRedis("Redis (ElastiCache)")
        storage = S3("S3 Bucket")

        # Relacionamentos
        lb >> svc
        [pod1, pod2, pod3] >> db
        [pod1, pod2, pod3] >> queue
        [pod1, pod2, pod3] >> cache
        [pod1, pod2, pod3] >> storage
"

Terraform 2

  1provider "aws" {
  2  region = "us-east-1"  # Altere para a região desejada
  3}
  4
  5# VPC
  6resource "aws_vpc" "main" {
  7  cidr_block = "10.0.0.0/16"
  8}
  9
 10resource "aws_subnet" "subnet" {
 11  vpc_id     = aws_vpc.main.id
 12  cidr_block = "10.0.1.0/24"
 13}
 14
 15# Security Group
 16resource "aws_security_group" "eks_sg" {
 17  vpc_id = aws_vpc.main.id
 18
 19  ingress {
 20    from_port   = 0
 21    to_port     = 0
 22    protocol    = "-1"
 23    cidr_blocks = ["0.0.0.0/0"]
 24  }
 25
 26  egress {
 27    from_port   = 0
 28    to_port     = 0
 29    protocol    = "-1"
 30    cidr_blocks = ["0.0.0.0/0"]
 31  }
 32}
 33
 34# EKS Cluster
 35resource "aws_eks_cluster" "eks_cluster" {
 36  name     = "eks-cluster"
 37  role_arn = aws_iam_role.eks_role.arn
 38
 39  vpc_config {
 40    subnet_ids = [aws_subnet.subnet.id]
 41    security_group_ids = [aws_security_group.eks_sg.id]
 42  }
 43}
 44
 45resource "aws_eks_node_group" "eks_nodes" {
 46  cluster_name    = aws_eks_cluster.eks_cluster.name
 47  node_group_name = "eks-nodes"
 48  node_role_arn   = aws_iam_role.eks_role.arn
 49  subnet_ids      = [aws_subnet.subnet.id]
 50
 51  scaling_config {
 52    desired_size = 3
 53    max_size     = 5
 54    min_size     = 1
 55  }
 56}
 57
 58resource "aws_iam_role" "eks_role" {
 59  name = "eks-role"
 60
 61  assume_role_policy = data.aws_iam_policy_document.eks_trust_policy.json
 62}
 63
 64data "aws_iam_policy_document" "eks_trust_policy" {
 65  statement {
 66    actions = ["sts:AssumeRole"]
 67
 68    principals {
 69      type        = "Service"
 70      identifiers = ["eks.amazonaws.com"]
 71    }
 72  }
 73}
 74
 75# ELB
 76resource "aws_lb" "elb" {
 77  name               = "elb"
 78  internal           = false
 79  load_balancer_type = "application"
 80  security_groups    = [aws_security_group.eks_sg.id]
 81  subnets            = [aws_subnet.subnet.id]
 82}
 83
 84# RDS MySQL
 85resource "aws_db_instance" "rds_mysql" {
 86  allocated_storage    = 20
 87  engine               = "mysql"
 88  instance_class       = "db.t3.micro"
 89  name                 = "mydatabase"
 90  username             = "admin"
 91  password             = "password"
 92  skip_final_snapshot  = true
 93  publicly_accessible  = false
 94  vpc_security_group_ids = [aws_security_group.rds_sg.id]
 95
 96  db_subnet_group_name = aws_db_subnet_group.main.id
 97}
 98
 99resource "aws_db_subnet_group" "main" {
100  name       = "main"
101  subnet_ids = [aws_subnet.subnet.id]
102}
103
104resource "aws_security_group" "rds_sg" {
105  vpc_id = aws_vpc.main.id
106
107  ingress {
108    from_port   = 3306
109    to_port     = 3306
110    protocol    = "tcp"
111    cidr_blocks = ["10.0.0.0/16"]
112  }
113
114  egress {
115    from_port   = 0
116    to_port     = 0
117    protocol    = "-1"
118    cidr_blocks = ["0.0.0.0/0"]
119  }
120}
121
122# ElastiCache Redis
123resource "aws_elasticache_cluster" "redis" {
124  cluster_id           = "redis-cluster"
125  engine               = "redis"
126  node_type            = "cache.t3.micro"
127  num_cache_nodes      = 1
128  parameter_group_name = "default.redis5.0"
129  subnet_group_name    = aws_elasticache_subnet_group.main.name
130  security_group_ids   = [aws_security_group.redis_sg.id]
131}
132
133resource "aws_elasticache_subnet_group" "main" {
134  name       = "main"
135  subnet_ids = [aws_subnet.subnet.id]
136}
137
138resource "aws_security_group" "redis_sg" {
139  vpc_id = aws_vpc.main.id
140
141  ingress {
142    from_port   = 6379
143    to_port     = 6379
144    protocol    = "tcp"
145    cidr_blocks = ["10.0.0.0/16"]
146  }
147
148  egress {
149    from_port   = 0
150    to_port     = 0
151    protocol    = "-1"
152    cidr_blocks = ["0.0.0.0/0"]
153  }
154}
155
156# S3 Bucket
157resource "aws_s3_bucket" "bucket" {
158  bucket = "my-s3-bucket"
159  acl    = "private"
160}
161
162# SQS Queue
163resource "aws_sqs_queue" "queue" {
164  name = "my-queue"
165}
166
167# Outputs
168output "eks_cluster_name" {
169  value = aws_eks_cluster.eks_cluster.name
170}
171
172output "rds_endpoint" {
173  value = aws_db_instance.rds_mysql.endpoint
174}
175
176output "redis_endpoint" {
177  value = aws_elasticache_cluster.redis.cache_nodes.0.address
178}
179
180output "s3_bucket_name" {
181  value = aws_s3_bucket.bucket.bucket
182}
183
184output "sqs_queue_url" {
185  value = aws_sqs_queue.queue.url
186}
187
188output "elb_dns_name" {
189  value = aws_lb.elb.dns_name
190}

Conclusão

Mais uma vez o nosso estagiário de luxo fez um bom trabalho, do zero a gente não sai mais, ai você me pergunta, mas Léo dá pra usar esse código? Claro jovem, dá sim! Mas entenda, se me perguntarem se é um código profissional para ser usado na empresa que eu trabalho? Eu diria que não, por que falta um monte de coisas importantes para utilizar em uma empresa, não tá organizado para múltiplos produtos e projetos, não têm organizações de TAGs os componentes, não segrega variáveis do código, não divide por ambientes, entre outras deficiências, mas é usável sim.

A intenção aqui não é ter um código perfeito como saída do prompt, e sim criar código para ter um ponto de partida. O mais importante aqui é, você ganhou uma mãozinha do “estag” de luxo 😀, agora cabe a você estudar, seguir e evoluir o código e aprender com esse processo.

Abraços!

Vida longa e próspera a todos!!

Referências

MENTORIA

Curtiu o blog? Quer trocar uma ideia comigo sobre algum post?

Marca Aqui! É um papo gratuito oferecido para quem é leitor do blog, podemos falar de temas como: DevOps, SRE e carreira em TI.


Te convido a ver os outros posts do blog Infra-as-Code garanto que tem coisas legais lá!!


--- --- IMPORTANTE --- ---
As opiniões aqui expressas são pessoais e de responsabilidade única e exclusiva do autor, elas não refletem necessariamente a posição das empresas que eu trabalho(ei) e/ou presto(ei) serviço.