Implantação de serviços distribuídos na Yandex.Cloud com o exemplo do Grafana

Olá a todos! Como parte do meu trabalho de curso, eu estudei as possibilidades de uma plataforma de nuvem nacional como Yandex.Cloud. A plataforma oferece vários serviços para resolver questões práticas. Porém, às vezes é necessário configurar seu próprio aplicativo em nuvem com uma infraestrutura razoavelmente complexa com base nesses serviços. Neste artigo, quero compartilhar a experiência de implantar tal aplicativo.

Implantação de serviços distribuídos na Yandex.Cloud com o exemplo do Grafana

O que se deseja obter?

Grafana — uma ferramenta poderosa para resolver tarefas analíticas ou monitorar sistemas. Na sua configuração básica, é uma máquina virtual com um servidor web Grafana, além de um banco de dados (ClickHouse, InfluxDB, etc.) com um conjunto de dados, sobre o qual será construída a análise.

Após iniciar a máquina virtual com o servidor web, pode-se acessar seu host e obter uma interface bonita, especificar bancos de dados como fontes para trabalho futuro, criar dashboards e gráficos.

Implantação de serviços distribuídos na Yandex.Cloud com o exemplo do Grafana

A versão básica tem uma desvantagem significativa — ela não é tolerante a falhas. Isso significa que toda a funcionalidade do aplicativo depende da viabilidade de uma única máquina virtual. Se ela falhar ou se 10 pessoas abrirem a interface simultaneamente, surgirão problemas.

Esses problemas são resolvidos facilmente: basta... implantar várias máquinas virtuais idênticas com servidor web e colocá-las sob um balanceador L3. Mas aqui a situação não é tão simples. O Grafana armazena as configurações do usuário (caminhos para bancos de dados, dashboards, gráficos, etc.) diretamente no disco de sua máquina virtual. Assim, se você alterar algumas configurações na interface, essas alterações só se refletirão na máquina virtual para a qual o balanceador nos direcionou. Isso levará a configurações inconsistentes do nosso aplicativo, resultando em problemas de inicialização e uso.

Para isso, uma outra base de dados, como o MySQL ou um de seus análogos, pode ajudar. Dizemos ao Grafana que ele deve armazenar as configurações do usuário exatamente nessa "base de dados de reserva". Depois, basta indicar uma vez o caminho para esse BD em cada máquina, e todas as outras configurações de usuário podem ser editadas em qualquer uma das máquinas virtuais, que se propagarão para as demais.

Eis o esquema da infraestrutura final do aplicativo:

Implantação de serviços distribuídos na Yandex.Cloud com o exemplo do Grafana

Vamos aprender a levantar manualmente

MySQL e ClickHouse

Antes de implantar um aplicativo assim com o pressionar de um botão, era necessário aprender a levantar manualmente cada um de seus componentes e integrá-los uns aos outros.

Aqui o Yandex.Cloud nos ajuda, fornecendo balanceadores L3, ClickHouse e MySQL como serviços gerenciados. O usuário só precisa informar os parâmetros e aguardar enquanto a plataforma coloca tudo em funcionamento.

Eu me registrei, criei um cloud e uma conta de pagamento. Depois, entrei no cloud e levantei clusters MySQL e ClickHouse com configurações mínimas. Esperei até que eles se tornassem ativos.

Implantação de serviços distribuídos na Yandex.Cloud com o exemplo do GrafanaImplantação de serviços distribuídos na Yandex.Cloud com o exemplo do Grafana

Também não devemos esquecer de criar um banco de dados em cada cluster e configurar o acesso a ele com nome de usuário e senha. Não entrarei em detalhes aqui — a interface é bastante intuitiva.

Um detalhe não tão evidente é que esses bancos de dados têm vários hosts que garantem sua resistência a falhas. No entanto, o Grafana requer exatamente um host para cada banco de dados com o qual trabalha. Leitura prolongada. documentação O cloud me levou a essa solução. Aparentemente, um host do tipo c-.rw.mdb.yandexcloud.net é mapeado para o master host ativo atual do cluster com o ID correspondente. É isso que iremos fornecer ao Grafana.

