One place for hosting & domains

      How To Manage and Use MySQL Database Triggers on Ubuntu 18.04

      The author selected the the Apache Software Foundation to receive a donation as part of the Write for DOnations program.


      In MySQL a trigger is a user-defined SQL command that is invoked automatically during an INSERT, DELETE, or UPDATE operation. The trigger code is associated with a table and is destroyed once a table is dropped. You can specify a trigger action time and set whether it will be activated before or after the defined database event.

      Triggers have several advantages. For instance, you can use them to generate the value of a derived column during an INSERT statement. Another use case is enforcing referential integrity where you can use a trigger to save a record to multiple related tables. Other benefits include logging user actions to audit tables as well as live-copying data across different database schemas for redundancy purposes to prevent a single point of failure.

      You can also use triggers to keep validation rules at the database level. This helps in sharing the data source across multiple applications without breaking the business logic. This greatly reduces round-trips to the database server, which therefore improves the response time of your applications. Since the database server executes triggers, they can take advantage of improved server resources such as RAM and CPU.

      In this tutorial, you’ll create, use, and delete different types of triggers on your MySQL database.


      Before you begin, make sure you have the following:

      Step 1 — Creating a Sample Database

      In this step, you’ll create a sample customer database with multiple tables for demonstrating how MySQL triggers work.

      To understand more about MySQL queries read our Introduction to Queries in MySQL.

      First, log in to your MySQL server as root:

      Enter your MySQL root password when prompted and hit ENTER to continue. When you see the mysql> prompt, run the following command to create a test_db database:


      Query OK, 1 row affected (0.00 sec)

      Next, switch to the test_db with:


      Database changed

      You’ll start by creating a customers table. This table will hold the customers’ records including the customer_id, customer_name, and level. There will be two customer levels: BASIC and VIP.

      • Create table customers(customer_id BIGINT PRIMARY KEY, customer_name VARCHAR(50), level VARCHAR(50) ) ENGINE=INNODB;


      Query OK, 0 rows affected (0.01 sec)

      Now, add a few records to the customers table. To do this, run the following commands one by one:

      • Insert into customers (customer_id, customer_name, level )values('1','JOHN DOE','BASIC');
      • Insert into customers (customer_id, customer_name, level )values('2','MARY ROE','BASIC');
      • Insert into customers (customer_id, customer_name, level )values('3','JOHN DOE','VIP');

      You’ll see the following output after running each of the INSERT commands:


      Query OK, 1 row affected (0.01 sec)

      To make sure that the sample records were inserted successfully, run the SELECT command:


      +-------------+---------------+-------+ | customer_id | customer_name | level | +-------------+---------------+-------+ | 1 | JOHN DOE | BASIC | | 2 | MARY ROE | BASIC | | 3 | JOHN DOE | VIP | +-------------+---------------+-------+ 3 rows in set (0.00 sec)

      You’ll also create another table for holding related information about the customers account. The table will have a customer_id and status_notes fields.

      Run the following command:

      • Create table customer_status(customer_id BIGINT PRIMARY KEY, status_notes VARCHAR(50)) ENGINE=INNODB;

      Next, you’ll create a sales table. This table will hold sales data related to the different customers through the customer_id column:

      • Create table sales(sales_id BIGINT PRIMARY KEY, customer_id BIGINT, sales_amount DOUBLE ) ENGINE=INNODB;


      Query OK, 0 rows affected (0.01 sec)

      You’ll add sample data to the sales data in the coming steps while testing the triggers. Next, create an audit_log table to log updates made to the sales table when you implement the AFTER UPDATE trigger in Step 5:

      • Create table audit_log(log_id BIGINT PRIMARY KEY AUTO_INCREMENT, sales_id BIGINT, previous_amount DOUBLE, new_amount DOUBLE, updated_by VARCHAR(50), updated_on DATETIME ) ENGINE=INNODB;


      Query OK, 0 rows affected (0.02 sec)

      With the test_db database and the four tables in place, you’ll now move on to work with the different MySQL triggers in your database.

      Step 2 — Creating a Before Insert Trigger

      In this step, you’ll examine the syntax of a MySQL trigger before applying this logic to create a BEFORE INSERT trigger that validates the sales_amount field when data is inserted into the sales table.

      The general syntax for creating a MySQL trigger is shown in the following example:

      DELIMITER //
      ON [TABLE]
      [TRIGGER BODY]//

      The structure of the trigger includes:

      DELIMITER //: The default MySQL delimiter is ;—it’s necessary to change it to something else in order for MySQL to treat the following lines as one command until it hits your custom delimiter. In this example, the delimiter is changed to // and then the ; delimiter is redefined at the end.

      [TRIGGER_NAME]: A trigger must have a name and this is where you include the value.

      [TRIGGER TIME]: A trigger can be invoked during different timings. MySQL allows you to define if the trigger will initiate before or after a database operation.

      [TRIGGER EVENT]: Triggers are only invoked by INSERT, UPDATE, and DELETE operations. You can use any value here depending on what you want to achieve.

      [TABLE]: Any trigger that you create on your MySQL database must be associated with a table.

      FOR EACH ROW: This statement tells MySQL to execute the trigger code for every row that the trigger affects.

      [TRIGGER BODY]: The code that is executed when the trigger is invoked is called a trigger body. This can be a single SQL statement or multiple commands. Note that if you are executing multiple SQL statements on the trigger body, you must wrap them between a BEGIN...END block.

      Note: When creating the trigger body, you can use the OLD and NEW keywords to access the old and new column values entered during an INSERT, UPDATE, and DELETE operation. In a DELETE trigger, only the OLD keyword can be used (which you’ll use in Step 4).

      Now you’ll create your first BEFORE INSERT trigger. This trigger will be associated with the sales table and it will be invoked before a record is inserted to validate the sales_amount. The function of the trigger is to check if the sales_amount being inserted to the sales table is greater than 10000 and raise an error if this evaluates to true.

      Make sure you’re logged in to the MySQL server. Then, enter the following MySQL commands one by one:

      • DELIMITER //
      • CREATE TRIGGER validate_sales_amount
      • ON sales
      • FOR EACH ROW
      • IF NEW.sales_amount>10000 THEN
      • SIGNAL SQLSTATE '45000'
      • SET MESSAGE_TEXT = 'Sale has exceeded the allowed amount of 10000.';
      • END IF//
      • DELIMITER ;

      You’re using the IF...THEN...END IF statement to evaluate if the amount being supplied during the INSERT statement is within your range. The trigger is able to extract the new sales_amount value being supplied by using the NEW keyword.

      To raise a generic error message, you use the following lines to inform the user about the error:

      SIGNAL SQLSTATE '45000'
      SET MESSAGE_TEXT = 'Sale has exceeded the allowed amount of 10000.';

      Next, insert a record with a sales_amount of 11000 to the sales table to check if the trigger will stop the operation:

      • Insert into sales(sales_id, customer_id, sales_amount) values('1','1','11000');


      ERROR 1644 (45000): Sale has exceeded the allowed amount of 10000.

      This error shows that the trigger code is working as expected.

      Now try a new record with a value of 7500 to check if the command will be successful:

      • Insert into sales(sales_id, customer_id, sales_amount) values('1','1','7500');

      Since the value is within the recommended range, you’ll see the following output:


      Query OK, 1 row affected (0.01 sec)

      To confirm that the data was inserted run the following command:

      The output confirms that the data is in the table:


      +----------+-------------+--------------+ | sales_id | customer_id | sales_amount | +----------+-------------+--------------+ | 1 | 1 | 7500 | +----------+-------------+--------------+ 1 row in set (0.00 sec)

      In this step you’ve tested triggers to validate data before insertion into a database.

      Next, you’ll work with the AFTER INSERT trigger to save related information into different tables.

      Step 3 — Creating an After Insert Trigger

      AFTER INSERT triggers are executed when records are successfully inserted into a table. This functionality can be used to run other business-related logics automatically. For instance, in a bank application, an AFTER INSERT trigger can close a loan account when a customer finishes paying off the loan. The trigger can monitor all payments inserted to a transaction table and close the loan automatically once the loan balance is zero.

      In this step, you’ll work with your customer_status table by using an AFTER INSERT trigger to enter related customer records.

      To create the AFTER INSERT trigger, enter the following commands:

      • DELIMITER //
      • CREATE TRIGGER customer_status_records
      • ON customers
      • FOR EACH ROW
      • Insert into customer_status(customer_id, status_notes) VALUES(NEW.customer_id, 'ACCOUNT OPENED SUCCESSFULLY')//
      • DELIMITER ;


      Query OK, 0 rows affected (0.00 sec)

      Here you instruct MySQL to save another record to the customer_status table once a new customer record is inserted to the customers table.

      Now, insert a new record in the customers table to confirm your trigger code will be invoked:

      • Insert into customers (customer_id, customer_name, level )values('4','DAVID DOE','VIP');


      Query OK, 1 row affected (0.01 sec)

      Since the record was inserted successfully, check that a new status record was inserted into the customer_status table:

      • Select * from customer_status;


      +-------------+-----------------------------+ | customer_id | status_notes | +-------------+-----------------------------+ | 4 | ACCOUNT OPENED SUCCESSFULLY | +-------------+-----------------------------+ 1 row in set (0.00 sec)

      The output confirms that the trigger ran successfully.

      The AFTER INSERT trigger is useful in monitoring the lifecycle of a customer. In a production environment, customers’ accounts may undergo different stages such as account opening, suspension, and closing.

      In the following steps you’ll work with UPDATE triggers.

      Step 4 — Creating a Before Update Trigger

      A BEFORE UPDATE trigger is similar to the BEFORE INSERT trigger—the difference is when they are invoked. You can use the BEFORE UPDATE trigger to check a business logic before a record is updated. To test this, you’ll use the customers table in which you’ve inserted some data already.

      You have two levels for your customers in the database. In this example, once a customer account is upgraded to the VIP level, the account can not be downgraded to the BASIC level. To enforce such a rule, you will create a BEFORE UPDATE trigger that will execute before the UPDATE statement as shown following. If a database user tries to downgrade a customer to the BASIC level from the VIP level, a user-defined exception will be triggered.

      Enter the following SQL commands one by one to create the BEFORE UPDATE trigger:

      • DELIMITER //
      • CREATE TRIGGER validate_customer_level
      • ON customers
      • FOR EACH ROW
      • IF OLD.level='VIP' THEN
      • SIGNAL SQLSTATE '45000'
      • SET MESSAGE_TEXT = 'A VIP customer can not be downgraded.';
      • END IF //
      • DELIMITER ;

      You use the OLD keyword to capture the level that the user is supplying when running the UPDATE command. Again, you use the IF...THEN...END IF statement to signal a generic error statement to the user.

      Next, run the following SQL command that tries to downgrade a customer account associated with the customer_id of 3:

      • Update customers set level='BASIC' where customer_id='3';

      You’ll see the following output providing the SET MESSAGE_TEXT:


      ERROR 1644 (45000): A VIP customer can not be downgraded.

      If you run the same command to a BASIC level customer, and try to upgrade the account to the VIP level, the command will execute successfully:

      • Update customers set level='VIP' where customer_id='1';


      Rows matched: 1 Changed: 1 Warnings: 0

      You’ve used the BEFORE UPDATE trigger to enforce a business rule. Now you’ll move on to use an AFTER UPDATE trigger for audit logging.

      Step 5 — Creating an After Update Trigger

      An AFTER UPDATE trigger is invoked once a database record is updated successfully. This behavior makes the trigger suitable for audit logging. In a multi-user environment, the administrator may want to view a history of users updating records in a particular table for audit purposes.

      You’ll create a trigger that logs the update activity of the sales table. Our audit_log table will contain information about the MySQL users updating the sales table, the date of the update, and the new and old sales_amount values.

      To create the trigger, run the following SQL commands:

      • DELIMITER //
      • CREATE TRIGGER log_sales_updates
      • ON sales
      • FOR EACH ROW
      • Insert into audit_log(sales_id, previous_amount, new_amount, updated_by, updated_on) VALUES (NEW.sales_id,OLD.sales_amount, NEW.sales_amount,(SELECT USER()), NOW() )//
      • DELIMITER ;

      You insert a new record to the audit_log table. You use the NEW keyword to retrieve the value of the sales_id and the new sales_amount. Also, you use the OLD keyword to retrieve the previous sales_amount since you want to log both amounts for audit purposes.

      The command SELECT USER() retrieves the current user performing the operation and the NOW() statement retrieves the value of the current date and time from the MySQL server.

      Now if a user tries to update the value of any record in the sales table, the log_sales_updates trigger will insert a new record to the audit_log table.

      Let’s create a new sales record with a random sales_id of 5 and try to update it. First, insert the sales record with:

      • Insert into sales(sales_id, customer_id, sales_amount) values('5', '2','8000');


      Query OK, 1 row affected (0.00 sec)

      Next, update the record:

      • Update sales set sales_amount='9000' where sales_id='5';

      You’ll see the following output:


      Rows matched: 1 Changed: 1 Warnings: 0

      Now run the following command to verify if the AFTER UPDATE trigger was able to register a new record into the audit_log table:

      The trigger logged the update. Your output shows the previous sales_amount and new amount registered with the user that updated the records:


      +--------+----------+-----------------+------------+----------------+---------------------+ | log_id | sales_id | previous_amount | new_amount | updated_by | updated_on | +--------+----------+-----------------+------------+----------------+---------------------+ | 1 | 5 | 8000 | 9000 | root@localhost | 2019-11-07 09:28:36 | +--------+----------+-----------------+------------+----------------+---------------------+ 1 row in set (0.00 sec)

      You also have the date and time the update was performed, which are valuable for audit purposes.

      Next you’ll use the DELETE trigger to enforce referencing integrity at the database level.

      Step 6 — Creating a Before Delete Trigger

      BEFORE DELETE triggers invoke before a DELETE statement executes on a table. These kinds of triggers are normally used to enforce referential integrity on different related tables. For example, each record on the sales table relates to a customer_id from the customers table. If a database user deleted a record from the customers table that has a related record in the sales table, you would have no way of knowing the customer associated with that record.

      To avoid this, you can create a BEFORE DELETE trigger to enforce your logic. Run the following SQL commands one by one:

      • DELIMITER //
      • CREATE TRIGGER validate_related_records
      • ON customers
      • FOR EACH ROW
      • IF OLD.customer_id in (select customer_id from sales) THEN
      • SIGNAL SQLSTATE '45000'
      • SET MESSAGE_TEXT = 'The customer has a related sales record.';
      • END IF//
      • DELIMITER ;

      Now, try to delete a customer that has a related sales record:

      • Delete from customers where customer_id='2';

      As a result you’ll receive the following output:


      ERROR 1644 (45000): The customer has a related sales record.

      The BEFORE DELETE trigger can prevent accidental deletion of related information in a database.

      However, in some situations, you may want to delete all the records associated with a particular record from the different related tables. In this situation you would use the AFTER DELETE trigger, which you’ll test in the next step.

      Step 7 — Creating an After Delete Trigger

      AFTER DELETE triggers are activated once a record has been deleted successfully. An example of how you can use an AFTER DELETE trigger is a situation in which the discount level a particular customer receives is determined by the number of sales made during a defined period. If some of the customer’s records are deleted from the sales table, the customer discount level would need to be downgraded.

      Another use of the AFTER DELETE trigger is deleting related information from another table once a record from a base table is deleted. For instance, you’ll set a trigger that deletes the customer record if the sales records with the related customer_id are deleted from the sales table. Run the following command to create your trigger:

      • DELIMITER //
      • CREATE TRIGGER delete_related_info
      • ON sales
      • FOR EACH ROW
      • Delete from customers where customer_id=OLD.customer_id;//
      • DELIMITER ;

      Next, run the following to delete all sales records associated with a customer_id of 2:

      • Delete from sales where customer_id='2';


      Query OK, 1 row affected (0.00 sec)

      Now check if there are records for the customer from the sales table:

      • Select * from customers where customer_id='2';

      You will receive an Empty Set output since the customer record associated with the customer_id of 2 was deleted by the trigger:


      Empty set (0.00 sec)

      You’ve now used each of the different forms of triggers to perform specific functions. Next you will see how you can remove a trigger from the database if you no longer need it.

      Step 8 — Deleting Triggers

      Similarly to any other database object, you can delete triggers using the DROP command. The following is the syntax for deleting a trigger:

      Drop trigger [TRIGGER NAME];

      For instance, to delete the last AFTER DELETE trigger that you created, run the following command:

      • Drop trigger delete_related_info;


      Query OK, 0 rows affected (0.00 sec)

      The need to delete triggers arises when you want to recreate its structure. In such a case, you can drop the trigger and redefine a new one with the different trigger commands.


      In this tutorial you’ve created, used, and deleted the different kinds of triggers from a MySQL database. Using an example customer-related database you’ve implemented triggers for different use cases such as data validation, business-logic application, audit logging, and enforcing referential integrity.

      For further information on using your MySQL database, check out the following:

      Source link

      Como instalar e proteger o Grafana no Ubuntu 18.04

      O autor escolheu o Dev Color para receber uma doação como parte do programa Write for DOnations.


      O Grafana é uma ferramenta open-source de monitoramento e visualização de dados que se integra a dados complexos de fontes como o Prometheus, InfluxDB, Graphite e ElasticSearch. O Grafana permite a você criar alertas, notificações e filtros ad-hoc para seus dados, além de facilitar a colaboração com seus colegas de equipe por meio de recursos de compartilhamento embutidos.

      Neste tutorial, você instalará o Grafana e o protegerá com um certificado SSL e um proxy reverso Nginx. Depois de configurar o Grafana, você terá a opção de configurar a autenticação do usuário através do GitHub, permitindo organizar melhor as permissões da sua equipe.


      Para seguir este tutorial, você precisará de:

      Passo 1 — Instalando o Grafana

      Neste primeiro passo, você instalará o Grafana no seu servidor Ubuntu 18.04. Você pode instalar o Grafana fazendo o download diretamente do site oficial ou através de um repositório APT. Como um repositório APT facilita a instalação e o gerenciamento das atualizações do Grafana, você utilizará esse método neste tutorial.

      Embora o Grafana esteja disponível no repositório oficial de pacotes do Ubuntu 18.04, a versão do Grafana pode não ser a mais recente, portanto, use o repositório oficial do Grafana.

      Faça o download da chave GPG do Grafana com o wget, em seguida faça um pipe da saída para o apt-key. Isso adicionará a chave à lista de chaves confiáveis da instalação do APT, o que permitirá que você baixe e verifique o pacote Grafana assinado pelo GPG.

      • wget -q -O - | sudo apt-key add -

      Neste comando, a opção -q desativa a mensagem de atualização de status para o wget e -O gera o arquivo que você baixou para o terminal. Essas duas opções garantem que apenas o conteúdo do arquivo baixado seja canalizado para o apt-key.

      Em seguida, adicione o repositório do Grafana às suas origens de pacotes do APT:

      • sudo add-apt-repository "deb stable main"

      Atualize seu cache do APT para atualizar suas listas de pacotes:

      Em seguida, verifique se o Grafana será instalado através do repositório real do Grafana:

      A saída do comando anterior informa a versão do Grafana que você está prestes a instalar e de onde você irá trazer o pacote. Verifique se o candidato à instalação no topo da lista virá do repositório oficial da Grafana em

      Output of apt-cache policy grafana

      grafana: Installed: (none) Candidate: 6.3.3 Version table: 6.3.3 500 500 stable/main amd64 Packages ...

      Agora você pode prosseguir com a instalação:

      Depois que o Grafana estiver instalado, use systemctl para iniciar o servidor Grafana:

      • sudo systemctl start grafana-server

      Em seguida, verifique se o Grafana está em execução, verificando o status do serviço:

      • sudo systemctl status grafana-server

      Você receberá uma saída semelhante a esta:

      Output of grafana-server status

      ● grafana-server.service - Grafana instance Loaded: loaded (/usr/lib/systemd/system/grafana-server.service; disabled; vendor preset: enabled) Active: active (running) since Tue 2019-08-13 08:22:30 UTC; 11s ago Docs: Main PID: 13630 (grafana-server) Tasks: 7 (limit: 1152) ...

      Esta saída contém informações sobre o processo do Grafana, incluindo seu status, Identificador do Processo Principal (PID) e muito mais. active (running) mostra que o processo está sendo executado corretamente.

      Por fim, ative o serviço para iniciar automaticamente o Grafana na inicialização:

      • sudo systemctl enable grafana-server

      Você receberá a seguinte saída:

      Output of systemctl enable grafana-server

      Synchronizing state of grafana-server.service with SysV service script with /lib/systemd/systemd-sysv-install. Executing: /lib/systemd/systemd-sysv-install enable grafana-server Created symlink /etc/systemd/system/ → /usr/lib/systemd/system/grafana-server.service.

      Isso confirma que o systemd criou os links simbólicos necessários para iniciar automaticamente o Grafana.

      O Grafana agora está instalado e pronto para uso. A seguir, você protegerá sua conexão com o Grafana com um proxy reverso e um certificado SSL.

      Passo 2 — Configurando o Proxy Reverso

      O uso de um certificado SSL garantirá a segurança dos seus dados, criptografando a conexão de e para o Grafana. Mas, para usar essa conexão, primeiro você precisará reconfigurar o Nginx como um proxy reverso para o Grafana.

      Abra o arquivo de configuração do Nginx que você criou ao configurar o bloco de servidor Nginx com o Let’s Encrypt nos Pré-requisitos. Você pode usar qualquer editor de texto, mas para este tutorial, usaremos o nano:

      • sudo nano /etc/nginx/sites-available/seu_domínio

      Localize o seguinte bloco:


          location / {
              try_files $uri $uri/ =404;

      Como você já configurou o Nginx para se comunicar através de SSL e como todo o tráfego web em seu servidor já passa pelo Nginx, basta dizer ao Nginx para encaminhar todas as solicitações ao Grafana, que é executado na porta 3000 por padrão.

      Exclua a linha try_files existente neste bloco de location e substitua-a pela seguinte opção proxy_pass.


          location / {
              proxy_pass http://localhost:3000;

      Isso mapeará o proxy para a porta apropriada. Quando terminar, salve e feche o arquivo pressionando CTRL+X, seguido por Y e, em seguida, ENTER se estiver usando o nano.

      Agora, teste as novas configurações para garantir que tudo esteja configurado corretamente:

      Você receberá a seguinte saída:


      nginx: the configuration file /etc/nginx/nginx.conf syntax is ok nginx: configuration file /etc/nginx/nginx.conf test is successful

      Por fim, ative as alterações recarregando o Nginx:

      • sudo systemctl reload nginx

      Agora você pode acessar a tela de login padrão do Grafana apontando o navegador para https://seu_domínio. Se você não conseguir acessar a Grafana, verifique se o seu firewall está configurado para permitir o tráfego na porta 443 e, em seguida, siga novamente as instruções anteriores.

      Com a conexão com o Grafana criptografada, agora você pode implementar medidas de segurança adicionais, começando com a alteração das credenciais administrativas padrão do Grafana.

      Passo 3 — Atualizando Credenciais

      Como todas as instalações do Grafana usam as mesmas credenciais administrativas por padrão, é uma boa prática alterar suas informações de login o mais rápido possível. Neste passo, você atualizará as credenciais para melhorar a segurança.

      Comece navegando até https://seu_domínio no seu navegador. Isso exibirá a tela de login padrão, na qual você verá o logotipo do Grafana, um formulário solicitando que você insira email or username e password, um botão Log in e um link Forgot your password?

      Grafana Login

      Digite admin nos campos User e Password e clique no botão Log in.

      Na próxima tela, você será solicitado a tornar sua conta mais segura alterando a senha padrão:

      Change Password

      Digite a senha que você deseja começar a usar nos campos New password e Confirm new password.

      A partir daqui, você pode clicar em Save para salvar as novas informações ou pressionar Skip para pular esta etapa. Se você pular, você será solicitado a alterar a senha na próxima vez que fizer login.

      Para aumentar a segurança da sua configuração do Grafana, clique em Save. Você retornará à página Home Dashboard:

      Home Dashboard

      Agora você protegeu sua conta alterando as credenciais padrão. Em seguida, você fará alterações na configuração do Grafana para que ninguém possa criar uma nova conta do Grafana sem a sua permissão.

      Passo 4 — Desativando Registros no Grafana e o Acesso Anônimo

      O Grafana fornece opções que permitem aos visitantes criar contas de usuário e visualizar dashboards sem se registrar. Quando o Grafana não estiver acessível via Internet ou quando estiver trabalhando com dados publicamente disponíveis, como status de serviço, convém permitir esses recursos. No entanto, ao usar o Grafana online para trabalhar com dados confidenciais, o acesso anônimo pode ser um problema de segurança. Para corrigir esse problema, faça algumas alterações na configuração do Grafana.

      Comece abrindo o arquivo de configuração principal do Grafana para edição:

      • sudo nano /etc/grafana/grafana.ini

      Localize a seguinte diretiva allow_sign_up sob o cabeçalho [users]:


      # disable user signup / registration
      ;allow_sign_up = true

      A ativação dessa diretiva com true adiciona um botão Sign Up na tela de login, permitindo que os usuários se registrem e acessem o Grafana.

      A desativação desta diretiva com false remove o botão Sign Up e fortalece a segurança e a privacidade do Grafana.

      Remova o comentário desta diretiva removendo o ; no início da linha e defina a opção como false:


      # disable user signup / registration
      allow_sign_up = false

      Em seguida, localize a seguinte diretiva enabled sob o cabeçalho [auth.anonymous]:


      # enable anonymous access
      ;enabled = false

      Definir enabled como true fornece aos usuários não registrados acesso aos seus dashboards; definir esta opção como false limita o acesso do dashboard apenas aos usuários registrados.

      Remova o comentário desta diretiva removendo o ; no início da linha e defina a opção como false:


      enabled = false

      Salve o arquivo e saia do seu editor de texto.

      Para ativar as alterações, reinicie o Grafana:

      • sudo systemctl restart grafana-server

      Verifique se tudo está funcionando, checando o status do serviço do Grafana:

      • sudo systemctl status grafana-server

      Como antes, a saída vai informar que o Grafana está active (running).

      Agora, aponte seu navegador para https://seu_domínio. Para retornar à tela Sign Up, leve o cursor para o seu avatar no canto inferior esquerdo da tela e clique na opção Sign out que aparece.

      Depois de sair, verifique se não há um botão Sign Up e se não é possível fazer login sem inserir as credenciais de login.

      Nesse ponto, o Grafana está totalmente configurado e pronto para uso. Em seguida, você pode simplificar o processo de login para sua organização, usando a autenticação através do GitHub.

      (Opcional) Passo 5 — Configurando um App GitHub OAuth

      Para uma abordagem alternativa ao fazer login, você pode configurar o Grafana para autenticação através do GitHub, que fornece acesso de login a todos os membros de organizações autorizadas do GitHub. Isso pode ser particularmente útil quando você deseja permitir que vários desenvolvedores colaborem e acessem métricas sem precisar criar credenciais específicas para o Grafana.

      Comece fazendo login em uma conta do GitHub associada à sua organização e navegue até a página de perfil do GitHub em

      Clique no nome da sua organização em Organization settings no menu de navegação no lado esquerdo da tela.

      GitHub Organization settings

      Na próxima tela, você verá seu Organization profile, onde poderá alterar configurações como seu Organization display name, Email e URL da organização .

      Como o Grafana usa OAuth, um padrão aberto para conceder acesso remoto de terceiros a recursos locais, para autenticar usuários através do GitHub, você precisará criar uma nova aplicação OAuth no GitHub.

      Clique no link OAuth Apps em Developer settings no lado inferior esquerdo da tela.

      Se você ainda não possui aplicações OAuth associadas à sua organização no GitHub, será mostrado a você No Organization Owned Applications. Caso contrário, você verá uma lista dos aplicações OAuth já conectadas à sua conta.

      Clique no botão Register an application para continuar.

      Na próxima tela, preencha os seguintes detalhes sobre a sua instalação do Grafana:

      • Application name - Isso ajuda a distinguir suas diferentes aplicações OAuth.
      • Homepage URL - Isso informa ao GitHub onde encontrar o Grafana. Digite https://seu_domínio nesse campo, substituindo seu_domínio pelo seu domínio.
      • Application Description - Isso fornece uma descrição do objetivo da sua aplicação OAuth.
      • Application callback URL - Este é o endereço para o qual os usuários serão enviados uma vez autenticados com êxito. Para o Grafana, esse campo deve ser definido como https://seu_domínio/login/github.

      Lembre-se de que os usuários do Grafana que efetuam login através do GitHub verão os valores inseridos nos três primeiros campos anteriores, portanto, insira algo significativo e apropriado.

      Quando preenchido, o formulário será semelhante a:

      GitHub Register OAuth Application

      Clique no botão verde Register application.

      Agora você será redirecionado para uma página que contém o Client ID e e o Client Secret associados à sua nova aplicação OAuth. Anote os dois valores, pois será necessário adicioná-los ao arquivo de configuração principal do Grafana para concluir a instalação.

      Atenção: Certifique-se de manter seu Client ID e seu Client Secret em um local seguro e não público, pois eles podem ser usados como base para um ataque.

      Com sua aplicação GitHub OAuth criada, agora você está pronto para reconfigurar o Grafana para usar o GitHub para autenticação.

      (Opcional) Passo 6 — Configurando o Grafana como um App OAuth no GitHub

      Para concluir a autenticação do GitHub para sua configuração do Grafana, você fará algumas alterações nos arquivos de configuração do Grafana.

      Para começar, abra o arquivo de configuração principal do Grafana.

      • sudo nano /etc/grafana/grafana.ini

      Localize o cabeçalho [auth.github] e descomente esta seção removendo o ; no início de cada linha exceto ;team_ids=, que não será alterado neste tutorial.

      Em seguida, configure o Grafana para usar o GitHub com os valores de client_id e client_secret da sua aplicação OAuth.

      • Defina enabled e allow_sign_up para true. Isso permitirá a autenticação via GitHub e permitirá que os membros da organização permitida criem contas. Observe que essa configuração é diferente da propriedade allow_sign_up em [users] que você alterou no Passo 4.
      • Defina client_id e client_secret com os valores que você obteve ao criar sua aplicação GitHub OAuth.
      • Defina allowed_organizations como o nome da sua organização para garantir que apenas membros da sua organização possam se inscrever e fazer login no Grafana.

      A configuração completa será semelhante a:


      enabled = true
      allow_sign_up = true
      client_id = seu_client_id_do_github
      client_secret = seu_client_secret_do_github
      scopes = user:email,read:org
      auth_url =
      token_url =
      api_url =
      ;team_ids =
      allowed_organizations = nome_da_sua_organização

      Agora você contou ao Grafana tudo o que ele precisava saber sobre o GitHub. Para concluir a instalação, você precisará habilitar os redirecionamentos por trás de um proxy reverso. Isso é feito configurando um valor root_url no cabeçalho [server].


      root_url = https://seu_domínio

      Salve sua configuração e feche o arquivo.

      Em seguida, reinicie o Grafana para ativar as alterações:

      • sudo systemctl restart grafana-server

      Por fim, verifique se o serviço está funcionando.

      • sudo systemctl status grafana-server

      A saída indicará que o serviço está active (running).

      Agora, teste seu novo sistema de autenticação navegando até https://seu_domínio. Se você já está logado no Grafana, passe o mouse sobre o log do avatar no canto inferior esquerdo da tela e clique em Sign out no menu secundário que aparece ao lado do seu nome.

      Na página de login, você verá uma nova seção sob o botão original Log in , que inclui um botão Sign in with GitHub com o logotipo do GitHub.

      Grafana Login page with GitHub

      Clique no botão Sign in with GitHub para ser redirecionado para o GitHub, onde você entrará na sua conta GitHub e confirmará sua intenção de Authorize Grafana ou autorizar o Grafana.

      Clique no botão verde, Authorize nomedasua_organização.

      Nota: Verifique se a sua conta do GitHub é membro da sua organização aprovada e se o seu endereço de e-mail do Grafana corresponde ao seu endereço de e-mail do GitHub. Se você tentar se autenticar com uma conta do GitHub que não seja membro de sua organização aprovada, receberá uma mensagem Login Failed informando: User not a member of one of the required organizations, ou seja, o usuário não é membro de uma das organizações necessárias.

      Agora você estará logado com sua conta Grafana existente. Se uma conta Grafana ainda não existir para o usuário no qual você efetuou login, o Grafana criará uma nova conta de usuário com permissões de visualização, ou Viewer, garantindo que os novos usuários possam usar apenas os dashboards existentes.

      Para alterar as permissões padrão para novos usuários, abra o arquivo de configuração principal do Grafana para edição.

      • sudo nano /etc/grafana/grafana.ini

      Localize a diretiva auto_assign_org_role no cabeçalho [users], e descomente a configuração removendo o ; no início da linha.

      Defina a diretiva para um dos seguintes valores:

      • Viewer — só pode usar dashboards existentes
      • Editor — pode alterar o uso, modificar e adicionar dashboards
      • Admin — tem permissão para fazer tudo

      Este tutorial definirá a atribuição automática como Viewer:


      auto_assign_org_role = Viewer

      Depois de salvar as alterações, feche o arquivo e reinicie o Grafana:

      • sudo systemctl restart grafana-server

      Verifique o status do serviço:

      • sudo systemctl status grafana-server

      Como antes, o status apresentará active (running).

      Neste ponto, você configurou totalmente o Grafana para permitir que membros da sua organização GitHub registrem e usem sua instalação do Grafana.


      Neste tutorial, você instalou, configurou e protegeu o Grafana e também aprendeu como permitir que membros da sua organização se autentiquem através do GitHub.

      Para estender sua instalação atual do Grafana, consulte a lista de dashboards oficiais e criados pela comunidade. Para saber mais sobre o uso do Grafana em geral, consulte a documentação oficial do Grafana, ou confira nossos tutoriais de monitoramento adicionais.

      Source link

      Como gerenciar a infraestrutura DigitalOcean e o Kubernetes com o Pulumi

      O autor escolheu a Diversity in Tech Fund para receber uma doação como parte do programa Write for DOnations.


      O Pulumi é uma ferramenta para criar, implantar e gerenciar infraestrutura usando código escrito em linguagens de programação de uso geral. Ele suporta a automação de todos os serviços gerenciados da DigitalOcean, como Droplets, bancos de dados gerenciados, registros DNS e clusters Kubernetes, além da configuração de aplicações. Os deployments são realizados a partir de uma interface de linha de comando fácil de usar que também se integra a uma ampla variedade de sistemas populares de CI/CD.

      O Pulumi suporta várias linguagens, mas neste tutorial você usará TypeScript, uma versão de tipagem estática do JavaScript que utiliza o runtime Node.js. Isso significa que você obterá suporte a IDE e checagem em tempo de compilação que o ajudarão a garantir que você configurou os recursos certos, usou slugs corretos etc., enquanto continua podendo acessar qualquer módulo NPM para tarefas utilitárias.

      Neste tutorial, você provisionará um cluster Kubernetes na DigitalOcean, uma aplicação Kubernetes com balanceamento de carga e um domínio DNS da DigitalOcean que disponibiliza seu aplicativo em um nome de domínio estável de sua escolha. Tudo isso pode ser provisionado em 60 linhas de infraestrutura como código e em uma única execução de linha de comando pulumi up. Após este tutorial, você estará pronto para criar com produtividade, arquiteturas poderosas de nuvem usando a infraestrutura como código do Pulumi que aproveita toda a área de serviços DigitalOcean e Kubernetes.


      Para seguir este tutorial, você precisará de:

      • Uma conta na DigitalOcean na qual fazer o deployment dos recursos. Se você ainda não possui uma, cadastre-se aqui.
      • Um token de API da DigitalOcean para executar deployments automatizados. Gere um token de acesso pessoal aqui e mantenha-o à mão, pois você o usará no Passo 2.
      • Como você criará e usará um cluster Kubernetes, precisará instalar o kubectl. Não se preocupe em configurá-lo ainda, pois você fará isso mais tarde.
      • Você escreverá sua infraestrutura como código no TypeScript e precisará do Node.js 8 ou posterior. Faça o download aqui ou instale-o usando o gerenciador de pacotes do seu sistema.
      • Você usará o Pulumi para fazer o deploy da infraestrutura, por isso precisará instalar o SDK do Pulumi open source.
      • Para executar o Passo 5 opcional, você precisará de um nome de domínio configurado para usar os servidores de nomes da DigitalOcean. Este guia explica como fazer isso para o registrador de sua escolha.

      Passo 1 — Estruturando um Novo Projeto

      O primeiro passo é criar um diretório que irá armazenar seu projeto Pulumi. Esse diretório conterá o código-fonte para suas definições de infraestrutura, além dos arquivos de metadados que descrevem o projeto e suas dependências NPM.

      Primeiro, crie o diretório:

      Em seguida, vá para o diretório recém-criado:

      A partir de agora, execute comandos a partir do seu diretório do-k8s recém-criado.

      Em seguida, crie um novo projeto Pulumi. Existem diferentes maneiras de fazer isso, mas a maneira mais fácil é usar o comando pulumi new com o modelo de projeto typescript. Este comando primeiro solicitará que você efetue login no Pulumi para que seu projeto e o estado do deployment sejam salvos e, em seguida, criará um projeto TypeScript simples no diretório atual:

      Aqui você passou a opção -y para o comando new, que diz a ele para aceitar as opções padrão do projeto. Por exemplo, o nome do projeto é retirado do nome do diretório atual e, portanto, será do-k8s. Se você quiser usar opções diferentes para o nome do seu projeto, simplesmente elimine o -y.

      Após executar o comando, liste o conteúdo do diretório com ls:

      Os seguintes arquivos estarão agora presentes:


      Pulumi.yaml index.ts node_modules package-lock.json package.json tsconfig.json

      O arquivo principal que você estará editando é index.ts. Embora este tutorial use apenas esse arquivo único, você pode organizar seu projeto da maneira que achar melhor usando os módulos Node.js. Este tutorial também descreve uma etapa de cada vez, aproveitando o fato de que o Pulumi pode detectar e deployar de forma incremental apenas o que mudou. Se preferir, você pode simplesmente preencher o programa inteiro e fazer o deploy de uma só vez usando o pulumi up.

      Agora que você estruturou seu novo projeto, está pronto para adicionar as dependências necessárias para seguir o tutorial.

      Passo 2 — Adicionando Dependências

      O próximo passo é instalar e adicionar dependências nos pacotes DigitalOcean e Kubernetes. Primeiro, instale-os usando o NPM:

      Isso fará o download dos pacotes NPM, plug-ins do Pulumi e os salvará como dependências.

      Em seguida, abra o arquivo index.ts com seu editor favorito. Este tutorial usará o nano:

      Substitua o conteúdo do seu index.ts pelo seguinte:


      import * as digitalocean from "@pulumi/digitalocean";
      import * as kubernetes from "@pulumi/kubernetes";

      Isso disponibiliza todo o conteúdo desses pacotes para o seu programa. Se você digitar "digitalocean." usando um IDE que entenda TypeScript e Node.js, você deverá ver uma lista dos recursos da DigitalOcean suportados por este pacote, por exemplo.

      Salve e feche o arquivo após adicionar o conteúdo.

      Nota: Usaremos um subconjunto do que está disponível nesses pacotes. Para obter a documentação completa dos recursos, propriedades e APIs associadas, consulte a documentação relevante da API para os pacotes @pulumi/digitalocean e @pulumi/kubernetes.

      Em seguida, você configurará seu token DigitalOcean para que o Pulumi possa provisionar recursos em sua conta:

      • pulumi config set digitalocean:token SEU_TOKEN_AQUI --secret

      Observe a flag --secret, que usa o serviço de criptografia do Pulumi para criptografar seu token, garantindo que ele seja armazenado em texto cifrado. Se preferir, você pode usar a variável de ambiente DIGITALOCEAN_TOKEN, mas você vai precisar lembrar-se de defini-la sempre que atualizar seu programa, enquanto o uso da configuração armazena e o utiliza automaticamente para o seu projeto.

      Nesta etapa, você adicionou as dependências necessárias e configurou seu token de API com o Pulumi para poder provisionar seu cluster Kubernetes.

      Passo 3 — Provisionando um Cluster Kubernetes

      Agora você está pronto para criar um cluster Kubernetes na DigitalOcean. Comece reabrindo o arquivo index.ts:

      Adicione estas linhas no final do seu arquivo index.ts:


      const cluster = new digitalocean.KubernetesCluster("do-cluster", {
          region: digitalocean.Regions.SFO2,
          version: "latest",
          nodePool: {
              name: "default",
              size: digitalocean.DropletSlugs.DropletS2VPCU2GB,
              nodeCount: 3,
      export const kubeconfig = cluster.kubeConfigs[0].rawConfig;

      Este novo código aloca uma instância do digitalocean.KubernetesCluster e define várias propriedades nele. Isso inclui o uso da sfo2 como slug da região, a versão mais recente, latest, do Kubernetes, o s-2vcpu-2gb slug de tamanho do Droplet, e indica a contagem desejada de três instâncias do Droplet. Sinta-se à vontade para alterar qualquer uma dessas opções, mas lembre-se de que o Kubernetes da DigitalOcean está disponível apenas em determinadas regiões no momento em que este artigo foi escrito. Você pode consultar a documentação do produto para obter informações atualizadas sobre a disponibilidade da região.

      Para obter uma lista completa das propriedades que você pode configurar no seu cluster, consulte a documentação da API do KubernetesCluster.

      A linha final nesse trecho de código exporta o aqruivo kubeconfig resultante do cluster Kubernetes para que seja fácil de usar. As variáveis exportadas são impressas no console e também acessíveis às ferramentas. Você usará isso momentaneamente para acessar nosso cluster a partir de ferramentas padrão como o kubectl.

      Agora você está pronto para implantar seu cluster. Para fazer isso, execute pulumi up:

      Este comando pega o programa, gera um plano para criar a infraestrutura descrita e executa uma série de etapas para deployar essas alterações. Isso funciona para a criação inicial da infraestrutura, além de poder diferenciar e atualizar sua infraestrutura quando as atualizações subsequentes são feitas. Nesse caso, a saída será mais ou menos assim:


      Previewing update (dev): Type Name Plan + pulumi:pulumi:Stack do-k8s-dev create + └─ digitalocean:index:KubernetesCluster do-cluster create Resources: + 2 to create Do you want to perform this update? yes > no details

      Isso indica que prosseguindo com a atualização será criado um único cluster Kubernetes chamado do-cluster. O prompt yes/no/details permite confirmar que este é o resultado desejado antes que quaisquer alterações sejam realmente feitas. Se você selecionar details, uma lista completa de recursos e suas propriedades serão mostrados. Escolha yes para iniciar o deployment:


      Updating (dev): Type Name Status + pulumi:pulumi:Stack do-k8s-dev created + └─ digitalocean:index:KubernetesCluster do-cluster created Outputs: kubeconfig: "..." Resources: + 2 created Duration: 6m5s Permalink:

      Leva alguns minutos para criar o cluster, mas depois ele estará em funcionamento e o kubeconfig completo será impresso no console. Salve o kubeconfig em um arquivo:

      • pulumi stack output kubeconfig > kubeconfig.yml

      E então use-o com o kubectl para executar qualquer comando do Kubernetes:

      • KUBECONFIG=./kubeconfig.yml kubectl get nodes

      Você receberá uma saída semelhante à seguinte:


      NAME STATUS ROLES AGE VERSION default-o4sj Ready <none> 4m5s v1.14.2 default-o4so Ready <none> 4m3s v1.14.2 default-o4sx Ready <none> 3m37s v1.14.2

      Nesse ponto, você configurou a infraestrutura como código e tem uma maneira repetível de ativar e configurar novos clusters Kubernetes na DigitalOcean . No próximo passo, você trabalhará em cima disso para definir a infraestrutura do Kubernetes no código e aprender como fazer o deploy e gerenciá-la da mesma forma.

      Passo 4 — Fazendo o Deploy de uma Aplicação no seu Cluster

      A seguir, você descreverá a configuração de uma aplicação Kubernetes usando infraestrutura como código. Isso consistirá em três partes:

      1. Um objeto Provider, que diz ao Pulumi para deployar recursos do Kubernetes no cluster da DigitalOcean, em vez do padrão que qualquer kubectl esteja configurado para usar.
      2. Um Deployment de Kubernetes, que é a maneira padrão do Kubernetes de deployar uma imagem de container Docker que é replicada em qualquer número de Pods.
      3. Um Serviço Kubernetes, que é a maneira padrão para dizer ao Kubernetes para balancear o acesso entre um conjunto alvo de Pods (neste caso, o Deployment acima).

      Essa é uma arquitetura de referência razoavelmente padrão para iniciar e executar um serviço com balanceamento de carga no Kubernetes.

      Para implantar todos os três, abra o arquivo index.ts novamente:

      Depois de abrir o arquivo, acrescente este código ao final dele:


      const provider = new kubernetes.Provider("do-k8s", { kubeconfig })
      const appLabels = { "app": "app-nginx" };
      const app = new kubernetes.apps.v1.Deployment("do-app-dep", {
          spec: {
              selector: { matchLabels: appLabels },
              replicas: 5,
              template: {
                  metadata: { labels: appLabels },
                  spec: {
                      containers: [{
                          name: "nginx",
                          image: "nginx",
      }, { provider });
      const appService = new kubernetes.core.v1.Service("do-app-svc", {
          spec: {
              type: "LoadBalancer",
              selector: app.spec.template.metadata.labels,
              ports: [{ port: 80 }],
      }, { provider });
      export const ingressIp = appService.status.loadBalancer.ingress[0].ip;

      Esse código é semelhante à configuração padrão do Kubernetes, e o comportamento dos objetos e suas propriedades é equivalente, exceto que ele está escrito em TypeScript ao lado de suas outras declarações de infraestrutura.

      Salve e feche o arquivo depois de fazer as alterações.

      Assim como antes, execute pulumi up para visualizar e deployar as alterações:

      Depois de selecionar yes para prosseguir, a CLI imprimirá atualizações de status detalhadas, incluindo diagnósticos sobre disponibilidade de Pod, alocação de endereço IP e muito mais. Isso ajudará você a entender por que seu deployment pode levar algum tempo para ser concluído ou ficar travado.

      A saída completa será mais ou menos assim:


      Updating (dev): Type Name Status pulumi:pulumi:Stack do-k8s-dev + ├─ pulumi:providers:kubernetes do-k8s created + ├─ kubernetes:apps:Deployment do-app-dep created + └─ kubernetes:core:Service do-app-svc created Outputs: + ingressIp : "" Resources: + 3 created 2 unchanged Duration: 2m52s Permalink:

      Após a conclusão, observe que o número desejado de Pods está em execução:

      • KUBECONFIG=./kubeconfig.yml kubectl get pods


      NAME READY STATUS RESTARTS AGE do-app-dep-vyf8k78z-758486ff68-5z8hk 1/1 Running 0 1m do-app-dep-vyf8k78z-758486ff68-8982s 1/1 Running 0 1m do-app-dep-vyf8k78z-758486ff68-94k7b 1/1 Running 0 1m do-app-dep-vyf8k78z-758486ff68-cqm4c 1/1 Running 0 1m do-app-dep-vyf8k78z-758486ff68-lx2d7 1/1 Running 0 1m

      Similar à maneira como o programa exporta o arquivo kubeconfig do cluster, este programa também exporta o endereço IP do balanceador de carga resultante do serviço Kubernetes. Use isto para fazer um curl no endpoint e verifique se ele está funcionando:

      • curl $(pulumi stack output ingressIp)


      <!DOCTYPE html> <html> <head> <title>Welcome to nginx!</title> <style> body { width: 35em; margin: 0 auto; font-family: Tahoma, Verdana, Arial, sans-serif; } </style> </head> <body> <h1>Welcome to nginx!</h1> <p>If you see this page, the nginx web server is successfully installed and working. Further configuration is required.</p> <p>For online documentation and support please refer to <a href=""></a>.<br/> Commercial support is available at <a href=""></a>.</p> <p><em>Thank you for using nginx.</em></p> </body> </html>

      A partir daqui, você pode editar e re-deployar facilmente sua infraestrutura de aplicações. Por exemplo, tente alterar a linha replicas: 5 para digamos replicas: 7 e, em seguida, execute novamente pulumi up:

      Observe que ele apenas mostra o que mudou e que ao selecionar detalhes, exibe a diferença precisa:


      Previewing update (dev): Type Name Plan Info pulumi:pulumi:Stack do-k8s-dev ~ └─ kubernetes:apps:Deployment do-app-dep update [diff: ~spec] Resources: ~ 1 to update 4 unchanged Do you want to perform this update? details pulumi:pulumi:Stack: (same) [urn=urn:pulumi:dev::do-k8s::pulumi:pulumi:Stack::do-k8s-dev] ~ kubernetes:apps/v1:Deployment: (update) [id=default/do-app-dep-vyf8k78z] [urn=urn:pulumi:dev::do-k8s::kubernetes:apps/v1:Deployment::do-app-dep] [provider=urn:pulumi:dev::do-k8s::pulumi:providers:kubernetes::do-k8s::80f36105-337f-451f-a191-5835823df9be] ~ spec: { ~ replicas: 5 => 7 }

      Agora você tem um cluster Kubernetes em plena operação e uma aplicação em funcionamento. Com a aplicação em funcionamento, você pode querer configurar um domínio personalizado para usar com ela. O próximo passo o guiará na configuração do DNS com o Pulumi.

      Passo 5 — Criando um Domínio DNS (Opcional)

      Embora o cluster e a aplicação Kubernetes estejam em funcionamento, o endereço da aplicação é dependente dos caprichos da atribuição automática de endereços IP pelo seu cluster. Conforme você ajusta e reimplementa as coisas, esse endereço pode mudar. Neste passo, você verá como atribuir um nome DNS personalizado ao endereço IP do balanceador de carga, para que fique estável, mesmo que você altere sua infraestrutura posteriormente.

      Nota: Para concluir este passo, garanta que você possui um domínio usando os servidores de nomes DNS da DigitalOcean,, e Instruções para configurar isso estão disponíveis na seção Pré-requisitos.

      Para configurar o DNS, abra o arquivo index.ts e acrescente o seguinte código ao final do arquivo:


      const domain = new digitalocean.Domain("do-domain", {
          name: "seu_domínio",
          ipAddress: ingressIp,

      Este código cria uma nova entrada DNS com um registro A que se refere ao endereço IP do seu serviço Kubernetes. Substitua seu_domínio neste trecho pelo nome de domínio escolhido.

      É comum querer subdomínios adicionais, como www, apontando para a aplicação web. É fácil conseguir isso usando um registro DNS da DigitalOcean. Para tornar este exemplo mais interessante, adicione também um registro CNAME que aponte www.seu_domí para seu_domí


      const cnameRecord = new digitalocean.DnsRecord("do-domain-cname", {
          type: "CNAME",
          name: "www",
          value: "@",

      Salve e feche o arquivo depois de fazer essas alterações.

      Por fim, execute pulumi up para fazer o deploy das alterações no DNS para apontar para a aplicação e o cluster existentes:


      Updating (dev): Type Name Status pulumi:pulumi:Stack do-k8s-dev + ├─ digitalocean:index:Domain do-domain created + └─ digitalocean:index:DnsRecord do-domain-cname created Resources: + 2 created 5 unchanged Duration: 6s Permalink:

      Após a propagação das alterações no DNS, você poderá acessar seu conteúdo em seu domínio personalizado:

      • curl www.seu_domí

      Você receberá uma saída semelhante à seguinte:


      <!DOCTYPE html> <html> <head> <title>Welcome to nginx!</title> <style> body { width: 35em; margin: 0 auto; font-family: Tahoma, Verdana, Arial, sans-serif; } </style> </head> <body> <h1>Welcome to nginx!</h1> <p>If you see this page, the nginx web server is successfully installed and working. Further configuration is required.</p> <p>For online documentation and support please refer to <a href=""></a>.<br/> Commercial support is available at <a href=""></a>.</p> <p><em>Thank you for using nginx.</em></p> </body> </html>

      Com isso, você configurou com êxito um novo cluster Kubernetes na DigitalOcean, fez o deploy de uma aplicação Kubernetes com balanceamento de carga e deu ao balanceador de carga dessa aplicação um nome de domínio estável usando o DNS da DigitalOcean, tudo em 60 linhas de código e um comando pulumi up .

      A próximo passo o guiará na remoção dos recursos, se você não precisar mais deles.

      Passo 6 — Removendo os Recursos (Opcional)

      Antes de concluir o tutorial, você pode querer destruir todos os recursos criados acima. Isso garantirá que você não seja cobrado pelos recursos que não estão sendo usados. Se você preferir manter sua aplicação em funcionamento, fique à vontade para pular esta etapa.

      Execute o seguinte comando para destruir os recursos. Cuidado ao usar isso, pois não pode ser desfeito!

      Assim como no comando up, destroy exibe uma visualização e um prompt antes de executar uma ação:


      Previewing destroy (dev): Type Name Plan - pulumi:pulumi:Stack do-k8s-dev delete - ├─ digitalocean:index:DnsRecord do-domain-cname delete - ├─ digitalocean:index:Domain do-domain delete - ├─ kubernetes:core:Service do-app-svc delete - ├─ kubernetes:apps:Deployment do-app-dep delete - ├─ pulumi:providers:kubernetes do-k8s delete - └─ digitalocean:index:KubernetesCluster do-cluster delete Resources: - 7 to delete Do you want to perform this destroy? yes > no details

      Supondo que é isso que você deseja, selecione yes e observe as exclusões:


      Destroying (dev): Type Name Status - pulumi:pulumi:Stack do-k8s-dev deleted - ├─ digitalocean:index:DnsRecord do-domain-cname deleted - ├─ digitalocean:index:Domain do-domain deleted - ├─ kubernetes:core:Service do-app-svc deleted - ├─ kubernetes:apps:Deployment do-app-dep deleted - ├─ pulumi:providers:kubernetes do-k8s deleted - └─ digitalocean:index:KubernetesCluster do-cluster deleted Resources: - 7 deleted Duration: 7s Permalink:

      Nesse momento, nada mais resta: as entradas de DNS desaparecem e o cluster Kubernetes — juntamente com a aplicação em execução nele — também desaparece. O link permanente, permalink, ainda está disponível, para que você possa voltar e ver o histórico completo de atualizações para essa pilha. Isso pode ajudá-lo a se recuperar se a destruição for um erro, uma vez que o serviço mantém um histórico completo do estado de todos os recursos.

      Se você gostaria de destruir o seu projeto na sua totalidade, remova a pilha:

      Você receberá uma saída pedindo para confirmar a exclusão digitando o nome da pilha:


      This will permanently remove the 'dev' stack! Please confirm that this is what you'd like to do by typing ("dev"):

      Ao contrário do comando destroy, que exclui os recursos de infraestrutura em nuvem, a remoção de uma pilha apaga totalmente o histórico completo da sua pilha do alcance do Pulumi.


      Neste tutorial, você fez o deploy dos recursos de infraestrutura na DigitalOcean — um cluster Kubernetes e um domínio DNS com registros A e CNAME — além da configuração da aplicação Kubernetes que usa esse cluster. Você fez isso usando infraestrutura como código escrita em uma linguagem de programação familiar, TypeScript, que trabalha com editores, ferramentas e bibliotecas existentes e aproveita as comunidades e pacotes existentes. Você fez tudo isso usando um único fluxo de trabalho de linha de comando para realizar deployments que abrangem sua aplicação e a infraestrutura.

      A partir daqui, há uma série de próximos passos que você pode dar:

      O exemplo completo deste tutorial está disponível no GitHub. Para obter maiores detalhes sobre como usar a infraestrutura como código do Pulumi em seus próprios projetos hoje, consulte a Documentação do Pulumi, Tutorials, ou os guias Getting Started. O Pulumi é open source e é livre para usar.

      Source link