Differences

This shows you the differences between two versions of the page.

Link to this comparison view

cc:temp [2022/11/06 13:40]
florin.mihalache
cc:temp [2022/11/11 23:12] (current)
florin.mihalache [Deployments & virtual machines în AWS]
Line 1: Line 1:
 ====== Laboratorul 05 - Terraform + AWS ====== ====== Laboratorul 05 - Terraform + AWS ======
 +
 +===== Deployments & virtual machines în AWS =====
 +În cadrul acestui laborator veți învăța cum să creați mașini virtuale în cadru AWS (Amazon Web Services), care reprezintă o platformă care furnizează servicii de tip cloud computing, baze de date, stocare de fișiere, device farms, etc.
 +
 +Pentru acest laborator presupunem că avem deja Terraform instalat de la laboratorul precedent. Dacă nu aveți Terraform instalat, puteți urma pașii din laboratorul anterior.
 +
 +Pe langa Terraform, avem nevoie de AWS CLI instalat. Pentru a instala, urmati pasii de [[https://​docs.aws.amazon.com/​cli/​latest/​userguide/​getting-started-install.html | aici]].
 +
 +Pe lângă asta, avem nevoie de un cont pentru Amazon AWS. După ce ați făcut pașii pentru a avea propriul cont AWS, vrem sa conectăm AWS CLI la consola de AWS.
 +
 +Pentru a face asta, mergem în AWS și intrăm în secțiunea IAM:
 +{{ :​cc:​laboratoare:​lab-5-image3.png?​700 |}}
 +
 +Apoi mergem la "My security credentials":​
 +{{ :​cc:​laboratoare:​lab-5-image1.png?​700 |}}
 +
 +Următorul pas este să mergem la "​Access Keys" și să apăsăm pe butonul de ''​Create New Access Key'':​
 +{{ :​cc:​laboratoare:​lab-5-image5.png?​700 |}}
 +
 +Păstrați fișierul generat. Rulați comanda ''​aws configure''​ și introduceți datele generate în fisierul creat anterior (''​AWSAccessKeyId''​ și ''​AWSSecretKey''​).
 +
 +Pentru a crea o instanță simplă de EC2 (o mașina virtuală) folosim următorul fișier de Terraform:
 +<code terraform>​
 +terraform {
 + ​required_providers {
 +   aws = {
 +     ​source ​ = "​hashicorp/​aws"​
 +     ​version = "~> 4.16"
 +   }
 + }
 + 
 + ​required_version = ">= 1.2.0"
 +}
 + 
 +provider "​aws"​ {
 + ​region = "​us-west-2"​ # regiunea in care o sa se faca deploy la resurse
 +}
 + 
 +resource "​aws_instance"​ "​app_server"​ {
 + ​ami ​          = "​ami-830c94e3"​ # tipul de masina folosita (ami = Amazon Machine Image)
 + ​instance_type = "​t2.micro"​ # tipul de instanta (resursele pe care le are masina)
 + 
 + tags = {
 +   Name = "​labAwsTerraform"​
 + }
 +}
 +</​code>​
 +
 +Rulați comenzile cunoscute pentru a face deployment acestei infrastructuri:​
 +<code bash>
 +terraform init
 +terraform fmt
 +terraform plan
 +terraform apply
 +</​code>​
 +
 +Pentru a verifica ca mașina virtuală a fost deployed, căutăm serviciul EC2:
 +{{ :​cc:​laboratoare:​lab-5-image7.png?​700 |}}
 +
 +Ajungem în pagina următoare în care vedem că nu avem nicio instanță up and running, deși planul nostru de Terraform a fost executat cu succes. De ce?
 +{{ :​cc:​laboratoare:​lab-5-image4.png?​700 |}}
 +
 +Observați diferența de regiuni (Frankfurt, în cazul din imaginea anterioară,​ față de us-west-2 în Terraform). Pentru a modifica regiunea în care facem deployment la resurse modificăm codul Terraform. În cazul de față, putem să facem click pe Frankfurt și să selectăm us-west-2 (Oregon). În acest moment putem vedea că avem o instanță up and running:
 +{{ :​cc:​laboratoare:​lab-5-image2.png?​700 |}}
 +
 +<note tip>
 +În codul Terraform modificați numele masinii din ''​labAwsTerraform''​ în ''​testUpdate''​.
 +Rulatț comenzile obișnuite pentru a vedea planul.
 +Observați că această modificare nu implică distrugerea mașinii existente, ci doar modificarea in-place.
 +</​note>​
 +
 +{{ :​cc:​laboratoare:​lab-5-image6.png?​700 |}}
 +
 +===== Cluster Kubernetes în AWS =====
 +Pentru a face deployment unui cluster de Kubernetes în AWS avem 2 opțiuni.
 +  - Facem deploy la mai multe mașini virtuale și instalăm și configurăm un cluster de mână.
 +  - Folosim serviciul AWS special conceput pentru clusters de Kubernetes, AWS EKS Cluster
 +
 +În cazul acestui laborator, o să facem deployment la un cluster folosind EKS.
 +
 +Pentru a urma best practices recomandate de hashicorp, o să spargem codul în mai multe fișiere.
 +
 +Fișierul ''​variables.tf''​ o sa conțină o simplă variabilă în care definim zona în care vrem să facem deployment:
 +<code terraform>​
 +variable "​region"​ {
 + ​description = "AWS region"​
 + ​type ​       = string
 + ​default ​    = "​us-west-2"​
 +}
 +</​code>​
 +
 +Mai departe avem nevoie de un VPC, deci vom crea un nou fisier ''​vpc.tf''​. Mai multe despre ce este un VPC: [[https://​docs.aws.amazon.com/​vpc/​latest/​userguide/​what-is-amazon-vpc.html | aici]].
 +<​code>​
 +module "​vpc"​ {
 + ​source ​ = "​terraform-aws-modules/​vpc/​aws"​
 + ​version = "​3.14.2"​
 + 
 + name = "​cc-vpc"​
 + 
 + cidr = "​10.0.0.0/​16"​
 + ​azs ​ = slice(data.aws_availability_zones.available.names,​ 0, 3)
 + 
 + ​private_subnets = ["​10.0.1.0/​24",​ "​10.0.2.0/​24",​ "​10.0.3.0/​24"​]
 + ​public_subnets ​ = ["​10.0.4.0/​24",​ "​10.0.5.0/​24",​ "​10.0.6.0/​24"​]
 + 
 + ​enable_nat_gateway ​  = true
 + ​single_nat_gateway ​  = true
 + ​enable_dns_hostnames = true
 + 
 + ​public_subnet_tags = {
 +   "​kubernetes.io/​cluster/​${local.cluster_name}"​ = "​shared"​
 +   "​kubernetes.io/​role/​elb" ​                     = 1
 + }
 + 
 + ​private_subnet_tags = {
 +   "​kubernetes.io/​cluster/​${local.cluster_name}"​ = "​shared"​
 +   "​kubernetes.io/​role/​internal-elb" ​            = 1
 + }
 +}
 +</​code>​
 +
 +Mai multe detalii despre modulul de Terraform pentru VPC: [[https://​registry.terraform.io/​providers/​hashicorp/​aws/​latest/​docs/​resources/​vpc | aici]].
 +
 +În continuare avem nevoie de 2 security groups, pe care o să le folosească cluster-ul nostru. Așadar creăm un nou fișier cu numele ''​securityGroups.tf''​ cu următorul conținut:
 +<​code>​
 +resource "​aws_security_group"​ "​node_group_one"​ {
 + ​name_prefix = "​node_group_one"​
 + ​vpc_id ​     = module.vpc.vpc_id
 + 
 + ​ingress {
 +   ​from_port = 22
 +   ​to_port ​  = 22
 +   ​protocol ​ = "​tcp"​
 + 
 +   ​cidr_blocks = [
 +     "​10.0.0.0/​8",​
 +   ]
 + }
 +}
 + 
 +resource "​aws_security_group"​ "​node_group_two"​ {
 + ​name_prefix = "​node_group_two"​
 + ​vpc_id ​     = module.vpc.vpc_id
 + 
 + ​ingress {
 +   ​from_port = 22
 +   ​to_port ​  = 22
 +   ​protocol ​ = "​tcp"​
 + 
 +   ​cidr_blocks = [
 +     "​192.168.0.0/​16",​
 +   ]
 + }
 +}
 +</​code>​
 +
 +Ne putem gândi la un security group ca la un firewall. Mai multe detalii în [[https://​aviatrix.com/​learn-center/​cloud-security/​aws-security-groups/​ | documentație]]. Documentația unui security group de AWS în Terraform: [[https://​registry.terraform.io/​providers/​hashicorp/​aws/​latest/​docs/​resources/​security_group | aici]].
 +
 +
 +Până acum am definit doar componentele de care o să ne folosim în momentul în care configurăm cluster-ul nostru. Pentru a face asta, avem un nou fișier ''​cluster.tf''​ cu următoarea configurație:​
 +<​code>​
 +module "​eks"​ {
 + ​source ​ = "​terraform-aws-modules/​eks/​aws"​
 + ​version = "​18.26.6"​
 + 
 + ​cluster_name ​   = local.cluster_name
 + ​cluster_version = "​1.22"​
 + 
 + ​vpc_id ​    = module.vpc.vpc_id
 + ​subnet_ids = module.vpc.private_subnets
 + 
 + ​eks_managed_node_group_defaults = {
 +   ​ami_type = "​AL2_x86_64"​
 + 
 +   ​attach_cluster_primary_security_group = true
 + 
 +   # Disabling and using externally provided security groups
 +   ​create_security_group = false
 + }
 + 
 + ​eks_managed_node_groups = {
 +   one = {
 +     name = "​node-group-1"​
 + 
 +     ​instance_types = ["​t3.small"​]
 + 
 +     ​min_size ​    = 1
 +     ​max_size ​    = 3
 +     ​desired_size = 2
 + 
 +     ​pre_bootstrap_user_data = <<​-EOT
 +     echo 'foo bar'
 +     EOT
 + 
 +     ​vpc_security_group_ids = [
 +       ​aws_security_group.node_group_one.id
 +     ]
 +   }
 + 
 +   two = {
 +     name = "​node-group-2"​
 + 
 +     ​instance_types = ["​t3.medium"​]
 + 
 +     ​min_size ​    = 1
 +     ​max_size ​    = 2
 +     ​desired_size = 1
 + 
 +     ​pre_bootstrap_user_data = <<​-EOT
 +     echo 'foo bar'
 +     EOT
 + 
 +     ​vpc_security_group_ids = [
 +       ​aws_security_group.node_group_two.id
 +     ]
 +   }
 + }
 +}
 +</​code>​
 +
 +Mai avem doar de creat un fișier ''​main.tf''​ cu următoarea configurație:​
 +<​code>​
 +provider "​kubernetes"​ {
 + ​host ​                  = module.eks.cluster_endpoint
 + ​cluster_ca_certificate = base64decode(module.eks.cluster_certificate_authority_data)
 +}
 + 
 +provider "​aws"​ {
 + ​region = var.region
 +}
 + 
 +data "​aws_availability_zones"​ "​available"​ {}
 + 
 +locals {
 + ​cluster_name = "​cc-eks-${random_string.suffix.result}"​
 +}
 + 
 +resource "​random_string"​ "​suffix"​ {
 + ​length ​ = 8
 + ​special = false
 +}
 +</​code>​
 +
 +Pentru a afișa câteva informații legate de infrastructura noastră avem nevoie de câteva outputs. Așa cum am învățat data trecută, facem un fișier separat în care definim acest outputs:
 +<​code>​
 +output "​cluster_id"​ {
 + ​description = "EKS cluster ID"
 + ​value ​      = module.eks.cluster_id
 +}
 + 
 +output "​cluster_endpoint"​ {
 + ​description = "​Endpoint for EKS control plane"
 + ​value ​      = module.eks.cluster_endpoint
 +}
 + 
 +output "​cluster_security_group_id"​ {
 + ​description = "​Security group ids attached to the cluster control plane"
 + ​value ​      = module.eks.cluster_security_group_id
 +}
 + 
 +output "​region"​ {
 + ​description = "AWS region"​
 + ​value ​      = var.region
 +}
 + 
 +output "​cluster_name"​ {
 + ​description = "​Kubernetes Cluster Name"
 + ​value ​      = local.cluster_name
 +}
 +</​code> ​
 +
 +Rulăm comenzile obișnuite pentru a crea infrastructura. Observați ca sunt foarte multe resurse care urmează să se construiască.
 +
 +In cazul in care ați realizat ca lipsește ceva (nu am definit niciunde ce versiuni ale provider-ilor vrem să folosim), best practices recomandă să avem un fișier numit ''​terraform.tf''​ care să conțină această configurație:​
 +<​code>​
 +terraform {
 + ​required_providers {
 +   aws = {
 +     ​source ​ = "​hashicorp/​aws"​
 +     ​version = "~> 4.15.0"​
 +   }
 + 
 +   ​random = {
 +     ​source ​ = "​hashicorp/​random"​
 +     ​version = "~> 3.1.0"
 +   }
 + 
 +   tls = {
 +     ​source ​ = "​hashicorp/​tls"​
 +     ​version = "~> 3.4.0"
 +   }
 + 
 +   ​cloudinit = {
 +     ​source ​ = "​hashicorp/​cloudinit"​
 +     ​version = "~> 2.2.0"
 +   }
 + 
 +   ​kubernetes = {
 +     ​source ​ = "​hashicorp/​kubernetes"​
 +     ​version = "~> 2.12.1"​
 +   }
 + }
 +}
 +</​code>​
 +
 +Asteptați ca planul să se termine de rulat sș verificați infrastructura creată în AWS (o să dureze în jur de 15-20 minute). Apoi, pentru a ne conecta la cluster-ul nostru proaspăt creat de Kubernetes, folosim următoarea comandă:
 +<code bash>
 +aws eks --region $(terraform output -raw region) update-kubeconfig \
 +    --name $(terraform output -raw cluster_name)
 +</​code>​
 +
 +Verificați conexiunea cu următoarea comandă: ''​kubectl cluster-info''​
 +
 +În acest moment avem un cluster configurat în AWS EKS și suntem conectați la el. Orice comandă de kubectl rulată o să fie executată pe cluster-ul nostru.
 +
  
cc/temp.1667734814.txt.gz · Last modified: 2022/11/06 13:40 by florin.mihalache
CC Attribution-Share Alike 3.0 Unported
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0