Servidor web

Agora é a vez do servidor web. Vamos levantar uma máquina virtual comum com Linux e configurar manualmente o Grafana nela.

Implantação de serviços distribuídos na Yandex.Cloud com o exemplo do Grafana

Implantação de serviços distribuídos na Yandex.Cloud com o exemplo do Grafana

Conecte-se via ssh e instale os pacotes necessários.

sudo apt-get install -y apt-transport-https software-properties-common wget
wget -q -O - https://packages.grafana.com/gpg.key | sudo apt-key add -
sudo add-apt-repository "deb https://packages.grafana.com/enterprise/deb stable main"
sudo apt-get update
sudo apt-get install -y grafana-enterprise 

Depois disso, iniciaremos o Grafana sob o systemctl e instalaremos o plugin para trabalhar com ClickHouse (sim, na configuração padrão ele não vem incluído).

sudo systemctl start grafana-server
sudo systemctl enable grafana-server
sudo grafana-cli plugins install vertamedia-clickhouse-datasource

Tudo, após isso, com um simples comando

sudo service grafana-server start

iniciaremos o servidor web. Agora, será possível digitar o IP externo da máquina virtual no navegador, indicar a porta 3000 e visualizar a bela interface do Grafana.
Implantação de serviços distribuídos na Yandex.Cloud com o exemplo do Grafana

Mas não é hora de correr, antes de configurar o Grafana, não se esqueça de indicar o caminho para o MySQL, para armazenar as configurações lá.

Toda a configuração do servidor web do Grafana está no arquivo /etc/grafana/grafana.ini. A linha necessária é assim:

;url =

Conectamos o host ao cluster MySQL. Neste mesmo arquivo estão o login e a senha para acessar o Grafana na imagem acima, ambos iguais por padrão. admin.

Você pode usar os comandos sed:

sudo sed -i "s#.*;url =.*#url = mysql://${MYSQL_USERNAME}:${MYSQL_PASSWORD}@${MYSQL_CLUSTER_URI}#" /etc/grafana/grafana.ini
sudo sed -i "s#.*;admin_user =.*#admin_user = ${GRAFANA_USERNAME}#" /etc/grafana/grafana.ini
sudo sed -i "s#.*;admin_password =.*#admin_password = ${GRAFANA_PASSWORD}#" /etc/grafana/grafana.ini

É hora de reiniciar o servidor web!

sudo service grafana-server restart

Agora, na interface do Grafana, vamos definir o ClickHouse como DataSource.

Consegui uma configuração funcional com as seguintes definições:

Implantação de serviços distribuídos na Yandex.Cloud com o exemplo do Grafana

Usei o seguinte URL https://c-.rw.mdb.yandexcloud.net:8443

Isso! Temos uma máquina virtual funcional com servidor web, conectada ao CH e MySQL. Já podemos carregar o conjunto de dados no ClickHouse e criar dashboards. No entanto, ainda não atingimos nosso objetivo e não implantamos uma infraestrutura completa.

Packer

O Yandex.Cloud permite criar uma imagem de disco de uma máquina virtual existente, e com base nela, quantas máquinas idênticas você precisar. É exatamente isso que vamos fazer. Para facilitar a coleta da imagem, usaremos a ferramenta Packer do HashiCorp. Ela aceita como entrada um arquivo json com instruções para a criação da imagem.

Nosso arquivo json será composto por dois blocos: builders e provisioners. O primeiro bloco descreve os parâmetros da imagem como uma entidade, e o segundo — as instruções para preenchê-la com o conteúdo necessário.

Builders

{
"builders": [
    {
      "type": "yandex",
      "endpoint": "{{user `endpoint`}}",
      "folder_id": "",
      "subnet_id": "{{user `subnet_id`}}",
      "zone": "{{user `zone`}}",
      "labels": {},
      "use_ipv4_nat": true,
      "use_internal_ip": false,
      "service_account_key_file": "",
      "image_name": "grafana-{{timestamp}}",
      "image_family": "grafana",
      "image_labels": {},
      "image_description": "GRAFANA",
      "source_image_family": "ubuntu-1804-lts",
      "disk_size_gb": 3,
      "disk_type": "network-hdd",
      "ssh_username": "ubuntu"
    }
  ],
...
}

