O autor selecionou a Fundação Wikimedia para receber uma doação como parte do programa Write for DOnations.
Introdução
A Infraestrutura como Código (IaC) é uma prática de automatizar a implantação e modificações da infraestrutura, definindo os estados dos recursos e suas relações em código. A execução desse código então cria ou modifica os recursos reais na nuvem. A IaC permite que os engenheiros usem uma ferramenta de IaC como o Terraform (da HashiCorp) para provisionamento de infraestrutura.
Com a IaC, as alterações na sua infraestrutura podem passar pelo mesmo processo de revisão de código que o seu código de aplicativo. Você pode armazenar o código em controle de versão (como o Git) para manter um histórico do estado de sua infraestrutura, e você pode automatizar ainda mais o processo de implantação com ferramentas de nível mais alto, como uma plataforma interna de desenvolvedores (IDP).
Terraform é uma ferramenta popular de IaC (Infrastructure as Code) agnóstica de plataforma devido ao seu amplo suporte para muitas plataformas, incluindo o GitHub, Cloudflare e DigitalOcean. A maioria das configurações do Terraform são escritas usando uma linguagem declarativa chamada de HashiCorp Configuration Language (HCL).
O Cloud Development Kit for Terraform (CDKTF) é uma ferramenta construída em cima do Terraform que permite definir infraestrutura usando uma linguagem de programação familiar (como TypeScript, Python ou Go) em vez de HCL. Esta ferramenta pode fornecer uma curva de aprendizado mais suave para desenvolvedores não familiarizados com HCL, enquanto permite que desenvolvedores usem recursos de programação nativos como loops, variáveis e funções. cdktf
. Em seguida, você irá criar um projeto CDKTF em TypeScript e definir o projeto com dois servidores NGINX balanceados por um cdktf
para implantar a infraestrutura. No final deste tutorial, você terá um projeto CDKTF a partir do qual poderá expandir sua infraestrutura.
Neste tutorial, você começará instalando a ferramenta de interface de linha de comando (CLI) cdktf
. Em seguida, você criará um projeto CDKTF em TypeScript e definirá o projeto com dois servidores NGINX que são balanceados por um balanceador de carga. Você usará então cdktf
para implantar a infraestrutura. No final deste tutorial, você terá um projeto CDKTF a partir do qual poderá expandir sua infraestrutura.
Nota: Este tutorial foi testado com CDKTF 0.11.2
e Terraform 1.2.2
.
Pré-requisitos
Para concluir este tutorial, você precisará:
- A good understanding of Infrastructure-as-Code (IaC). You can learn about IaC in Infrastructure as Code Explained.
- A DigitalOcean account. If you do not have one, sign up for a new account.
- A DigitalOcean Personal Access Token, which you can create via the DigitalOcean console. Instructions on how to do that can be found at How to Generate a Personal Access Token.
- A password-less SSH key added to your DigitalOcean account. You can add that by following How To Use SSH Keys with DigitalOcean Droplets. When you add the key to your account, remember the name you give it, as you will need it in this tutorial. For CDKTF to accept the name of your key, it must start with a letter or underscore and may contain only letters, digits, underscores, and dashes.
- Terraform instalado em sua máquina local, que você pode configurar com “Etapa 1 – Instalando Terraform” em Como usar Terraform com DigitalOcean.
- Node.js instalado em sua máquina local. Você pode encontrar instruções para isso na série Como instalar Node.js e criar um ambiente de desenvolvimento local.
- Para se sentir confortável programando com JavaScript. Para construir suas habilidades, confira a série Como Codificar em JavaScript.
- Para se sentir confortável usando os recursos básicos do TypeScript. Se você não se sente confortável com TypeScript, a série de tutoriais Como Codificar em TypeScript é uma boa fonte para você se atualizar.
- A code editor or integrated development environment (IDE) that supports TypeScript. If you are not currently using one, try Visual Studio Code. You can also read up on How To Work With TypeScript in Visual Studio Code.
Passo 1 — Instalando o CLI cdktf
Para começar, você instalará a ferramenta de linha de comando cdktf
.
O CLI cdktf
está disponível como um pacote NPM. Se você pesquisar por cdktf
no npmjs.com, encontrará dois pacotes com nomes semelhantes: cdktf
e cdktf-cli
.
Conceitualmente, o CDKTF é uma camada de abstração em cima do Terraform. Consiste em duas partes:
-
uma biblioteca contendo um conjunto de construções nativas da linguagem (como funções e classes) para definir infraestrutura. Essa parte é encapsulada dentro do pacote npm
cdktf
. Por exemplo, você pode ver o uso das classesApp
eTerraformStack
do pacotecdktf
no seguinte projeto de exemplo do CDKTF: - Um adaptador que analisa os construtos dentro do projeto CDKTF e os reduz a um conjunto de documentos JSON, que são então ingeridos no Terraform da mesma forma que o HCL é ingerido. Este adaptador é encapsulado em uma ferramenta CLI chamada
cdktf
, fornecida pelo pacotecdktf-cli
.
Para instalar a ferramenta CLI cdktf
, você precisa do pacote cdktf-cli
. Você pode instalar este pacote globalmente usando npm
, yarn
ou um gerenciador de pacotes de sua escolha.
Para instalar cdktf-cli
com npm
, execute o seguinte:
Observação: Provavelmente haverá uma versão mais recente do pacote cdktf-cli
após a publicação deste artigo. Você pode tentar seguir o tutorial com a versão mais recente executando npm install --global cdktf-cli@latest
em vez disso, mas esteja ciente de que algumas saídas podem diferir ligeiramente.
Alternativamente, você pode usar Homebrew no macOS ou Linux para instalar a CLI cdktf
como a fórmula cdktf
:cdktf
sem argumentos:
Para verificar se a instalação foi bem-sucedida, execute o comando cdktf
sem argumentos:
Você verá uma saída semelhante à seguinte:
OutputPlease pass a command to cdktf, here are all available ones:
cdktf
Commands:
cdktf init Create a new cdktf project from a template.
cdktf get Generate CDK Constructs for Terraform providers and modules.
cdktf convert Converts a single file of HCL configuration to CDK for Terraform.
cdktf deploy [stacks...] Deploy the given stacks
cdktf destroy [stacks..] Destroy the given stacks
cdktf diff [stack] Perform a diff (terraform plan) for the given stack
cdktf list List stacks in app.
cdktf login Retrieves an API token to connect to Terraform Cloud.
cdktf synth Synthesizes Terraform code for the given app in a directory.
cdktf watch [stacks..] [experimental] Watch for file changes and automatically trigger a deploy
cdktf output [stacks..] Prints the output of stacks
cdktf debug Get debug information about the current project and environment
cdktf completion generate completion script
Options:
--version Mostrar número da versão
--disable-logging Não escrever arquivos de log. Suportado usando a variável de ambiente CDKTF_DISABLE_LOGGING.
--disable-plugin-cache-env Não definir TF_PLUGIN_CACHE_DIR automaticamente.
--log-level Qual nível de log deve ser escrito.
-h, --help Show help
Options can be specified via environment variables with the "CDKTF_" prefix (e.g. "CDKTF_OUTPUT")
A saída mostra as comandos disponíveis. Nas próximas etapas deste tutorial, você ganhará experiência usando cdktf init
, cdktf get
, cdktf deploy
e cdktf destroy
.
Agora que você instalou o CLI cdktf
, você pode definir a infraestrutura escrevendo algum código TypeScript.
Passo 2 – Criando um Novo Projeto CDKTF
Neste passo, você usará o CLI cdktf
que acabou de instalar para criar um projeto CDKTF padrão, no qual você construirá nas próximas etapas.
Crie um diretório que abrigará o projeto CDKTF executando o seguinte comando:
Em seguida, navegue até o diretório recém-criado:
Use o comando cdktf init
para criar um esqueleto de projeto CDKTF no qual você construirá:
O CDKTF permite aos desenvolvedores definir infraestrutura usando TypeScript, Python, Java, C# ou Go. A opção --template=typescript
diz ao cdktf
para criar este projeto CDKTF usando TypeScript.
O Terraform (e assim o CDKTF) mantém o controle dos recursos que está gerenciando registrando suas definições e estados em arquivos chamados arquivos de estado do Terraform. A opção --local
diz ao CDKTF para manter esses arquivos de estado localmente na máquina que está executando o cdktf
(cada arquivo segue a estrutura de nomeação terraform.<stack>.tfstate
).
Após executar o comando, o CLI pode pedir sua permissão para enviar relatórios de falhas à equipe do CDKTF para ajudá-los a melhorar o produto:
Output? Do you want to send crash reports to the CDKTF team? See https://www.terraform.io/cdktf/create-and-deploy/configuration-file for
more information (Y/n)
Digite Y
se você deseja consentir ou N
se discordar, depois pressione ENTER
.
cdktf
então criará o esqueleto do projeto e instalará os pacotes. Quando o projeto estiver esqueletizado, você verá uma saída semelhante ao seguinte:
Output Your cdktf typescript project is ready!
cat help Print this message
Compile:
npm run get Import/update Terraform providers and modules (you should check-in this directory)
npm run compile Compile typescript code to javascript (or "npm run watch")
npm run watch Watch for changes and compile typescript in the background
npm run build Compile typescript
Synthesize:
cdktf synth [stack] Synthesize Terraform resources from stacks to cdktf.out/ (ready for 'terraform apply')
Diff:
cdktf diff [stack] Perform a diff (terraform plan) for the given stack
Deploy:
cdktf deploy [stack] Deploy the given stack
Destroy:
cdktf destroy [stack] Destroy the stack
Test:
npm run test Runs unit tests (edit __tests__/main-test.ts to add your own tests)
npm run test:watch Watches the tests and reruns them on change
Upgrades:
npm run upgrade Upgrade cdktf modules to latest version
npm run upgrade:next Upgrade cdktf modules to latest "@next" version (last commit)
Você também verá alguns novos arquivos adicionados ao diretório infra
. Os arquivos mais importantes são cdktf.json
e main.ts
.
cdktf.json
é o arquivo de configuração do projeto CDKTF. Se você abrir o arquivo, ele exibirá algo como o seguinte:app
define o comando que será executado para sintetizar o código TypeScript em JSON compatível com o Terraform. Esta propriedade indica que main.ts
é o ponto de entrada para o projeto CDKTF.
A propriedade app
define o comando que será executado para sintetizar o código TypeScript em JSON compatível com o Terraform. Essa propriedade indica que main.ts
é o ponto de entrada para o projeto CDKTF.
Se você abrir o arquivo main.ts
, verá algo semelhante ao seguinte:
Na linguagem do CDKTF, um conjunto de recursos de infraestrutura relacionados pode ser agrupado em um pilha. Por exemplo, os recursos que compõem um aplicativo de API, como Droplets, balanceadores de carga e registros DNS, podem ser agrupados em uma única pilha chamada APIStack
. Cada pilha mantém seu próprio estado e pode ser implantada, modificada ou destruída independentemente de outras pilhas. Um uso comum de pilhas é ter uma pilha para produção e uma pilha separada para desenvolvimento.
Um aplicativo é um contêiner para várias pilhas. Por exemplo, um aplicativo pode agrupar as pilhas de vários microsserviços.
O projeto CDKTF gerado no esqueleto de main.ts
contém uma única classe de pilha chamada MyStack
, atualmente definindo nenhum recurso. Uma instância de MyStack
é criada com o nome infra
, contida dentro de um aplicativo chamado app
. Nas etapas subsequentes, você definirá recursos de infraestrutura dentro do construtor MyStack
.
Após criar o projeto, o próximo passo é configurar o projeto CDKTF com provedores.
Passo 3 — Instalação do Provedor DigitalOcean
Neste passo, você instalará o Provedor DigitalOcean no projeto CDKTF.
Provedores são bibliotecas que fornecem instruções para o Terraform (que é usado pelo cdktf
por baixo dos panos) sobre como criar, atualizar e excluir recursos em provedores de nuvem, provedores SaaS e outras plataformas que expõem interfaces de programação de aplicativos (APIs). Os provedores encapsulam a lógica de chamada dessas APIs de upstream em funções padrão que o Terraform pode chamar.
Por exemplo, se você fosse criar um novo Droplet DigitalOcean sem o Terraform, você teria que enviar uma solicitação POST
para o endpoint /v2/droplets
do API DigitalOcean. Com o Terraform, você instalaria o provedor DigitalOcean e definiria um recurso digitalocean_droplet
, semelhante ao seguinte trecho de amostra:
Em seguida, você pode usar a ferramenta CLI cdktf
para traduzir esse código TypeScript em JSON compatível com o Terraform e passá-lo para o provedor, que fará as chamadas de API apropriadas para criar o Droplet em seu nome.
Agora que você entende o que é um provedor, pode configurar o provedor DigitalOcean para seu projeto CDKTF.
Abra o arquivo cdktf.json
e adicione a string digitalocean/digitalocean
à matriz terraformProviders
:
digitalocean/digitalocean
é o identificador para o provedor DigitalOcean no Terraform Registry.
Salve e feche o arquivo.
Em seguida, execute cdktf get
para baixar e instalar o provedor.
cdktf get
irá baixar o provedor, extrair o esquema, gerar as classes TypeScript correspondentes e adicioná-lo como um módulo TypeScript sob .gen/providers/
. Essa geração automática de código permite que você use quaisquer provedores Terraform e módulos HCL com CDKTF, e é assim que CDKTF pode fornecer a conclusão de código em editores que oferecem suporte a ele.
Depois que cdktf get
terminar de ser executado, você verá uma saída semelhante à seguinte:
OutputGenerated typescript constructs in the output directory: .gen
Você também verá um novo diretório chamado .gen
contendo o código gerado do provedor.
Nesta etapa, você instalou o provedor digitalocean/digitalocean
no projeto. Na próxima etapa, você configurará o provedor DigitalOcean com as credenciais necessárias para autenticar o provedor com a API DigitalOcean.
Etapa 4 — Configurando o Provedor DigitalOcean
Nesta etapa, você configurará o provedor DigitalOcean com seu Token de Acesso Pessoal DigitalOcean, o que permite que o provedor chame a API DigitalOcean em seu nome.
Provedores diferentes requerem e suportam diferentes credenciais para autenticar com a API upstream. Para o provedor DigitalOcean, você precisa fornecer seu Token de Acesso Pessoal DigitalOcean. Você pode especificar o token para o provedor definindo-o como as variáveis de ambiente DIGITALOCEAN_TOKEN
ou DIGITALOCEAN_ACCESS_TOKEN
.
Execute o seguinte comando no seu terminal para definir a variável de ambiente para essa sessão de terminal.
Nota: Ao chamar export
, você está definindo a variável de ambiente apenas para essa sessão de terminal. Se você fechar e reabrir o terminal ou executar os comandos cdktf
em um terminal diferente, precisará executar o comando export
novamente para que a variável de ambiente entre em vigor.
Em seguida, você especificará o provedor dentro da classe MyStack
, o que permitirá definir recursos fornecidos pelo provedor dentro de sua pilha. Atualize o arquivo main.ts
para o seguinte:
O módulo para o provedor está localizado em ./.gen/providers/digitalocean
, que foi gerado automaticamente quando você executou cdktf get
.
Você configurou o provedor digitalocean/digitalocean
com credenciais nesta etapa. Em seguida, você começará a definir a infraestrutura que faz parte do objetivo deste tutorial.
Passo 5 — Definindo Aplicações Web em Droplets
Nesta etapa, você definirá dois servidores NGINX, cada um servindo arquivos diferentes, implantados em dois Droplets Ubuntu 20.04 idênticos.
Você começa com a definição dos dois Droplets. Modifique o main.ts
com as alterações realçadas:
Você usa um loop nativo em JavaScript (Array.prototype.map()
) para evitar duplicação no código.
Assim como se estivesse criando o Droplet através do console, existem vários parâmetros a serem especificados:
image
– a distribuição e versão do Linux que o Droplet executará.region
– o datacenter onde o Droplet será executado.size
– a quantidade de recursos de CPU e memória a serem reservados para o Droplet.name
– um nome único usado para se referir ao Droplet.
Os valores para image
, region
e size
devem ser coisas que o DigitalOcean suporta. Você pode encontrar os valores válidos (chamados de slugs) para todas as distribuições do Linux, tamanhos de Droplet e regiões suportadas na página DigitalOcean API Slugs. Você pode encontrar uma lista completa de atributos obrigatórios e opcionais na página de documentação do digitalocean_droplet
.
Adicionando uma Chave SSH
Como parte dos pré-requisitos, você carregou uma chave pública SSH sem senha em sua conta do DigitalOcean e anotou seu nome. Agora, você usará esse nome para recuperar o ID da chave SSH e passá-lo na definição do seu Droplet.
Como a chave SSH foi adicionada manualmente à sua conta do DigitalOcean, ela não é um recurso gerenciado pela sua configuração atual do Terraform. Se você tentasse definir um novo recurso digitalocean_ssh_key
, ele criaria uma nova chave SSH em vez de usar a existente.
Em vez disso, você definirá uma nova digitalocean_ssh_key
fonte de dados. No Terraform, fontes de dados são usadas para recuperar informações sobre infraestrutura que não são gerenciadas pela configuração atual do Terraform. Em outras palavras, elas fornecem uma visão somente leitura do estado de infraestrutura externa existente. Uma vez definida uma fonte de dados, você pode usar os dados em outro lugar em sua configuração do Terraform.
Ainda no main.ts
e dentro do construtor de MyStack
, defina uma nova fonte de dados DataDigitaloceanSshKey
e passe o nome que você atribuiu à sua chave SSH (aqui, o nome é do_cdktf
):
Em seguida, atualize a definição do Droplet para incluir a chave SSH:
Ao ser provisionado, você pode acessar o Droplet usando uma chave SSH privada em vez de uma senha.
Especificando Script de Dados do Usuário para Instalar o NGINX
Agora você definiu dois Droplets idênticos rodando Ubuntu, configurados com acesso SSH. A próxima tarefa é instalar o NGINX em cada Droplet.
Quando um Droplet está sendo criado, uma ferramenta chamada CloudInit fará o bootstrap do servidor. O CloudInit pode aceitar um arquivo chamado dados do usuário, que pode modificar como o servidor é bootstrapped. Os dados do usuário podem ser quaisquer arquivos cloud-config
ou scripts que o servidor possa interpretar, como scripts Bash.
No restante deste passo, você criará um script Bash e o especificará como os dados do usuário do Droplet. O script instalará o NGINX como parte do processo de bootstrap. Além disso, o script também substituirá o conteúdo do arquivo /var/www/html/index.html
(o arquivo padrão servido pelo NGINX) com o nome de host e o endereço IP do Droplet, o que fará com que os dois servidores NGINX sirvam arquivos diferentes. No próximo passo, você colocará ambos esses servidores NGINX por trás de um balanceador de carga; ao servir arquivos diferentes, ficará evidente se o balanceador de carga está distribuindo solicitações corretamente ou não.
Ainda no main.ts
, adicione uma nova propriedade userData
ao objeto de configuração do Droplet:
Aviso: Certifique-se de que não haja novas linhas antes do shebang (#!
); caso contrário, o script pode não ser executado.
Quando o Droplet for provisionado pela primeira vez, o script será executado como o usuário root
. Ele usará o gerenciador de pacotes do Ubuntu, APT, para instalar o pacote nginx
. Em seguida, usará o Metadata Service da DigitalOcean para recuperar informações sobre si mesmo e gravar o nome de host e o endereço IP em index.html
, que é servido pelo NGINX.
Neste passo, você definiu os dois Droplets executando o Ubuntu, configurou cada um com acesso SSH e instalou o NGINX usando o recurso de dados do usuário. No próximo passo, você definirá um balanceador de carga que ficará na frente desses servidores NGINX e configurará-o para balancear a carga de forma round-robin.
Passo 6 — Definindo um Balanceador de Carga
Neste passo, você definirá um Balanceador de Carga DigitalOcean ao definir uma instância do recurso digitalocean_loadbalancer
.
Ainda no main.ts
, adicione a seguinte definição para um balanceador de carga no final do construtor MyStack
:
O argumento forwardingRule
informa ao balanceador de carga para escutar solicitações HTTP na porta 80
e encaminhá-las para cada um dos Droplets na porta 80
.
Os dropletIds
especificam os Droplets para os quais o balanceador de carga encaminhará solicitações. Ele aceita um número, mas o valor de droplet.id
é uma string. Portanto, você usou a Fn.tonumber
função Terraform para converter o valor de ID de Droplet de string para um número.
Nota: Você usou a função Terraform Fn.tonumber
aqui em vez da parseInt
nativa do JavaScript porque o valor de droplet.id
é desconhecido até que o Droplet seja provisionado. As funções Terraform são projetadas para operar em valores de tempo de execução desconhecidos antes de o Terraform aplicar uma configuração.
Salve e feche o arquivo.
Você agora definiu dois Droplets e um balanceador de carga que fica na frente deles. Seu main.ts
deve ser semelhante a isto:
Na próxima etapa, você usará a ferramenta CLI cdktf
para materializar todo o seu projeto CDKTF.
Etapa 7 – Provisionamento da sua Infraestrutura
Nesta etapa, você usará a ferramenta CLI cdktf
para provisionar os Droplets e os balanceadores de carga que você definiu nas etapas anteriores.
Certifique-se de que você está na pasta infra/
e definiu a variável de ambiente DIGITALOCEAN_ACCESS_TOKEN
para a sessão do terminal, então execute o comando cdktf deploy
:
Você deve ver uma saída semelhante ao seguinte:
Outputinfra Initializing the backend...
infra Initializing provider plugins...
infra - Reusing previous version of digitalocean/digitalocean from the dependency lock file
infra - Using previously-installed digitalocean/digitalocean v2.19.0
infra Terraform has been successfully initialized!
infra 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:
infra # digitalocean_droplet.bar (bar) will be created
+ resource "digitalocean_droplet" "bar" {
+ backups = false
+ created_at = (known after apply)
+ disk = (known after apply)
+ graceful_shutdown = false
+ id = (known after apply)
+ image = "ubuntu-20-04-x64"
+ ipv4_address = (known after apply)
+ ipv4_address_private = (known after apply)
+ ipv6 = false
+ ipv6_address = (known after apply)
+ locked = (known after apply)
+ memory = (known after apply)
+ monitoring = false
+ name = "bar"
+ price_hourly = (known after apply)
+ price_monthly = (known after apply)
+ private_networking = (known after apply)
+ region = "lon1"
+ resize_disk = true
+ size = "s-1vcpu-1gb"
+ ssh_keys = [
+ "34377800",
]
+ status = (known after apply)
+ urn = (known after apply)
+ user_data = "f9b1d9796d069fe504ce0d89439b6b664b14b1a1"
+ vcpus = (known after apply)
+ volume_ids = (known after apply)
+ vpc_uuid = (known after apply)
}
# digitalocean_droplet.foo (foo) será criado
+ resource "digitalocean_droplet" "foo" {
+ backups = false
+ created_at = (known after apply)
+ disk = (known after apply)
+ graceful_shutdown = false
+ id = (known after apply)
+ image = "ubuntu-20-04-x64"
+ ipv4_address = (known after apply)
+ ipv4_address_private = (known after apply)
+ ipv6 = false
+ ipv6_address = (known after apply)
+ locked = (known after apply)
+ memory = (known after apply)
+ monitoring = false
+ name = "foo"
+ price_hourly = (known after apply)
+ price_monthly = (known after apply)
+ private_networking = (known after apply)
+ region = "lon1"
+ resize_disk = true
+ size = "s-1vcpu-1gb"
+ ssh_keys = [
+ "34377800",
]
+ status = (known after apply)
+ urn = (known after apply)
+ user_data = "f9b1d9796d069fe504ce0d89439b6b664b14b1a1"
+ vcpus = (known after apply)
+ volume_ids = (known after apply)
+ vpc_uuid = (known after apply)
}
# digitalocean_loadbalancer.lb (lb) será criado
+ resource "digitalocean_loadbalancer" "lb" {
+ algorithm = "round_robin"
+ disable_lets_encrypt_dns_records = false
+ droplet_ids = (known after apply)
+ enable_backend_keepalive = false
+ enable_proxy_protocol = false
+ id = (known after apply)
+ ip = (known after apply)
+ name = "default"
+ redirect_http_to_https = false
+ region = "lon1"
+ size_unit = (known after apply)
+ status = (known after apply)
+ urn = (known after apply)
+ vpc_uuid = (known after apply)
+ forwarding_rule {
+ certificate_id = (known after apply)
+ certificate_name = (known after apply)
+ entry_port = 80
+ entry_protocol = "http"
+ target_port = 80
+ target_protocol = "http"
+ tls_passthrough = false
}
+ healthcheck {
+ check_interval_seconds = (known after apply)
+ healthy_threshold = (known after apply)
+ path = (known after apply)
+ port = (known after apply)
+ protocol = (known after apply)
+ response_timeout_seconds = (known after apply)
+ unhealthy_threshold = (known after apply)
}
+ sticky_sessions {
+ cookie_name = (known after apply)
+ cookie_ttl_seconds = (known after apply)
+ type = (known after apply)
}
}
Plan: 3 to add, 0 to change, 0 to destroy.
─────────────────────────────────────────────────────────────────────────────
Saved the plan to: plan
To perform exactly these actions, run the following command to apply:
terraform apply "plan"
Please review the diff output above for infra
❯ Approve Applies the changes outlined in the plan.
Dismiss
Stop
Nota: CDKTF ainda está sendo desenvolvido e a saída pode diferir da mostrada acima.
Esta exibição lista todos os recursos e propriedades que cdktf
planeja criar, atualizar e destruir. Alguns valores, como o ID de um Droplet, só são conhecidos após o provisionamento do recurso. Para esses, você verá (conhecido após aplicar)
como o valor da propriedade na saída.
Revise a lista de recursos para garantir que seja o que você espera. Em seguida, use as teclas de seta para selecionar a opção Aprovar e pressione ENTER
.
Você verá uma saída semelhante à seguinte:
Outputinfra digitalocean_droplet.foo (foo): Creating...
digitalocean_droplet.bar (bar): Creating...
infra digitalocean_droplet.bar (bar): Still creating... [10s elapsed]
infra digitalocean_droplet.foo (foo): Still creating... [10s elapsed]
1 Stack deploying 0 Stacks done 0 Stacks waiting
Esta saída informa que cdktf
está se comunicando com a API do DigitalOcean para criar o Droplet. cdktf
está criando os Droplets primeiro porque o balanceador de carga depende do ID do Droplet, que é desconhecido até que os Droplets sejam provisionados.
A criação do Droplet geralmente leva menos de um minuto. Depois que os Droplets são provisionados, cdktf
passa a criar o balanceador de carga.
Outputinfra digitalocean_droplet.bar (bar): Creation complete after 54s [id=298041598]
infra digitalocean_droplet.foo (foo): Creation complete after 55s [id=298041600]
infra digitalocean_loadbalancer.lb (lb): Creating...
infra digitalocean_loadbalancer.lb (lb): Still creating... [10s elapsed]
O balanceador de carga pode demorar mais. Após a criação do balanceador de carga, você verá um resumo que mostra que a pilha foi implantada com sucesso.
Outputinfra digitalocean_loadbalancer.lb (lb): Still creating... [1m30s elapsed]
infra digitalocean_loadbalancer.lb (lb): Creation complete after 1m32s [id=4f9ae2b7-b649-4fb4-beed-96b95bb72dd1]
infra
Apply complete! Resources: 3 added, 0 changed, 0 destroyed.
No outputs found.
Agora você pode visitar o console do DigitalOcean, onde pode ver um balanceador de carga chamado default
e dois Droplets saudáveis chamados foo
e bar
, cada um servindo como um alvo para o balanceador de carga.
Você pode testar se o NGINX está funcionando e servindo conteúdo corretamente visitando o endereço IP de cada Droplet. Você deve ver um texto semelhante ao seguinte:
Droplet: bar, IP Address: droplet_ip
Se você não vir essa string de texto ou o servidor não estiver respondendo, verifique se os dados do usuário que você especificou estão corretos e que nenhum caractere (incluindo novas linhas) antecede o shebang (#!
). Você também pode fazer SSH no Droplet usando sua chave privada SSH e revisar os logs de saída gerados por CloudInit em /var/log/cloud-init-output.log
:
Uma vez que você tenha confirmado que os Droplets estão ativos e servindo conteúdo, você pode começar a testar o balanceador de carga. Você faz isso enviando alguns pedidos.
Execute o seguinte comando a partir do seu terminal para enviar dez pedidos ao balanceador de carga:
Você deve ver uma saída semelhante ao seguinte, embora os endereços IP mostrados possam ser diferentes:
OutputDroplet: foo, IP Address: droplet_foo_ip
Droplet: bar, IP Address: droplet_bar_ip
Droplet: foo, IP Address: droplet_foo_ip
Droplet: bar, IP Address: droplet_bar_ip
Droplet: bar, IP Address: droplet_bar_ip
Droplet: foo, IP Address: droplet_foo_ip
Droplet: bar, IP Address: droplet_bar_ip
Droplet: foo, IP Address: droplet_foo_ip
Droplet: bar, IP Address: droplet_bar_ip
Droplet: foo, IP Address: droplet_foo_ip
Isso mostra que os pedidos ao balanceador de carga foram encaminhados para cada Droplet cinco vezes, indicando que o balanceador de carga está funcionando.
Nota: O balanceador de carga pode não sempre equilibrar entre os dois Droplets perfeitamente; você pode descobrir que quatro pedidos foram enviados para um Droplet e seis para o outro. Esse comportamento é normal.
Neste passo, você usou cdktf
para provisionar seus recursos e depois usou o console da DigitalOcean para descobrir os endereços IP de seus Droplets e balanceador de carga. Em seguida, você enviou pedidos para cada Droplet e balanceador de carga para confirmar que eles funcionam.
No próximo passo, você obterá os endereços IP dos Droplets e do balanceador de carga sem fazer login no console da DigitalOcean.
Passo 8 — Saída de Informações
No passo anterior, você teve que fazer login no Console da DigitalOcean para obter os endereços IP do seu Droplet e do balanceador de carga. Neste passo, você modificará seu código ligeiramente para que essas informações sejam impressas na saída do comando cdktf deploy
, economizando uma viagem ao console.
O Terraform registra a configuração e o estado de seus recursos gerenciados em arquivos de estado. Para sua pilha infra
, o arquivo de estado pode ser encontrado em infra/terraform.infra.tfstate
. Você poderá encontrar os endereços IP dos Droplets e do balanceador de carga dentro deste arquivo de estado.
No entanto, percorrer um arquivo grande pode ser inconveniente. O CDKTF fornece o construtor TerraformOutput
, que você pode usar para produzir variáveis e torná-las disponíveis fora da pilha. Quaisquer saídas são impressas em stdout
após a execução de cdktf deploy
. A execução de cdktf output
também pode imprimir saídas a qualquer momento.
Nota: Embora você use apenas saídas para imprimir informações no console neste tutorial, seu verdadeiro poder vem de pilhas usando saídas de outras pilhas como entrada, um recurso conhecido como referências entre pilhas.
Atualize o arquivo main.ts
para incluir saídas dos endereços IP do balanceador de carga e dos Droplets:
Salve e feche o arquivo.
Execute cdktf deploy
para concretizar a mudança:
Dentro da saída, você deve ver algo semelhante ao seguinte:
Output─────────────────────────────────────────────────────────────────────────────
Changes to Outputs:
+ droplet0IP = "droplet_foo_ip"
+ droplet1IP = "droplet_bar_ip"
+ loadBalancerIP = "load_balancer_ip"
You can apply this plan to save these new output values to the Terraform
state, without changing any real infrastructure.
─────────────────────────────────────────────────────────────────────────────
Esse resultado informa que não serão feitas alterações na infraestrutura, apenas o que é produzido pela pilha.
Use as setas para selecionar Aprovar e, em seguida, pressione ENTER
. No final da saída do terminal, você deve ver algo semelhante a:
Outputinfra
droplet0IP = droplet_foo_ip
droplet1IP = droplet_bar_ip
loadBalancerIP = load_balancer_ip
Agora, cada vez que você executar cdktf deploy
ou cdktf output
, o endereço IP dos Droplets e dos balanceadores de carga são impressos na saída do terminal, eliminando a necessidade de acessar essas informações pelo console da DigitalOcean.
Você agora provisionou dois Droplets e um balanceador de carga e confirmou que eles estão funcionando. Você pode usar o projeto CDKTF que desenvolveu como base para definir uma infraestrutura mais sofisticada (você pode encontrar uma implementação de referência em do-community / digitalocean-cdktf-typescript
).
Os recursos provisionados neste tutorial incorrerão em cobrança. Se você não pretende usar a infraestrutura criada, deve destruí-la. No próximo e último passo, você limpará o projeto destruindo os recursos criados neste tutorial.
Passo 9 — Destruindo Sua Infraestrutura
Neste passo, você removerá todos os recursos criados neste tutorial.
Ainda dentro da pasta infra/
, execute cdktf destroy
:
Você deve ver uma saída semelhante à seguinte:
Outputinfra Initializing the backend...
infra Initializing provider plugins...
infra - Reusing previous version of digitalocean/digitalocean from the dependency lock file
infra - Using previously-installed digitalocean/digitalocean v2.19.0
infra Terraform has been successfully initialized!
infra digitalocean_droplet.bar (bar): Refreshing state... [id=298041598]
digitalocean_droplet.foo (foo): Refreshing state... [id=298041600]
infra digitalocean_loadbalancer.lb (lb): Refreshing state... [id=4f9ae2b7-b649-4fb4-beed-96b95bb72dd1]
infra Terraform used the selected providers to generate the following execution
plan. Resource actions are indicated with the following symbols:
- destroy
Terraform will perform the following actions:
infra # digitalocean_droplet.bar (bar) will be destroyed
- resource "digitalocean_droplet" "bar" {
- backups = false -> null
- created_at = "2022-05-02T10:04:16Z" -> null
- disk = 25 -> null
- graceful_shutdown = false -> null
- id = "298041598" -> null
- image = "ubuntu-20-04-x64" -> null
- ipv4_address = "droplet_bar_public_ip" -> null
- ipv4_address_private = "droplet_bar_private_ip" -> null
- ipv6 = false -> null
- locked = false -> null
- memory = 1024 -> null
- monitoring = false -> null
- name = "bar" -> null
- price_hourly = 0.00744 -> null
- price_monthly = 5 -> null
- private_networking = true -> null
- region = "lon1" -> null
- resize_disk = true -> null
- size = "s-1vcpu-1gb" -> null
- ssh_keys = [
- "34377800",
] -> null
- status = "active" -> null
- tags = [] -> null
- urn = "do:droplet:298041598" -> null
- user_data = "f9b1d9796d069fe504ce0d89439b6b664b14b1a1" -> null
- vcpus = 1 -> null
- volume_ids = [] -> null
- vpc_uuid = "bed80b32-dc82-11e8-83ec-3cfdfea9f3f0" -> null
}
# digitalocean_droplet.foo (foo) será destruído
- resource "digitalocean_droplet" "foo" {
- backups = false -> null
- created_at = "2022-05-02T10:04:16Z" -> null
- disk = 25 -> null
- graceful_shutdown = false -> null
- id = "298041600" -> null
- image = "ubuntu-20-04-x64" -> null
- ipv4_address = "droplet_foo_public_ip" -> null
- ipv4_address_private = "droplet_foo_private_ip" -> null
- ipv6 = false -> null
- locked = false -> null
- memory = 1024 -> null
- monitoring = false -> null
- name = "foo" -> null
- price_hourly = 0.00744 -> null
- price_monthly = 5 -> null
- private_networking = true -> null
- region = "lon1" -> null
- resize_disk = true -> null
- size = "s-1vcpu-1gb" -> null
- ssh_keys = [
- "34377800",
] -> null
- status = "active" -> null
- tags = [] -> null
- urn = "do:droplet:298041600" -> null
- user_data = "f9b1d9796d069fe504ce0d89439b6b664b14b1a1" -> null
- vcpus = 1 -> null
- volume_ids = [] -> null
- vpc_uuid = "bed80b32-dc82-11e8-83ec-3cfdfea9f3f0" -> null
}
# digitalocean_loadbalancer.lb (lb) será destruído
- resource "digitalocean_loadbalancer" "lb" {
- algorithm = "round_robin" -> null
- disable_lets_encrypt_dns_records = false -> null
- droplet_ids = [
- 298041598,
- 298041600,
] -> null
- enable_backend_keepalive = false -> null
- enable_proxy_protocol = false -> null
- id = "4f9ae2b7-b649-4fb4-beed-96b95bb72dd1" -> null
- ip = "load_balancer_ip" -> null
- name = "default" -> null
- redirect_http_to_https = false -> null
- region = "lon1" -> null
- size_unit = 1 -> null
- status = "active" -> null
- urn = "do:loadbalancer:4f9ae2b7-b649-4fb4-beed-96b95bb72dd1" -> null
- vpc_uuid = "bed80b32-dc82-11e8-83ec-3cfdfea9f3f0" -> null
- forwarding_rule {
- entry_port = 80 -> null
- entry_protocol = "http" -> nul
infra l
- target_port = 80 -> null
- target_protocol = "http" -> null
- tls_passthrough = false -> null
}
- healthcheck {
- check_interval_seconds = 10 -> null
- healthy_threshold = 5 -> null
- path = "/" -> null
- port = 80 -> null
- protocol = "http" -> null
- response_timeout_seconds = 5 -> null
- unhealthy_threshold = 3 -> null
}
- sticky_sessions {
- cookie_ttl_seconds = 0 -> null
- type = "none" -> null
}
}
Plan: 0 to add, 0 to change, 3 to destroy.
─────────────────────────────────────────────────────────────────────────────
Saved the plan to: plan
To perform exactly these actions, run the following command to apply:
terraform apply "plan"
Please review the diff output above for infra
❯ Approve Applies the changes outlined in the plan.
Dismiss
Stop
Desta vez, em vez de mostrar +
ao lado de cada recurso, ele mostra -
, indicando que o CDKTF planeja destruir o recurso. Examine as alterações propostas e, em seguida, use as teclas de seta para selecionar Aprovar e pressione ENTER
. O provedor DigitalOcean agora se comunicará com a API do DigitalOcean para destruir os recursos.
Outputinfra digitalocean_loadbalancer.lb (lb): Destroying... [id=4f9ae2b7-b649-4fb4-beed-96b95bb72dd1]
infra digitalocean_loadbalancer.lb (lb): Destruction complete after 1s
infra digitalocean_droplet.bar (bar): Destroying... [id=298041598]
digitalocean_droplet.foo (foo): Destroying... [id=298041600]
O balanceador de carga foi excluído primeiro porque não possui dependências (nenhum outro recurso referencia o balanceador de carga em suas entradas). Como o balanceador de carga referencia os Droplets, eles só podem ser destruídos após o balanceador de carga ser destruído.
Após os recursos terem sido destruídos, você verá a seguinte linha impressa na saída:
OutputDestroy complete! Resources: 3 destroyed.
Conclusão
Neste tutorial, você usou o CDKTF para provisionar e destruir uma página web com balanceamento de carga, consistindo em dois Droplets do DigitalOcean executando servidores NGINX, servidos atrás de um balanceador de carga. Você também exibiu informações sobre os recursos no terminal.
CDKTF é uma camada de abstração acima do Terraform. Uma boa compreensão do Terraform é útil para entender o CDKTF. Se você gostaria de aprender mais sobre o Terraform, você pode ler a série Como Gerenciar Infraestrutura com Terraform, que cobre o Terraform em profundidade.
Você também pode conferir a documentação oficial do CDK for Terraform e os tutoriais para aprender mais sobre o CDKTF.