OCI – Usando tags e oci-cli para automatizar deleção de recursos

Geralmente as tags são utilizadas para tracking de custo, saber à qual departamento determinado recurso está vinculado e segurança, nesse post vou demonstrar como montar uma estrutura de tags e um script para automatizar a exclusão de recursos baseado no valor de uma tag.

Primeiro devemos conhecer um pouco mais sobre a estrutura de uma tag e como ela pode ser aplicada aos nossos recursos.

Tag Namespace

O namespace pode ser considerado como um grupo de tags, aqui irei usar um chamado Controle.

Tag Definition

Nela vamos especificar a nossa Tag e também o seu tipo que pode ser estático(onde o user pode entrar um valor) ou uma lista de valores (valores pré-definidos por alguém que possua a permissão de gerenciamento de tags), aqui irei criar uma do tipo lista de valores com os valores Y(o que o script vai apagar) e N (o que o script não vai apagar), também vou criar uma do tipo estática para caso o usuário queira especificar um motivo do recurso não ser apagado.

No fim, isso que teremos criado até o momento

Tags Default

Esse é um recurso muito importante para que se tenha um controle melhor do seu ambiente, usando uma Tag Default ela é automaticamente atribuída a um compartimento, dessa forma o usuário não precisa(ou é obrigado) a definir um valor a ela, no nosso caso, vou definir o nosso namespace Controle ao meu compartimento indo em Identity > Compartments > Compartment details > Tag Defaults como falei anteriormente, o namespace é um agrupamento de tags, sendo assim além dele, você pode especificar qual tag dentro dele vai ser aplicada de forma automática e caso ela seja do tipo lista de valores qual o valor padrão, aqui colocarei padrão Y (ou seja, apagar), o usuário precisa de forma explicita alterar o valor da tag caso queira preservar o recurso:

Quanto ao motivo, vou deixar que o usuário especifique o valor:

Um ponto legal desse recurso, é que a tag é aplicada a todos os recursos que estão sendo criados pelo usuário, mesmo aqueles que não são criado de forma direta por ele, um exemplo disso é o disco de boot de uma VM que é criado automaticamente pelo processo, ele vai herdar o valor das tags.

No final, esse vai ser o meu compartimento com as tags aplicadas

Uma dica, ainda não é possível controlar para que tag defaults sejam exibidas baseadas em condições, então coloque algum texto na Tag Motivo para facilitar a criação, caso não faça isso, o usuário vai ser obrigado a colocar algum valor na tag mesmo que ele queira apagar o recurso.

Validando a tag

Agora vou simular a criação de uma VM no meu compartimento que possui a tag aplicada:

Veja que ele não pediu nenhum valor de tag para o usuário, mas caso você verifique a aba Tag verá que os valores foram definidos automaticamente:

Como disse, a tag é aplicada a todos os recursos que foram criados pelo processo:

oci cli

Quem me conhece, sabe que sou fã de recursos de linha de comando e o oci-cli é um deles, ele é bem completo e vamos usa-lo para uma pequena automação para apagar recursos que possuam determinado valor na tag, esse script foi feito para rodar em um bash e irei passar pelas funções presentes nele.

Sugiro que não executem esse código em ambiente produtivo sem entender o que ele faz! Não me responsabilizo por nenhum dano

Identificar regiões ativas

get_regions() {
oci iam region-subscription list --all  --query 'data[*]."region-name"' | sed -e 's/\[//g ; s/\]//g ; s/\"//g ; s/\,//g ; /^$/d' > regions.txt
}

Essa função recupera todas as regiões que sua conta possui ativa e salva em um arquivo chamado regions.txt

Identificar compartimentos

get_compartments(){
oci iam compartment list --all  --access-level ANY --compartment-id-in-subtree true --query 'data[*].id' | sed -e 's/\[//g ; s/\]//g ; s/\"//g ; s/\,//g ; s/\}//g ; /^$/d' | sed  s/\{//g > compartments.txt
}

Com essa função, iremos pegar todos os compartimentos que o usuário que esteja fazendo a chamada possui acesso e salvar os ocids em um arquivo chamados compartments.txt

Juntando tudo

del_inst(){
while read -r region <&3; do
  while read -r compartment  <&4; do
   echo "Listando recursos em $region compartimento $compartment"
   oci compute instance list -c $compartment --query 'data[*].{"NOME:":"display-name","TAG-DELETE":"defined-tags"."Controle"."Apagar","TAG-MOTIVO":"defined-tags"."Controle"."Motivo","OCID":"id"}' --output table --region $region > control_inst-$region.txt 
	echo "Listando recursos a serem apagados em $region compartimento $compartment"
	oci compute instance list -c $compartment --query 'data[?"defined-tags"."Controle"."Apagar"==`Y`]."id"'  --region $region | sed -e 's/\[//g ; s/\]//g ; s/\"//g ; s/\,//g ; /^$/d'  > del_inst-$region.txt 2>/dev/null
	echo "Apagando VMS da regiao $region compartimento $compartment"
	while read -r inst_del <&5; do
	echo $inst_del
	oci compute instance terminate  --instance-id $inst_del  --force --region $region --preserve-boot-volume false 
	done 5<del_inst-$region.txt
  done 4<compartments.txt
done 3<regions.txt
}


Essa é a parte feia do código e ele possui alguns pontos importantes, ele vai executar um loop em cada região que esteja no arquivo regions.txt, passando por cada compartimento que esteja no arquivo compartments.txt e vai executar duas chamadas, uma para gerar um arquivo de controle chamado control_inst-$region.txt contendo todas as instâncias que ele encontrou na região/compartimento e mostrando o valor da tag Apagar:

oci compute instance list -c $compartment --query 'data[*].{"NOME:":"display-name","TAG-DELETE":"defined-tags"."Controle"."Apagar","OCID":"id"}' --output table --region $region > control_inst-$region.txt

Dessa forma você vai ter um histórico.

Depois disso ele vai gerar um arquivo(del_inst-$region.txt) contendo somente o OCID das instancias que possuem a tag Apagar=Y

oci compute instance list -c $compartment --query 'data[?"defined-tags"."Controle"."Apagar"==`Y`]."id"'  --region $region | sed -e 's/\[//g ; s/\]//g ; s/\"//g ; s/\,//g ; /^$/d'  > del_inst-$region.txt 2>/dev/null

E finalmente executamos a leitura do arquivo del_inst-$region.txt passando os ocids como parâmetro da seguinte chamada

oci compute instance terminate --instance-id $inst_del --force --region $region --preserve-boot-volume false

Por que dividi o código dessa forma? Pois gosto de logs e também acredito que dessa forma você tenha mais segurança/controle do que vai ser executado, uma dica é que caso não queira rodar para todas a regiões/compartimentos, basta fazer como o exemplo abaixo, colocando o nome a região/compartimento em seus respectivos .txt .

Executando

Aqui executarei apenas para a região de GRU e meu compartimento

E caso precise verificar um histórico, basta dar um cat no arquivo control_inst-$region.txt

Espero que tenham gostado dos exemplos, como próximo passo, vou publicar o script completo com mais opções de limpeza.

chevron_left
chevron_right