Neste modelo, você deve definir o ID da seção na nuvem onde deseja criar a imagem, bem como o caminho para o arquivo com as chaves da conta de serviço, previamente criada nesta seção. Você pode ler mais sobre a criação de contas de serviço e chaves em forma de arquivo na seção correspondente. documentação.

Essa configuração indica que a imagem do disco será criada com base na plataforma ubuntu-1804-lts, colocada na seção correspondente do usuário no grupo de imagens GRAFANA com o nome grafana-{{timestamp}}.

Provisioners

Agora vamos para a parte mais interessante da configuração. Aqui, descreveremos a sequência de ações que devem ser realizadas na máquina virtual antes de congelar seu estado na imagem do disco.

{
...,
"provisioners": [
    {
            "type": "shell",
            "pause_before": "5s",
            "scripts": [
                "prepare-ctg.sh"
            ]
        },
    {
            "type": "file",
            "source": "setup.sh",
            "destination": "\/opt\/grafana\/setup.sh"
        },
        {
            "type": "shell",
        "execute_command": "sudo {{ .Vars }} bash '{{ .Path }}'",
            "pause_before": "5s",
            "scripts": [
                "install-packages.sh",
                "grafana-setup.sh",
                "run-setup-at-reboot.sh"
        ]
        }
  ]
}

Aqui, todas as ações estão divididas em 3 etapas. Na primeira etapa, um simples script é executado para criar um diretório auxiliar.

prepare-ctg.sh:

#!/bin/bash
sudo mkdir -p /opt/grafana
sudo chown -R ubuntu:ubuntu /opt/grafana

Na próxima etapa, colocamos neste diretório um script que deve ser executado logo após o início da máquina virtual. Este script configurará as variáveis de usuário que precisam ser definidas no arquivo de configuração do Grafana e reiniciará o servidor web.

setup.sh:

#!/bin/bash
CLUSTER_ID="<cluster_id>"
USERNAME="<username>"
PASSWORD="<password>"
sudo sed -i "s#.*;url =.*#url = mysql://${USERNAME}:${PASSWORD}@c-${CLUSTER_ID}.rw.mdb.yandexcloud.net#" /etc/grafana/grafana.ini
sudo sed -i "s#.*;admin_user =.*#admin_user = ${USERNAME}#" /etc/grafana/grafana.ini
sudo sed -i "s#.*;admin_password =.*#admin_password = ${PASSWORD}#" /etc/grafana/grafana.ini
sudo service grafana-server restart

Após isso, restam 3 coisas a serem feitas:
1) instalar pacotes
2) iniciar o Grafana pelo systemctl e instalar o plugin ClickHouse
3) adicionar o script setup.sh para ser executado logo após a ativação da máquina virtual.

install-packages.sh:

#!/bin/bash
sudo systemd-run --property='After=apt-daily.service apt-daily-upgrade.service' --wait /bin/true
sudo apt-get install -y apt-transport-https
sudo apt-get install -y software-properties-common wget
wget -q -O - https://packages.grafana.com/gpg.key | sudo apt-key add -
sudo add-apt-repository "deb https://packages.grafana.com/enterprise/deb stable main"
sudo apt-get update
sudo apt-get install -y grafana-enterprise 

grafana-setup.sh:

#!/bin/bash
sudo systemctl start grafana-server
sudo systemctl enable grafana-server
sudo grafana-cli plugins install vertamedia-clickhouse-datasource

run-setup-at-reboot.sh:

#!/bin/bash
chmod +x /opt/grafana/setup.sh
cat > /etc/cron.d/first-boot <<EOF
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games
@reboot root /bin/bash /opt/grafana/setup.sh > /var/log/yc-setup.log 2>&1
EOF
chmod +x /etc/cron.d/first-boot;

