Your Web News in One Place

Help Webnuz

Referal links:

Sign up for GreenGeeks web hosting
August 16, 2022 03:00 pm GMT

Despliegue y prueba de servicios creados con Terraform en AWS

Terraform es una herramienta de IaC multicloud, basado en el lenguaje de configuracin Hansicorp que es un tipo de JSON.

Las plantillas de Terraform generalmente se distribuyen de la siguiente forma:

Template Structure

Provider: Se define la nube en la cual vamos a trabajar.
DataSources-Parameters: Se definen los parmetros o variables que vamos a utilizar dentro de nuestra plantilla.
Resources: Definimos los recursos a desplegar.

La siguiente arquitectura muestra los recursos que vamos a desplegar en AWS con Terraform.

Arquitectura

plantilla

# PROVIDERprovider "aws" {    region = "${var.aws_regions[0]}"    #Se definen los tags comunes a todos los resources    default_tags {        tags = {            despliegue = "Terraform AWS"        }    }}#DATA - PARAMETERS - VARIABLESlocals {  tags = {    despliegue = "Terraform AWS"  }}variable "amiinstance" {    default = "ami-090fa75af13c156b4"    type = string  }variable "aws_regions" {    default = [        "us-east-1",        "us-east-2"    ]    type = list}variable "aws_instance_size" {    type = map    default= {        small = "t2.micro",        medium = "t2.medium",        large = "t2.large"    }}variable "aws_instancedb_size" {    type = map    default= {        small = "db.t2.micro",        medium = "db.t2.small"    }}variable "tag" {    default = "template_terraform"    type = string}variable "cidr_subnets" {    default = [        "10.0.1.0/24",#public        "10.0.2.0/28",#private        "10.0.3.0/28"#private    ]    type = list}#RESOURCESresource "aws_vpc" "vpcterraform" {    cidr_block = "10.0.0.0/16"    enable_dns_hostnames = true    tags = {        Name = "${var.tag}"    }}resource "aws_internet_gateway" "igwterraform" {    vpc_id = "${aws_vpc.vpcterraform.id}"    tags = {        Name = "routeTableTFPublic_${var.tag}"    }}resource "aws_route_table" "routeTableTFPublic" {    vpc_id = "${aws_vpc.vpcterraform.id}"    route {        cidr_block = "0.0.0.0/0"        gateway_id = "${aws_internet_gateway.igwterraform.id}"    }    tags = {        Name = "routeTableTFPublic_${var.tag}"    }}resource "aws_route_table" "routeTablerivate" {    vpc_id = "${aws_vpc.vpcterraform.id}"    tags = {        Name = "routeTableTFPrivate_${var.tag}"    }}resource "aws_subnet" "publicsubnet1" {    vpc_id = "${aws_vpc.vpcterraform.id}"    cidr_block = var.cidr_subnets[0]    map_public_ip_on_launch = true    availability_zone = "us-east-1a"    tags = {        Name = "publicsubnet1_${var.tag}"    }}resource "aws_route_table_association" "routeTableAssociationTF" {    subnet_id = "${aws_subnet.publicsubnet1.id}"    route_table_id = "${aws_route_table.routeTableTFPublic.id}"}resource "aws_subnet" "privatesubnet1" {    vpc_id = "${aws_vpc.vpcterraform.id}"    cidr_block = var.cidr_subnets[1]    availability_zone = "us-east-1b"    tags = {        Name = "privatesubnet1_${var.tag}"    }}resource "aws_subnet" "privatesubnet2" {    vpc_id = "${aws_vpc.vpcterraform.id}"    cidr_block = var.cidr_subnets[2]    availability_zone = "us-east-1c"    tags = {        Name = "privatesubnet2_${var.tag}"    }}resource "aws_db_subnet_group" "dbprivatesubnetgroup"{    name = "dbprivatesubnetgroup"    subnet_ids = ["${aws_subnet.privatesubnet1.id}","${aws_subnet.privatesubnet2.id}"]    tags = {        Name = "dbprivatesubnetgroup_${var.tag}"    }}resource "aws_iam_role" "instance_role" {    assume_role_policy = jsonencode({        "Version": "2012-10-17",        "Statement": [        {            "Effect": "Allow",            "Action": [                "sts:AssumeRole"            ],            "Principal": {                "Service": [                    "ec2.amazonaws.com"                ]            }        }        ]    })    tags = {        tag-key = "role_${var.tag}"    }}resource "aws_iam_policy" "policy"{    policy = jsonencode({        "Version": "2012-10-17",        "Statement": [            {                "Effect": "Allow",                "Action": [                    "cloudwatch:PutMetricData",                    "ds:CreateComputer",                    "ds:DescribeDirectories",                    "ec2:DescribeInstanceStatus",                    "logs:*",                    "ssm:*",                    "ec2messages:*"                ],                "Resource": "*"            },            {                "Effect": "Allow",                "Action": "iam:CreateServiceLinkedRole",                "Resource": "arn:aws:iam::*:role/aws-service-role/ssm.amazonaws.com/AWSServiceRoleForAmazonSSM*",                "Condition": {                    "StringLike": {                        "iam:AWSServiceName": "ssm.amazonaws.com"                    }                }            },            {                "Effect": "Allow",                "Action": [                    "iam:DeleteServiceLinkedRole",                    "iam:GetServiceLinkedRoleDeletionStatus"                ],                "Resource": "arn:aws:iam::*:role/aws-service-role/ssm.amazonaws.com/AWSServiceRoleForAmazonSSM*"            },            {                "Effect": "Allow",                "Action": [                    "ssmmessages:CreateControlChannel",                    "ssmmessages:CreateDataChannel",                    "ssmmessages:OpenControlChannel",                    "ssmmessages:OpenDataChannel"                ],                "Resource": "*"            }        ]    })    tags = {        tag-key = "policy_${var.tag}"    }}resource "aws_iam_role_policy_attachment" "policy_attachment" {    role = "${aws_iam_role.instance_role.name}"    policy_arn = "${aws_iam_policy.policy.arn}"}resource "aws_iam_instance_profile" "instance_profile" {    role  = "${aws_iam_role.instance_role.name}"}resource "aws_security_group" "sg_instance" {    vpc_id = "${aws_vpc.vpcterraform.id}"    ingress {        from_port = 22        to_port = 22        protocol ="tcp"        cidr_blocks = ["0.0.0.0/0"]    }    ingress {        from_port   = 80        to_port     = 80        protocol    = "tcp"        cidr_blocks = ["0.0.0.0/0"]    }    egress {        from_port   = 0        to_port     = 0        protocol    = "-1"        cidr_blocks = ["0.0.0.0/0"]    }    tags = {        Name = "sg_instance_${var.tag}"    }}resource "aws_instance" "instancia" {    ami= "${var.amiinstance}"    instance_type = "${var.aws_instance_size.small}"    subnet_id = "${aws_subnet.publicsubnet1.id}"    vpc_security_group_ids = [ "${aws_security_group.sg_instance.id}" ]    tags = {        Name = "instancia_${var.tag}"    }    iam_instance_profile = "${aws_iam_instance_profile.instance_profile.id}"    depends_on = [aws_internet_gateway.igwterraform]    user_data = <<EOF    #!/bin/bash    yum update -y    yum install httpd -y    service httpd start    chkconfig httpd on    cd /var/www/html    echo "<html><body><h1>Terraform Instancia: $(hostname -f)</h1></body></html>" > index.html    EOF}resource "aws_security_group" "sgbd" {    name = "sg"    vpc_id = "${aws_vpc.vpcterraform.id}"    ingress {        from_port = 3306        to_port = 3306        protocol ="tcp"        cidr_blocks = ["${aws_instance.instancia.private_ip}/32"]    }    tags = {        Name = "sgbd_${var.tag}"    }}resource "aws_db_instance" "dbinstance" {    db_subnet_group_name = "${aws_db_subnet_group.dbprivatesubnetgroup.name}"    engine = "mysql"    db_name = "dbterraform"    engine_version = "5.7.28"    instance_class = "${var.aws_instancedb_size.small}"    username = "admin"    password = "admin12345678"    allocated_storage = 10    skip_final_snapshot = true    vpc_security_group_ids =  [ "${aws_security_group.sgbd.id}" ]    tags = {        Name = "dbinstance_${var.tag}"    }}output "endpoint" {    value = "${aws_instance.instancia.public_ip}"}

