diff --git a/.github/workflows/destroy.yaml b/.github/workflows/destroy.yaml new file mode 100644 index 0000000..2b186b5 --- /dev/null +++ b/.github/workflows/destroy.yaml @@ -0,0 +1,27 @@ +name: "Terraform destroy" + +on: + workflow_dispatch: + +jobs: + terraform: + name: "Terraform destroy" + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v3 + + - name: Configurar as credenciais da AWS + uses: aws-actions/configure-aws-credentials@v1 + with: + aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} + aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} + aws-region: us-east-1 + + - name: Terraform Init + working-directory: ./src + run: terraform init -backend-config="bucket=${{ secrets.AWS_BUCKET_NAME }}" -backend-config="key=${{ secrets.AWS_BUCKET_FILE }}" + + - name: Terraform destroy + working-directory: ./src + run: terraform destroy --auto-approve diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml new file mode 100644 index 0000000..5b453b8 --- /dev/null +++ b/.github/workflows/main.yml @@ -0,0 +1,30 @@ +name: "Terraform" + +on: + push: + branches: ["main"] + paths: ["src/**"] + workflow_dispatch: + +jobs: + terraform: + name: "Terraform Apply" + runs-on: "ubuntu-latest" + steps: + - name: "Configure AWS Credentials" + uses: aws-actions/configure-aws-credentials@v4 + with: + aws-region: us-east-1 + aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} + aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} + + - name: Checkout + uses: actions/checkout@v4 + + - name: Terraform init + working-directory: ./src + run: terraform init -backend-config="bucket=${{ secrets.AWS_BUCKET_NAME }}" -backend-config="key=${{ secrets.AWS_BUCKET_FILE }}" + + - name: Terraform Apply + working-directory: ./src + run: terraform apply --auto-approve \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..586a6cb --- /dev/null +++ b/README.md @@ -0,0 +1,66 @@ +# Automação com Terraform + +## Objetivo do projeto + +O objetivo é automatizar o processo de criação e manutenção do ambiente para execução dos projetos de Software da Mr. Fusion Solutions. + +## Premissas do Projeto + +Para o desenvolvimento do projeto, foram levantadas as seguintes premissas: + ++ Utilizar o Terraform como ferramenta de infraestrutura como código. ++ O cluster Kubernetes deve ser criado utilizando o serviço Elastic Kubernetes Service (EKS) da AWS. ++ O projeto deve ser o mais simples e reaproveitável possível. ++ Toda vez que houver alteração no código Terraform na branch main do repositório, a pipeline deve ser executada. ++ Só vai haver um ambiente Kubernetes (os ambientes de desenvolvimento, homologação e produção serão separados por namespace). + +## Tecnologias utilizadas no projeto + ++ [AWS](https://aws.amazon.com) + + [S3](https://aws.amazon.com/s3) + + [EKS](https://aws.amazon.com/eks) ++ [AWS CLI](https://aws.amazon.com/cli/) ++ [Terraform](https://www.terraform.io) + + [AWS Provider](https://registry.terraform.io/providers/hashicorp/aws) + + [AWS VPC Terraform module](https://registry.terraform.io/modules/terraform-aws-modules/vpc/aws) + + [AWS EKS Terraform module](https://registry.terraform.io/modules/terraform-aws-modules/eks/aws) ++ [GitHub](https://github.com) + + [GitHub Actions](https://github.com/features/actions) + +## Motivações para o uso de cada tecnologia + ++ **EKS** - Requisito do projeto. ++ **S3** - Foi adotado para armazenar o estado atual do projeto Terraform. Foi definido o seu uso por ser um serviço da própria AWS e ter controle de versionamento dos arquivos. ++ **GitHub Actions** - Requisito do projeto. + +## Instruções para executar + +A pipeline de criação ou atualização do projeto é executada sempre que o código Terraform do projeto for alterado na branch main. + +## Configurações +As variáveis de configuração do projeto estão no arquivo terraform.tfvars, exceto as variáveis consideradas sensiveis que estão no gerenciador de secrets do GitHub Actions. + +**Variáveis armazendas em secrets:** + +AWS_ACCESS_KEY_ID => Access Key utilizada para configurar o AWS CLI. + +AWS_SECRET_ACCESS_KEY => Secret access Key utilizada para configurar o AWS CLI. + +AWS_BUCKET_NAME => Nome do Bucket utilizado para armazenar o estado do projeto Terraform. + +AWS_BUCKET_FILE => Nome do arquivo utilizado para armazenar o estado do projeto Terraform. + +## Estrutura da solução + +![Diagrama do projeto](./diagramas/pipeline.drawio.png) + +Explicação do Fluxo + +## Possíveis evoluções do projeto + +Algumas evoluções que sugiro para o projeto: + ++ Separar ambientes dev, homolog e prod utilizando o Terraform Workspace ou Terraform Grunt para criação e gerenciamento desses ambientes. ++ Usar o DynamoDB junto com o S3 para evitar execução paralela do Terraform. + +... diff --git a/diagramas/pipeline.drawio.png b/diagramas/pipeline.drawio.png new file mode 100644 index 0000000..67b1e80 Binary files /dev/null and b/diagramas/pipeline.drawio.png differ diff --git a/src/.gitignore b/src/.gitignore new file mode 100644 index 0000000..dc82526 --- /dev/null +++ b/src/.gitignore @@ -0,0 +1,34 @@ +# Local .terraform directories +**/.terraform/* + +# .tfstate files +*.tfstate +*.tfstate.* + +# Crash log files +crash.log +crash.*.log + +# Exclude all .tfvars files, which are likely to contain sensitive data, such as +# password, private keys, and other secrets. These should not be part of version +# control as they are data points which are potentially sensitive and subject +# to change depending on the environment. +*.tfvars +*.tfvars.json + +# Ignore override files as they are usually used to override resources locally and so +# are not checked in +override.tf +override.tf.json +*_override.tf +*_override.tf.json + +# Include override files you do wish to add to version control using negated pattern +# !example_override.tf + +# Include tfplan files to ignore the plan output of command: terraform plan -out=tfplan +# example: *tfplan* + +# Ignore CLI configuration files +.terraformrc +terraform.rc \ No newline at end of file diff --git a/src/.terraform.lock.hcl b/src/.terraform.lock.hcl new file mode 100644 index 0000000..58fef82 --- /dev/null +++ b/src/.terraform.lock.hcl @@ -0,0 +1,105 @@ +# This file is maintained automatically by "terraform init". +# Manual edits may be lost in future updates. + +provider "registry.terraform.io/hashicorp/aws" { + version = "5.48.0" + constraints = "5.48.0" + hashes = [ + "h1:rMyeKizkPgNuYQ1UQpWGDvGdJQs5vDPDlYtS4jVxxcI=", + "zh:0876d94be46be905d1f6c149461979cd6e9bec80d5ffad43fd6267fe7c3a924d", + "zh:3a853f887e6f61c2ba383c46e71bcec97ecd31d25a78dab08958f43bbbaecb86", + "zh:43235595e26dd131f00704b5b64a65c4e7c4984a559b30d4272170e1b78e99b7", + "zh:6866f7535ec2ef8fe6ed16eecee2e31418a2bd86cec73e1d18e47bd3bb87f68e", + "zh:756a4ed97f30ea6e8871c16446b24ce55601143a715e067b7f9ebdae8349da34", + "zh:793e8414962934be9805186874f207ca1dc8d162b6665e4938893ad827a545c6", + "zh:79b2f886507f21ff1b752ff140ed95ed551f389abf0c8177c7b5f5bbbd95da8e", + "zh:8653b1bc6f7e62404e02f940d962d0c2ba0c4dd4c28bd595945454cf348c2697", + "zh:9b12af85486a96aedd8d7984b0ff811a4b42e3d88dad1a3fb4c0b580d04fa425", + "zh:9bd612f013c075685c129e5d0ec9243572cd51359599b7218459babe0e9b6ac7", + "zh:aabafe758ee8392f56d2c894017203de4dae38c1e3e0d274c54e194b9b8fccff", + "zh:aded7d6034115ca512b79ca17da65ebb8906e3b8def78dcbc0640142b0c05ca0", + "zh:ce383ee19b37666aba60db6b01cbe7a1fcbb40c6dd54d0cb36b2ba114ee5ae62", + "zh:ceaf1b998b9ced4b63f35da386358e4c7ad6def582438987c91bceffefb9e258", + "zh:d79225a9ae6a7391c33aa2d794bf9b167db66398c4f054f94d557615b051a40d", + ] +} + +provider "registry.terraform.io/hashicorp/cloudinit" { + version = "2.3.4" + constraints = ">= 2.0.0" + hashes = [ + "h1:cVIIhnXweOHavu1uV2bdKScTjLbM1WnKM/25wqYBJWo=", + "zh:09f1f1e1d232da96fbf9513b0fb5263bc2fe9bee85697aa15d40bb93835efbeb", + "zh:381e74b90d7a038c3a8dcdcc2ce8c72d6b86da9f208a27f4b98cabe1a1032773", + "zh:398eb321949e28c4c5f7c52e9b1f922a10d0b2b073b7db04cb69318d24ffc5a9", + "zh:4a425679614a8f0fe440845828794e609b35af17db59134c4f9e56d61e979813", + "zh:4d955d8608ece4984c9f1dacda2a59fdb4ea6b0243872f049b388181aab8c80a", + "zh:78d5eefdd9e494defcb3c68d282b8f96630502cac21d1ea161f53cfe9bb483b3", + "zh:a48fbee1d58d55a1f4c92c2f38c83a37c8b2f2701ed1a3c926cefb0801fa446a", + "zh:b748fe6631b16a1dafd35a09377c3bffa89552af584cf95f47568b6cd31fc241", + "zh:d4b931f7a54603fa4692a2ec6e498b95464babd2be072bed5c7c2e140a280d99", + "zh:f1c9337fcfe3a7be39d179eb7986c22a979cfb2c587c05f1b3b83064f41785c5", + "zh:f58fc57edd1ee3250a28943cd84de3e4b744cdb52df0356a53403fc240240636", + "zh:f5f50de0923ff530b03e1bca0ac697534d61bb3e5fc7f60e13becb62229097a9", + ] +} + +provider "registry.terraform.io/hashicorp/null" { + version = "3.2.2" + constraints = ">= 3.0.0" + hashes = [ + "h1:zT1ZbegaAYHwQa+QwIFugArWikRJI9dqohj8xb0GY88=", + "zh:3248aae6a2198f3ec8394218d05bd5e42be59f43a3a7c0b71c66ec0df08b69e7", + "zh:32b1aaa1c3013d33c245493f4a65465eab9436b454d250102729321a44c8ab9a", + "zh:38eff7e470acb48f66380a73a5c7cdd76cc9b9c9ba9a7249c7991488abe22fe3", + "zh:4c2f1faee67af104f5f9e711c4574ff4d298afaa8a420680b0cb55d7bbc65606", + "zh:544b33b757c0b954dbb87db83a5ad921edd61f02f1dc86c6186a5ea86465b546", + "zh:696cf785090e1e8cf1587499516b0494f47413b43cb99877ad97f5d0de3dc539", + "zh:6e301f34757b5d265ae44467d95306d61bef5e41930be1365f5a8dcf80f59452", + "zh:78d5eefdd9e494defcb3c68d282b8f96630502cac21d1ea161f53cfe9bb483b3", + "zh:913a929070c819e59e94bb37a2a253c228f83921136ff4a7aa1a178c7cce5422", + "zh:aa9015926cd152425dbf86d1abdbc74bfe0e1ba3d26b3db35051d7b9ca9f72ae", + "zh:bb04798b016e1e1d49bcc76d62c53b56c88c63d6f2dfe38821afef17c416a0e1", + "zh:c23084e1b23577de22603cff752e59128d83cfecc2e6819edadd8cf7a10af11e", + ] +} + +provider "registry.terraform.io/hashicorp/time" { + version = "0.11.1" + constraints = ">= 0.9.0" + hashes = [ + "h1:IkDriv5C9G+kQQ+mP+8QGIahwKgbQcw1/mzh9U6q+ZI=", + "zh:19a393db736ec4fd024d098d55aefaef07056c37a448ece3b55b3f5f4c2c7e4a", + "zh:227fa1e221de2907f37be78d40c06ca6a6f7b243a1ec33ade014dfaf6d92cd9c", + "zh:29970fecbf4a3ca23bacbb05d6b90cdd33dd379f90059fe39e08289951502d9f", + "zh:65024596f22f10e7dcb5e0e4a75277f275b529daa0bc0daf34ca7901c678ab88", + "zh:694d080cb5e3bf5ef08c7409208d061c135a4f5f4cdc93ea8607860995264b2e", + "zh:78d5eefdd9e494defcb3c68d282b8f96630502cac21d1ea161f53cfe9bb483b3", + "zh:b29d15d13e1b3412e6a4e1627d378dbd102659132f7488f64017dd6b6d5216d3", + "zh:bb79f4cae9f8c17c73998edc54aa16c2130a03227f7f4e71fc6ac87e230575ec", + "zh:ceccf80e95929d97f62dcf1bb3c7c7553d5757b2d9e7d222518722fc934f7ad5", + "zh:f40e638336527490e294d9c938ae55919069e6987e85a80506784ba90348792a", + "zh:f99ef33b1629a3b2278201142a3011a8489e66d92da832a5b99e442204de18fb", + "zh:fded14754ea46fdecc62a52cd970126420d4cd190e598cb61190b4724a727edb", + ] +} + +provider "registry.terraform.io/hashicorp/tls" { + version = "4.0.5" + constraints = ">= 3.0.0" + hashes = [ + "h1:e4LBdJoZJNOQXPWgOAG0UuPBVhCStu98PieNlqJTmeU=", + "zh:01cfb11cb74654c003f6d4e32bbef8f5969ee2856394a96d127da4949c65153e", + "zh:0472ea1574026aa1e8ca82bb6df2c40cd0478e9336b7a8a64e652119a2fa4f32", + "zh:1a8ddba2b1550c5d02003ea5d6cdda2eef6870ece86c5619f33edd699c9dc14b", + "zh:1e3bb505c000adb12cdf60af5b08f0ed68bc3955b0d4d4a126db5ca4d429eb4a", + "zh:6636401b2463c25e03e68a6b786acf91a311c78444b1dc4f97c539f9f78de22a", + "zh:76858f9d8b460e7b2a338c477671d07286b0d287fd2d2e3214030ae8f61dd56e", + "zh:a13b69fb43cb8746793b3069c4d897bb18f454290b496f19d03c3387d1c9a2dc", + "zh:a90ca81bb9bb509063b736842250ecff0f886a91baae8de65c8430168001dad9", + "zh:c4de401395936e41234f1956ebadbd2ed9f414e6908f27d578614aaa529870d4", + "zh:c657e121af8fde19964482997f0de2d5173217274f6997e16389e7707ed8ece8", + "zh:d68b07a67fbd604c38ec9733069fbf23441436fecf554de6c75c032f82e1ef19", + "zh:f569b65999264a9416862bca5cd2a6177d94ccb0424f3a4ef424428912b9cb3c", + ] +} diff --git a/src/main.tf b/src/main.tf new file mode 100644 index 0000000..914a379 --- /dev/null +++ b/src/main.tf @@ -0,0 +1,53 @@ +module "vpc" { + source = "terraform-aws-modules/vpc/aws" + version = "5.8.1" + + name = var.aws_vpc_name + cidr = var.aws_vpc_cidr + + azs = var.aws_vpc_azs + private_subnets = var.aws_vpc_private_subnets + public_subnets = var.aws_vpc_public_subnets + + enable_nat_gateway = true + enable_vpn_gateway = true + + tags = merge(var.aws_project_tags, { "kubernetes.io/cluster/${var.aws_eks_name}" = "shared" }) + + public_subnet_tags = { + "kubernetes.io/cluster/${var.aws_eks_name}" = "shared" + "kubernetes.io/role/elb" = 1 + } + + private_subnet_tags = { + "kubernetes.io/cluster/${var.aws_eks_name}" = "shared" + "kubernetes.io/role/internal-elb" = 1 + } +} + +module "eks" { + source = "terraform-aws-modules/eks/aws" + version = "20.8.5" + + cluster_name = var.aws_eks_name + cluster_version = var.aws_eks_version + + enable_cluster_creator_admin_permissions = true + + subnet_ids = module.vpc.private_subnets + vpc_id = module.vpc.vpc_id + + cluster_endpoint_public_access = true + + eks_managed_node_groups = { + default = { + min_size = 2 + max_size = 2 + desired_size = 2 + instance_types = var.aws_eks_managed_node_groups_instance_types + tags = var.aws_project_tags + } + } + + tags = var.aws_project_tags +} diff --git a/src/providers.tf b/src/providers.tf new file mode 100644 index 0000000..f6742b9 --- /dev/null +++ b/src/providers.tf @@ -0,0 +1,15 @@ +terraform { + required_providers { + aws = { + source = "hashicorp/aws" + version = "5.48.0" + } + } + backend "s3" { + + } +} + +provider "aws" { + region = var.aws_region +} \ No newline at end of file diff --git a/src/terraform.tfvars b/src/terraform.tfvars new file mode 100644 index 0000000..67f3d8d --- /dev/null +++ b/src/terraform.tfvars @@ -0,0 +1,15 @@ +aws_region = "us-east-1" +aws_vpc_name = "live-vpc" +aws_vpc_cidr = "10.0.0.0/16" +aws_vpc_azs = ["us-east-1a", "us-east-1b", "us-east-1c"] +aws_vpc_private_subnets = ["10.0.1.0/24", "10.0.2.0/24", "10.0.3.0/24"] +aws_vpc_public_subnets = ["10.0.101.0/24", "10.0.102.0/24", "10.0.103.0/24"] +aws_eks_name = "live-eks" +aws_eks_version = "1.29" +aws_eks_managed_node_groups_instance_types = ["t3.small"] +aws_project_tags = { + Terraform = "true" + Environment = "producao" + Project = "live" + Teste = "ok" +} \ No newline at end of file diff --git a/src/variables.tf b/src/variables.tf new file mode 100644 index 0000000..4ed15a4 --- /dev/null +++ b/src/variables.tf @@ -0,0 +1,60 @@ + +variable "aws_region" { + description = "Região usada para criar os recursos da AWS" + type = string + nullable = false +} + +variable "aws_vpc_name" { + description = "Colocar sempre a descrição" + type = string + nullable = false +} + +variable "aws_vpc_cidr" { + description = "Colocar sempre a descrição" + type = string + nullable = false +} + +variable "aws_vpc_azs" { + description = "Colocar sempre a descrição" + type = set(string) + nullable = false +} + +variable "aws_vpc_private_subnets" { + description = "Colocar sempre a descrição" + type = set(string) + nullable = false +} + +variable "aws_vpc_public_subnets" { + description = "Colocar sempre a descrição" + type = set(string) + nullable = false +} + +variable "aws_eks_name" { + description = "Colocar sempre a descrição" + type = string + nullable = false +} + +variable "aws_eks_version" { + description = "Colocar sempre a descrição" + type = string + nullable = false +} + +variable "aws_eks_managed_node_groups_instance_types" { + description = "Colocar sempre a descrição" + type = set(string) + nullable = false +} + +variable "aws_project_tags" { + description = "Colocar sempre a descrição" + type = map(any) + nullable = false +} \ No newline at end of file