Agora, resta iniciar o Packer e, como resultado, obter a imagem colocada na partição especificada. Ao criar a máquina virtual, você pode escolher essa imagem como disco de inicialização e, após o início, terá um servidor web Grafana pronto.

Implantação de serviços distribuídos na Yandex.Cloud com o exemplo do Grafana
Implantação de serviços distribuídos na Yandex.Cloud com o exemplo do Grafana

Grupo de instâncias e balanceador

Após a criação da imagem do disco que permite criar múltiplos servidores web Grafana idênticos, podemos criar um grupo de instâncias. Na plataforma Yandex.Cloud, esse termo se refere a uma reunião de máquinas virtuais com características idênticas. Ao criar um grupo de instâncias, configura-se o protótipo de todas as máquinas nesse grupo, e depois as características do grupo em si (por exemplo, o número mínimo e máximo de máquinas ativas). Se o número atual não corresponder a esses critérios, o grupo de instâncias irá automaticamente remover as máquinas desnecessárias ou criar novas a partir da imagem existente.

No âmbito da nossa tarefa, criaremos um grupo de instâncias de servidores web que serão gerados a partir da imagem de disco criada anteriormente.

Implantação de serviços distribuídos na Yandex.Cloud com o exemplo do Grafana

Implantação de serviços distribuídos na Yandex.Cloud com o exemplo do Grafana

A configuração mais notável do grupo de instâncias. O grupo alvo, em integração com o Load Balancer, permitirá configurar um balanceador L3 em cima das máquinas virtuais desse grupo com apenas alguns cliques.

Implantação de serviços distribuídos na Yandex.Cloud com o exemplo do Grafana

Ao configurar o balanceador, implementei dois pontos importantes:

  1. Configurei o balanceador para receber o tráfego do usuário na porta 80 e redirecioná-lo para a porta 3000 das máquinas virtuais, que é onde o Grafana está hospedado.
  2. Configurei a verificação de viabilidade das máquinas, fazendo ping na porta 3000.

Implantação de serviços distribuídos na Yandex.Cloud com o exemplo do Grafana

Mini-Conclusão

Finalmente conseguimos implantar manualmente a infraestrutura desejada do aplicativo, e agora temos um serviço Grafana altamente disponível. Basta saber o endereço IP do balanceador como ponto de entrada para o aplicativo e o host do cluster ClickHouse para carregar o conjunto de dados.

Parece uma vitória? Sim, uma vitória. Mas algo ainda incomoda. Todo o processo acima exige muitas ações manuais e não é escalável, então gostaria de automatizá-lo tanto quanto possível. Este será o foco da próxima seção.

Integração com Terraform

Vamos mais uma vez usar a ferramenta da HashiCorp chamada Terraform. Ela ajudará a implantar toda a infraestrutura do aplicativo com um clique, com base em algumas variáveis passadas pelo usuário. Vamos escrever uma receita que possa ser executada repetidamente em diferentes seções de diferentes usuários.

Todo o trabalho com Terraform se resume à escrita de um arquivo de configuração (*.tf) e à criação da infraestrutura com base nele.

Variáveis

No início do arquivo, colocaremos as variáveis que determinam onde e como a futura infraestrutura será implantada.

variable "oauth_token" {
    type = string
    default = ""
}
variable "cloud_id" {
    type = string
    default = ""
}
variable "folder_id" {
    type = string
    default = ""
}
variable "service_account_id" {
    type = string
    default = ""
}
variable "image_id" {
    type = string
    default = ""
}
variable "username" {
    type = string
    default = ""
}
variable "password" {
    type = string
    default = ""
}
variable "dbname" {
    type = string
    default = ""
}
variable "public_key_path" {
    type = string
    default = ""
}

Todo o processo de implantação do aplicativo se resumirá à construção da imagem do disco e configuração dessas variáveis. Vou explicar para que elas servem:

