- Criação de modulos de Terraform
- Criação de cluster GKE
- Criação de zonas de DNS
- Utilização de diferentes providers (kubectl provider)
- Templates de ficheiros
Tempo estimado: Cerca de 2 horas
Pré requsitos: Antes de começares, é necessário verificares algumas coisas:
Certifica-te que tens a google-cloud-shell
devidamente autorizada correndo este comando:
gcloud config set project ten21-terraforming-p-154457 && gcloud config set accessibility/screen_reader false
De seguida, clica no botão Start para começares.
Neste projeto temos que preparar um prefixo que identifique unicamente os recursos que vão ser criados, por forma a evitar colisões.
- No ficheiro terraform.tfvars é necessário definir um prefixo, no seguinte formato:
user_prefix = "<valor>"
Inicializar:
terraform init
💡Para evitar que o terraform peça o nome do projeto a cada plan
, podemos definir o nome do projeto por defeito:
- Abrir o ficheiro terraform.tfvars.
- Descomentar a linha
project_id
e adicionar o id do projeto que aparece a amarelo na linha de comandos.
💡Notem que a variavel user_prefix
tem uma validação declarada no ficheiro variables.tf. Caso estejam a ter um erro, é preciso garantir queo nome escolhido cumpre com as regras de validação.
from docs: You can specify custom validation rules for a particular variable by adding a validation block within the corresponding variable block. The example below checks whether the AMI ID has the correct syntax.
Planear:
terraform plan -out plan.tfplan
Aplicar:
terraform apply plan.tfplan
- No ficheiro vpc.tf encontram-se as definições da VPC e respetiva subnet a usar
👉 Descomentar as seguintes resources:
resource "google_compute_network" "default"
resource "google_compute_subnetwork" "gke"
resource "google_compute_router" "default"
resource "google_compute_router_nat" "default"
💡ProTip: CTRL+K+U
é o atalho para descomentar em bloco
Why: Tanto o router
como o nat
são recursos necessários para permitir que o cluster GKE possa aceder à internet para fazer download das imagens dos containers que vamos usar.
Executar o plan
& apply
:
terraform plan -out plan.tfplan
terraform apply plan.tfplan
Validar the a VPC foi criada:
gcloud compute networks list | grep $(terraform output -raw my_identifier)
Validar que a subnet foi criada:
gcloud compute networks subnets list | grep "$(terraform output -raw my_identifier)"
Neste capitulo iremos abordar a utilização de terraform modules para instanciar o GKE.
Exemplo demonstrativo da organização de modulos no slide 12 da apresentação.
from docs: A module is a container for multiple resources that are used together.
Every Terraform configuration has at least one module, known as its root module, which consists of the resources defined in the .tf files in the main working directory.
A module can call other modules, which lets you include the child module's resources into the configuration in a concise way. Modules can also be called multiple times, either within the same configuration or in separate configurations, allowing resource configurations to be packaged and re-used.
Agora que temos os pre-requisitos instalados, iremos entao proceder à primeira aplicação de um terraform module para aprovisionar um cluster GKE.
- No ficheiro ./gke.tf encontra-se a invocação do module
- Por cada module é preciso fazer
terraform init
👉 No ficheiro ./gke.tf, descomentar as seguintes resources:
module "gke"
output "gke_name"
output "gke_location"
Primeiro temos que executar terraform init
para inicializar o modulo:
terraform init
Executar o plan
& apply
:
terraform plan -out plan.tfplan
terraform apply plan.tfplan
⏰ Notem que a criação de um cluster GKE pode levar até 10 minutos...
Podemos verificar que o nosso cluster foi corretamente criado através do comando:
gcloud container clusters list --project $(terraform output -raw project_id) | grep $(terraform output -raw my_identifier)
Também é possivel verificar o estado do cluster pela GUI aqui.
O acesso a um GKE, tal como qualquer outro cluster de Kubernetes, é feito a partir da cli kubectl
. Para podermos executar comandos kubectl
precisamos primeiro de garantir que temos uma configuração válida para aceder ao nosso cluster.
Usar o comando gcloud
para construir um KUBECONFIG
válido para aceder ao cluster:
export KUBECONFIG=$(pwd)/kubeconfig.yaml && gcloud container clusters get-credentials $(terraform output -raw gke_name) --zone $(terraform output -raw gke_location) --project $(terraform output -raw project_id)
Verificar o acesso ao cluster:
kubectl get nodes
Nesta secção abordar a utilização de um provider (kubectl provider) para instanciar (via terraform) todos os workloads que vão correr no nosso cluster.
Trata-se de um provider da comunidade que tal como o nome indica, facilita a utilização de terraform para orquestrar ficheiros yaml
.
from docs: This provider is the best way of managing Kubernetes resources in Terraform, by allowing you to use the thing Kubernetes loves best - yaml!
👉 Para habilitar o modulo, temos que ir ao ficheiro ./k8s.hipster.tf
e descomentar o seguinte modulo:
module "hipster"
- ⛔ não descomentar a linha
fqdn
; será habilitado mais a frente ⛔
💡Os microserviços utilizados nesta demo, encontram-se neste registry e o respetivo código neste repositório de github.
Executar terraform init
para inicializar o modulo:
terraform init
Executar o plan
& apply
:
terraform plan -out plan.tfplan
terraform apply plan.tfplan
⏰ Após o apply
, pode demorar uns minutos a acabar o comando pois o terraform espera que os pods estejam em Running
state.
Podemos verificar que os pods foram corretamente instanciados:
kubectl get pods -n hipster-demo
Também podemos constatar que o cluster-autoscaler teve que aprovisionar mais nodes para acautelar o demand 😃🚀
kubectl get nodes
Para testar e validar a nossa aplicação antes de a colocar em "produção", podemos tirar partido da capacidade de fazer port-forward
.
Para iniciar um port-forward
no porto 8080
:
kubectl port-forward -n hipster-demo service/frontend 8080:80
- Após este passo, basta testar a aplicação no port-foward que foi estabelecido no seguinte url: http://localhost:8080
- Se estiverem a usar a Google CloudShell podem clicar em
Preview on Port 8080
no canto superior direito
Conseguimos validar que os workloads estao a funcionar.
- O próximo passo será expor a partir dos ingresses e respectivos load-balancers do GKE
- Para isso precisamos de um DNS para HTTP/HTTPS
- Caso queiramos usar HTTPS vamos também precisar de um certificado SSL
No ficheiro ./dns.tf
encontra-se a definição do modulo.
👉 Para habilitar o modulo ./dns.tf
precisamos de descomentar as seguintes resources:
module "dns"
output "fqdn"
Executar terraform init
para inicializar o modulo:
terraform init
Executar o plan
& apply
:
terraform plan -out plan.tfplan
terraform apply plan.tfplan
Podemos verificar que a nossa zona de DNS foi corretamente criada através do seguinte comando:
gcloud dns managed-zones list --project $(terraform output -raw project_id) | grep $(terraform output -raw my_identifier)
O external-dns
é a cola entre o Kubernetes e o DNS.
from docs: ExternalDNS synchronizes exposed Kubernetes Services and Ingresses with DNS providers.
No ficheiro é necessário passar o fqdn devolvido pelo modulo de dns.
👉 Descomentar o modulo external_dns
no ficheiro ./k8s.external-dns.tf
:
module "external_dns"
output "fqdn"
Na diretória ./modules/external-dns
encontra-se a implementação do modulo external-dns
que permite atualizar os registos DNS automaticamente.
Executar o init
pois estamos a introduzir um novo modulo:
terraform init
Executar o plan
& apply
:
terraform plan -out plan.tfplan
terraform apply plan.tfplan
Podemos verificar a criação do external-dns
pelo seguinte comando:
kubectl get pods -n external-dns
Podemos também investigar os logs emitidos pelo deployment:
kubectl logs -n external-dns -l app=external-dns --follow
from docs: Ingress exposes HTTP and HTTPS routes from outside the cluster to services within the cluster. Traffic routing is controlled by rules defined on the Ingress resource.
A criação do ingress
será o culminar das últimas operações que efectuamos (DNS + HTTPS).
- Só será possivel aceder ao nosso site via internet se o expormos a partir de um ingress;
- A criação do ingress irá despoletar a criação de um balanceador com um IP público bem como a geração de um certificado gerido pela Google;
- Após a atribuição do IP, o
external-dns
irá atualizar o DNS com o respetivo IP; - Uma vez criado o registo no DNS, o GCE irá aprovisionar o certificado automaticamente;
- ⏰ Todo o processo pode levar até cerca de 10 minutos a acontecer;
👉 No ficheiro ./k8s.hipster.tf
iremos descomentar a secção 3.3 onde iremos modificar o comportamento do modulo da seguinte forma:
-
Atribuir o
fqdn
dado pelo modulo dedns
á variávelfqdn
; ofqdn
representa o domínio onde vai ser criado o host declarado peloingress
.fqdn = module.dns.fqdn
-
Ativar a criação dos manifestos de ingress através da variável boleana
ingress_enabled
.ingress_enabled = true
Executar o plan
& apply
:
terraform plan -out plan.tfplan
terraform apply plan.tfplan
Podemos verificar a criação do ingress
e a respetiva atribuição de IP a partir dos seguintes comandos:
kubectl get ingress -n hipster-demo
kubectl describe ingress -n hipster-demo hipster-ingress
Também podemos verificar a atuação do external-dns
assim que o ingress ganhou um IP:
kubectl logs -f -n external-dns -l app=external-dns
Ou então podemos verificar os registos no Cloud DNS:
gcloud dns record-sets list --zone $(terraform output -raw my_identifier)-dns --project $(terraform output -raw project_id)
🚀 Infelizmente, devido ao tempo que a Google demora a gerar os certificados, o site só estará disponível quando o certificado for gerado e a chain estiver devidamente validada. Este processo leva cerca de 10 minutos ⏰😡
Podemos verificar o estado do mesmo usando o seguinte comando:
kubectl describe managedcertificates -n hipster-demo hipster
Por fim, podemos destruir tudo de uma só vez.
⏰ Notem que devido à quantidade de recursos envolvidos, a operação de destroy pode demorar entre 10 a 20 minutos.
terraform destroy
🔚🏁 Chegámos ao fim 🏁🔚