Terraform tiene comandos para iniciar, validar, desplegar y destruir los recursos definidos en nuestras plantillas (Antes de usar los siguientes comandos recuerden configurar sus access keys con el comando aws configure).

1.terraform init: Configura el directorio donde se encuentra nuestra plantilla para que pueda ser usado con Terraform.

Init

2.terraform validate: Valida que la plantilla no tenga errores de sintaxis o de lgica.

Validate

3.terraform plan: Nos muestra una descripcin de los recursos que van a ser desplegados, valida si hay cambios en nuestros recursos (en caso de actualizacin) y valida que nuestra plantilla no tenga errores.

Plan

4.terraform apply: Nos va a mostrar la infraestructura que se va a desplegar y nos va a preguntar que s estamos de acuerdo por lo que debemos escribir yes para que inicie el despliegue de nuestros servicios.

Terraform apply

Al final nos va a mostrar la cantidad de recursos que se crearon y los outputs que tenemos definidos en la plantilla.

Terraform apply

Terraform al desplegar nuestra infraestructura crea el archivo
terraform.tfstate donde se guarda la informacin de los recursos desplegados.
Podemos ver qu recursos se desplegaron con el comando: terraform state list y podemos ver la informacin del recurso con el comando terraform state show nombre_del_recurso.

Una vez que se han creado todos nuestros recursos, vamos a verlos en la consola de AWS. Para esto buscamos resources groups y le damos click.