oauth_token — token de acesso à nuvem. Pode ser obtido através de link.
cloud_id — identificador da nuvem onde iremos implantar o aplicativo
folder_id — identificador da seção onde iremos implantar o aplicativo
service_account_id — identificador da conta de serviço na seção correspondente da nuvem.
image_id — identificador da imagem do disco obtida com o Packer
nome de usuário e senha — nome de usuário e senha para acesso aos dois bancos de dados e ao servidor web Grafana
dbname — nome do banco de dados dentro dos clusters CH e MySQL
public_key_path — caminho para o arquivo com sua chave ssh pública, pelo qual será possível se conectar como ubuntu a máquinas virtuais com servidores web

Configuração do provedor

Agora precisamos configurar o provedor Terraform — neste caso, Yandex:

provider "yandex" {
  token     = var.oauth_token
  cloud_id  = var.cloud_id
  folder_id = var.folder_id
  zone      = "ru-central1-a"
}

Pode-se notar que aqui usamos variáveis definidas acima.

Rede e clusters

Agora vamos criar uma rede onde os elementos de nossa infraestrutura se comunicam, três sub-redes (uma em cada região) e levantaremos os clusters CH e MySQL.


resource "yandex_vpc_network" "grafana_network" {}

resource "yandex_vpc_subnet" "subnet_a" {
  zone           = "ru-central1-a"
  network_id     = yandex_vpc_network.grafana_network.id
  v4_cidr_blocks = ["10.1.0.0/24"]
}

resource "yandex_vpc_subnet" "subnet_b" {
  zone           = "ru-central1-b"
  network_id     = yandex_vpc_network.grafana_network.id
  v4_cidr_blocks = ["10.2.0.0/24"]
}

resource "yandex_vpc_subnet" "subnet_c" {
  zone           = "ru-central1-c"
  network_id     = yandex_vpc_network.grafana_network.id
  v4_cidr_blocks = ["10.3.0.0/24"]
}

resource "yandex_mdb_clickhouse_cluster" "ch_cluster" {
  name        = "grafana-clickhouse"
  environment = "PRODUÇÃO"
  network_id  = yandex_vpc_network.grafana_network.id

  clickhouse {
    resources {
      resource_preset_id = "s2.micro"
      disk_type_id       = "network-ssd"
      disk_size          = 16
    }
  }

  zookeeper {
    resources {
      resource_preset_id = "s2.micro"
      disk_type_id       = "network-ssd"
      disk_size          = 10
    }
  }

  database {
    name = var.dbname
  }

  user {
    name     = var.username
    password = var.password
    permission {
      database_name = var.dbname
    }
  }

  host {
    type      = "CLICKHOUSE"
    zone      = "ru-central1-a"
    subnet_id = yandex_vpc_subnet.subnet_a.id
  }

  host {
    type      = "CLICKHOUSE"
    zone      = "ru-central1-b"
    subnet_id = yandex_vpc_subnet.subnet_b.id
  }

  host {
    type      = "CLICKHOUSE"
    zone      = "ru-central1-c"
    subnet_id = yandex_vpc_subnet.subnet_c.id
  }

  host {
    type      = "ZOOKEEPER"
    zone      = "ru-central1-a"
    subnet_id = yandex_vpc_subnet.subnet_a.id
  }

  host {
    type      = "ZOOKEEPER"
    zone      = "ru-central1-b"
    subnet_id = yandex_vpc_subnet.subnet_b.id
  }

  host {
    type      = "ZOOKEEPER"
    zone      = "ru-central1-c"
    subnet_id = yandex_vpc_subnet.subnet_c.id
  }
}

resource "yandex_mdb_mysql_cluster" "mysql_cluster" {
  name        = "grafana_mysql"
  environment = "PRODUÇÃO"
  network_id  = yandex_vpc_network.grafana_network.id
  version     = "8.0"

  resources {
    resource_preset_id = "s2.micro"
    disk_type_id       = "network-ssd"
    disk_size          = 16
  }

  database {
    name = var.dbname
  }

  user {
    name     = var.username
    password = var.password
    permission {
      database_name = var.dbname
      roles         = ["TODOS"]
    }
  }

  host {
    zone      = "ru-central1-a"
    subnet_id = yandex_vpc_subnet.subnet_a.id
  }
  host {
    zone      = "ru-central1-b"
    subnet_id = yandex_vpc_subnet.subnet_b.id
  }
  host {
    zone      = "ru-central1-c"
    subnet_id = yandex_vpc_subnet.subnet_c.id
  }
}

