DEV Community

Gabriel de Biasi for Trybe

Posted on

Evite configuration drift no seu estado de terraform ao usar aws_security_group

O terraform é uma ferramenta fantástica para provisionar e manter o estado de uma infraestrutura, tanto on-premises quanto nos ambientes de cloud. Entretanto, algumas vezes passamos por algumas situações que nós temos uma expectativa de que o terraform funcione de uma maneira, porém o terraform acaba funcionando de outra forma.

Foi o que aconteceu comigo ao utilizar o recurso aws_security_group. Este recurso permite criar um Security Group dentro de uma VPC, que na prática pode ser aplicado a outros recursos, como instâncias EC2, banco de dados, clusters Kubernetes, para fechar portas de conexão e liberar apenas algumas portas específicas (ou nenhuma).

Meu caso de uso foi criar um Security Group para uma instância EC2 que iria trabalhar como um worker, ou seja, essa instância iria obter os jobs através de uma fonte externa, realizar o processamento e enviar o resultado. Em resumo, por trabalhar em pull-based, essa instância não precisaria ter nenhuma regra de ingresso (entrada), apenas uma regra de egresso (saída) para qualquer IP.

Logo, fiz o recurso da seguinte maneira:

resource "aws_security_group" "sg" {
  name   = "my-amazing-security-group"
  vpc_id = aws_vpc.main.id

  egress {
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = ["0.0.0.0/0"]
  }
}
Enter fullscreen mode Exit fullscreen mode

Ao executar o comando terraform apply, obtive a seguinte saída:

gabriel@machine:~/terraform$ terraform apply

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
  + create

Terraform will perform the following actions:

  # aws_security_group.sg will be created
  + resource "aws_security_group" "sg" {
      + arn                    = (known after apply)
      + description            = "Managed by Terraform"
      + egress                 = [
          + {
              + cidr_blocks      = [
                  + "0.0.0.0/0",
                ]
              + description      = ""
              + from_port        = 0
              + ipv6_cidr_blocks = []
              + prefix_list_ids  = []
              + protocol         = "-1"
              + security_groups  = []
              + self             = false
              + to_port          = 0
            },
        ]
      + id                     = (known after apply)
      + ingress                = (known after apply)
      + name                   = "my-amazing-security-group"
      + name_prefix            = (known after apply)
      + owner_id               = (known after apply)
      + revoke_rules_on_delete = false
      + tags_all               = (known after apply)
      + vpc_id                 = "vpc-0101010101"
    }

Plan: 1 to add, 0 to change, 0 to destroy.

aws_security_group.sg: Creating...
aws_security_group.sg: Creation complete after 2s [id=sg-0101010101010101]
Enter fullscreen mode Exit fullscreen mode

Ótimo! O terraform criou o security group e eu pude utilizar na instância EC2 que criei. Entretanto, percebi que tinha cometido um erro ao provisionar a instância EC2 e eu precisava me conectar nessa instância usando ssh.

made a mistake

Para possibilitar o acesso, eu precisava criar a regra de ingresso no security group. Logo, fui diretamente no dashboard da AWS, editei o security group manualmente liberando a porta 22 para apenas o meu IP.

hehehe

Após me conectar na instância e resolver o problema, pensei: “Vou simplesmente executar terraform apply, pois o terraform irá perceber a regra extra no security group e criar um plano para remover esta regra”. Então, ao executar o comando, obtive a seguinte saída:

gabriel@machine:~/terraform$ terraform apply
aws_security_group.sg: Refreshing state... [id=sg-0101010101010101]

No changes. Your infrastructure matches the configuration.

Terraform has compared your real infrastructure against your configuration and found no differences, so no changes are needed.

Apply complete! Resources: 0 added, 0 changed, 0 destroyed.
Enter fullscreen mode Exit fullscreen mode

confuso

Na hora fiquei confuso. O terraform não percebeu a regra nova no security group? Fui no dashboard da AWS e vi que a regra de ingresso ainda estava presente! E agora?

Pesquisando melhor, entendi que o recurso aws_security_group não mantém o estado das regras, se isso não for explícito. Ou seja, precisamos deixar explícito na definição do recurso que não queremos nenhuma regra de ingresso. Corrigindo nosso código, ficaria assim:

resource "aws_security_group" "sg" {
  name   = "my-amazing-security-group"
  vpc_id = data.aws_vpc.main.id

  ingress = []    # explicitamente nenhuma regra de ingresso

  egress {
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = ["0.0.0.0/0"]
  }
}
Enter fullscreen mode Exit fullscreen mode

Perceba que o atributo ingress recebe uma lista vazia. Isto deixa explícito que não queremos nenhuma regra de ingresso para este security group. Logo, executando o comando terraform apply novamente, finalmente podemos ter o estado garantido:

gabriel@machine:~/terraform$ terraform apply
aws_security_group.sg: Refreshing state... [id=sg-0110522c7ec4870d0]

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
  ~ update in-place

Terraform will perform the following actions:

  # aws_security_group.sg will be updated in-place
  ~ resource "aws_security_group" "sg" {
        id                     = "sg-0110522c7ec4870d0"
      ~ ingress                = [
          - {
              - cidr_blocks      = [
                  - "169.169.169.169/32",
                ]
              - description      = "My IP"
              - from_port        = 22
              - ipv6_cidr_blocks = []
              - prefix_list_ids  = []
              - protocol         = "tcp"
              - security_groups  = []
              - self             = false
              - to_port          = 22
            },
        ]
        name                   = "my-amazing-security-group"
        tags                   = {}
        # (7 unchanged attributes hidden)
    }

Plan: 0 to add, 1 to change, 0 to destroy.

aws_security_group.sg: Modifying... [id=sg-0110522c7ec4870d0]
aws_security_group.sg: Modifications complete after 0s [id=sg-0110522c7ec4870d0]

Apply complete! Resources: 0 added, 1 changed, 0 destroyed.
Enter fullscreen mode Exit fullscreen mode

ufa

Ufa! Agora sim o terraform nos garante que este security group não ganhe novas regras através do dashboard da AWS e mantenha este estado pra gente.

Discussion (1)

Collapse
heymarkkop profile image
Mark Kop

A AWS é cheia de detalhezinho assim, né? Valeu por compartilhar!