Resources Groups

Ya en la pantalla principal damos click en Tag Editor, seleccionamos todas las regiones, todos los recursos, en los tags escribimos despliegue - Terraform AWS y damos click en le botn Search Resources. Esto nos va a traer todos los recursos que tiene este tag.

Tag Editor

El resultado de la bsqueda nos va a mostrar los recursos que cumplen las condiciones anteriores.

Search Tag Editor

Este resultado lo obtuvimos ya que a todos los recursos de la plantilla les asignamos el tag: Name: despliegue - Value: Terraform AWS, en el siguiente fragmento de la plantilla:

provider "aws" {    region = "${var.aws_regions[0]}"    #Se definen los tags comunes a todos los resources    default_tags {        tags = {            despliegue = "Terraform AWS"        }    }}

Ahora vamos a validar el funcionamiento de nuestra aplicacin. En la pantalla de resultados damos click en la instancia de EC2 que creamos.

Click Instance

Los que nos lleva a la pantalla de EC2 y copiamos la Ip publica de la instancia y la colocamos en una nueva pestaa de nuestro navegador.

Click Instance

lo que nos va a mostrar lo siguiente:

Click Instance

Este resultado lo obtuvimos ya que en nuestra definicin de la instancia dentro dentro de la propiedad user data le pedimos que instalara apache y creara una pagina web.

resource "aws_instance" "instancia" {    ami= "${var.amiinstance}"    instance_type = "${var.aws_instance_size.small}"    subnet_id = "${aws_subnet.publicsubnet1.id}"    vpc_security_group_ids = [ "${aws_security_group.sg_instance.id}" ]    tags = {        Name = "instancia_${var.tag}"    }    iam_instance_profile = "${aws_iam_instance_profile.instance_profile.id}"    user_data = <<EOF    #!/bin/bash    yum update -y    yum install httpd -y    service httpd start    chkconfig httpd on    cd /var/www/html    echo "<html><body><h1>Terraform Instancia: $(hostname -f)</h1></body></html>" > index.html    yum install mysql    EOF}

De acuerdo a la anterior definicin de nuestra instancia, no definimos un access key para poder ingresar a ella desde la terminal.
Para acceder a la instancia y validar nuestra base de datos vamos a buscar el servicio System Manager.

System Manager

En la pagina principal damos click Session Manager, despus en Start Session.

Session Manager

Ahora seleccionamos la instancia que creamos y damos click en el botn Start Session

Start Session

Lo que nos va abrir una terminal como la siguiente.

Terminal

Donde podemos ejecutar los comandos para acceder a la base de datos creada con la plantilla:

Instalar mysql (para usar como cliente):

sudo susudo yum install mysql

Conectarse a la base de datos:

mysql -h reemplezar_por_endpoint_basededatos -u admin -p database

Para lograr abrir la terminal desde System Manager se crearon los siguientes recursos en la plantilla:

aws_iam_roleaws_iam_policyaws_iam_role_policy_attachmentaws_iam_instance_profile

para asociar el recurso aws_iam_instance_profile a nuestra instancia.

5.terraform destroy: al ejecutar el comando nos muestra los recursos que se van a eliminar, despus nos solicita que autoricemos la eliminacin por lo que debemos escribir yes.

Destroy

Con la ejecucin de estos comando terminamos con el despliegue y la liberacin de los recursos desplegados con Terraform.

Terraform me parece practico ya que su sintaxis se me asemeja al desarrollo (he trabajado como desarrollador). Una de las cosas que creo mas importantes para trabajar con herramientas IAC es la documentacin la cual me pareci sencilla pero practica.

Para mejorar la plantilla pueden crear archivos separados para las variables, para los outputs y realizar la misma ejecucin de comandos, esto con el fin que nuestra plantilla quede ms organizada y legible.

Camilo Cabrales

Referencias

Documentacin

Instalacin

Comando Init

Comando Plan

Comando Destroy


Original Link: https://dev.to/cecamilo/despliegue-y-prueba-de-servicios-creados-con-terraform-en-aws-a6

Share this article:    Share on Facebook
View Full Article

Dev To

An online community for sharing and discovering great ideas, having debates, and making friends

More About this Source Visit Dev To