Como pode ser visto, cada um dos dois clusters é criado de forma bastante resiliente, dispostos em três zonas de disponibilidade.

Servidores web

À primeira vista, poderia continuar assim, mas enfrentei uma dificuldade. Anteriormente, eu primeiro levantava o cluster MySQL e só depois, sabendo seu ID, montava a imagem do disco com a configuração necessária, onde indicava o host do cluster. Mas agora não sabemos o ID do cluster até a execução do Terraform, incluindo no momento de montagem da imagem. Por isso, tive que recorrer ao seguinte truque.

Usando o serviço de metadados da Amazon, iremos passar alguns parâmetros para a máquina virtual, que serão recebidos e processados por ela. Precisamos que, após a inicialização, a máquina acesse os metadados para o host do cluster MySQL e para o nome de usuário e senha que o usuário especificou no arquivo Terraform. Faremos algumas pequenas alterações no conteúdo do arquivo setup.sh, que é executado ao ligar a máquina virtual.

setup.sh:

#!/bin/bash
CLUSTER_URI="$(curl -H 'Metadata-Flavor:Google' http://169.254.169.254/computeMetadata/v1/instance/attributes/mysql_cluster_uri)"
USERNAME="$(curl -H 'Metadata-Flavor:Google' http://169.254.169.254/computeMetadata/v1/instance/attributes/username)"
PASSWORD="$(curl -H 'Metadata-Flavor:Google' http://169.254.169.254/computeMetadata/v1/instance/attributes/password)"
sudo sed -i "s#.*;url =.*#url = mysql://${USERNAME}:${PASSWORD}@${CLUSTER_URI}#" /etc/grafana/grafana.ini
sudo sed -i "s#.*;admin_user =.*#admin_user = ${USERNAME}#" /etc/grafana/grafana.ini
sudo sed -i "s#.*;admin_password =.*#admin_password = ${PASSWORD}#" /etc/grafana/grafana.ini
sudo service grafana-server restart

Grupo de instâncias e balanceador

Após reconstruir a nova imagem do disco, finalmente podemos adicionar nosso arquivo para o Terraform.

Vamos indicar que queremos usar uma imagem de disco existente:

data "yandex_compute_image" "grafana_image" {
  image_id = var.image_id
}

Agora vamos criar o grupo de instâncias:

resource "yandex_compute_instance_group" "grafana_group" {
  name               = "grafana-group"
  folder_id          = var.folder_id
  service_account_id = var.service_account_id
  instance_template {
    platform_id = "standard-v1"
    resources {
      memory = 1
      cores  = 1
    }
    boot_disk {
      mode = "READ_WRITE"
      initialize_params {
        image_id = data.yandex_compute_image.grafana_image.id
        size     = 4
      }
    }
    network_interface {
      network_id = yandex_vpc_network.grafana_network.id
      subnet_ids = [yandex_vpc_subnet.subnet_a.id, yandex_vpc_subnet.subnet_b.id, yandex_vpc_subnet.subnet_c.id]
      nat = "true"
    }
    metadata = {
      mysql_cluster_uri = "c-${yandex_mdb_mysql_cluster.mysql_cluster.id}.rw.mdb.yandexcloud.net:3306/${var.dbname}"
      username = var.username
      password = var.password
      ssh-keys = "ubuntu:${file("${var.public_key_path}")}"
    }
    network_settings {
      type = "STANDARD"
    }
  }

  scale_policy {
    fixed_scale {
      size = 6
    }
  }

  allocation_policy {
    zones = ["ru-central1-a", "ru-central1-b", "ru-central1-c"]
  }

  deploy_policy {
    max_unavailable = 2
    max_creating    = 2
    max_expansion   = 2
    max_deleting    = 2
  }

  load_balancer {
    target_group_name = "grafana-target-group"
  }
}

Vale a pena notar como passamos para os metadados cluster_uri, nome de usuário e senha. É isso que a máquina virtual irá buscar e colocar na configuração do Grafana ao ser iniciada.

Agora é a vez do balanceador.

resource "yandex_lb_network_load_balancer" "grafana_balancer" {
  name = "grafana-balancer"

  listener {
    name = "grafana-listener"
    port = 80
    target_port = 3000
    external_address_spec {
      ip_version = "ipv4"
    }
  }

  attached_target_group {
    target_group_id = yandex_compute_instance_group.grafana_group.load_balancer.0.target_group_id

    healthcheck {
      name = "healthcheck"
      tcp_options {
        port = 3000
      }
    }
  }
}

Um pouco de açúcar

Restou apenas um pequeno detalhe. Depois que a infraestrutura for levantada, será necessário acessar a interface do Grafana e adicionar manualmente o cluster CH (cujo ID ainda precisamos obter) como fonte de dados. Mas o Terraform sabe o ID do cluster. Vamos confiar a ele a conclusão desse trabalho.

Vamos adicionar um novo provedor — Grafana, e vamos usar o IP do balanceador como host. Todas as alterações que o Terraform fizer na máquina, para a qual o balanceador o direcionar, serão refletidas no MySQL e, portanto, em todas as outras máquinas.

provider "grafana" {
  url  = "http://${[for s in yandex_lb_network_load_balancer.grafana_balancer.listener: s.external_address_spec.0.address].0}"
  auth = "${var.username}:${var.password}"
}

resource "grafana_data_source" "ch_data_source" {
  type          = "vertamedia-clickhouse-datasource"
  name          = "grafana"
  url           = "https://c-${yandex_mdb_clickhouse_cluster.ch_cluster.id}.rw.mdb.yandexcloud.net:8443"
  basic_auth_enabled = "true"
  basic_auth_username = var.username
  basic_auth_password = var.password
  is_default = "true"
  access_mode = "proxy"
}

Vamos pentear.

Vamos extrair o IP do balanceador e o host do cluster ClickHouse.

output "grafana_balancer_ip_address" {
  value = [for s in yandex_lb_network_load_balancer.grafana_balancer.listener: s.external_address_spec.0.address].0
}

output "clickhouse_cluster_host" {
  value = "https://c-${yandex_mdb_clickhouse_cluster.ch_cluster.id}.rw.mdb.yandexcloud.net:8443"
}

Pode iniciar.

Pronto! Nosso arquivo de configuração está pronto e, ao definir as variáveis, podemos informar ao Terraform para levantar tudo o que descrevemos acima. Todo o processo levou cerca de 15 minutos.
No final, podemos ver uma mensagem bonita:

Aplicação completa! Recursos: 9 adicionados, 0 alterados, 0 destruídos.
Saídas:

clickhouse_cluster_host = https://c-c9q14ipa2ngadqsbp2iq.rw.mdb.yandexcloud.net:8443
grafana_balancer_ip_address = 130.193.50.25

E na nuvem os elementos da infraestrutura levantada serão visíveis:

Implantação de serviços distribuídos na Yandex.Cloud com o exemplo do Grafana

Resumindo

Agora, com o exemplo do Grafana, cada um de vocês aprendeu a implantar aplicativos com uma arquitetura em nuvem robusta na plataforma Yandex.Cloud. Ferramentas úteis da HashiCorp, como Packer e Terraform, podem ajudar nisso. Espero que este artigo seja útil para alguém 🙂

P.S. Abaixo, adicionarei um link para o repositório onde é possível encontrar receitas prontas para Packer e Terraform, cujos trechos eu trouxe neste artigo.

Repositório

Fonte: habr.com

Compre hospedagem confiável para sites com proteção contra DDoS, servidores VPS VDS 🔥 Compre hospedagem confiável para sites com proteção contra DDoS, servidores VPS VDS | ProHoster