Al final me he decidido y he dado el paso a probar esta herramienta de IA. Últimamente trabajo mucho con Terraform y tengo curiosidad de saber cómo funciona y cómo me puede ayudar en mi día a día. GitHub ofrece dos versiones de Copilot, una para cuentas individuales y otra para empresas. Para cuentas individuales ofrecen una prueba de 30 días: https://github.com/features/copilot
Copilot for Individuals | Copilot for Business |
---|---|
Plugs right into your editor | Everything included in Copilot for Individuals, plus… |
Turns natural language prompts into code | Simple license management |
Offers multi-line function suggestions | Organization-wide policy management |
Speeds up test generation | Industry-leading privacy |
Filters out common vulnerable coding patterns | Corporate proxy support |
Blocks suggestions matching public code | Copilot Chat beta |
Tengo mi entorno preparado, he instalado la extensión GitHub Copilot en VS Code y conectado con github.com. He creado un archivo main.tf, he comenzado a escribir y ha comenzado la acción.
Lo primero que he querido configurar es el bloque terraform para configurar required_version. Tras escribirlo, automáticamente me lo ha sugerido. Las sugerencias las muestra con un tono grisaceo, basta con tabular para aceptarla o seguir escribiendo para que de forma automática estas cambien adaptándose al código que estamos configurando.
Aquí comienza lo bueno, al presionar enter dos veces para comenzar a escribir el siguiente bloque de código ya me está sugiriendo la creación del bloque provider. En este caso me lo configura con aws pero yo lo edito para que sea azurerm.
Vuelvo a repetir, presiono enter dos veces y me sugiere la creación de un grupo de recursos, con el nombre y la localización definidas.
Si observamos no me ha sugerido el bloque required_providers ni backend dentro del bloque de terraform, el cual resuelvo presionando enter dos veces después de required_version y automáticamente me sugiere ambos bloques.
Siguiendo aplicando este metodo, Copilot me ha sugerido los siguientes recursos que muestro a continuación.
terraform {
required_version = ">= 0.12"
required_providers {
azurerm = {
source = "hashicorp/azurerm"
version = "=2.0.0"
}
}
backend "azurerm" {
resource_group_name = "rg-terraform-azure"
storage_account_name = "terraformazurestorage"
container_name = "tfstate"
key = "terraform.tfstate"
}
}
provider "azurerm" {
version = "=2.0.0"
features {}
}
resource "azurerm_resource_group" "rg" {
name = "rg-terraform-azure"
location = "West Europe"
}
resource "azurerm_virtual_network" "vnet" {
name = "vnet-terraform-azure"
address_space = ["10.0.0.0/16"]
location = azurerm_resource_group.rg.location
resource_group_name = azurerm_resource_group.rg.name
}
resource "azurerm_subnet" "subnet" {
name = "subnet-terraform-azure"
resource_group_name = azurerm_resource_group.rg.name
virtual_network_name = azurerm_virtual_network.vnet.name
address_prefix = "10.10.1.10/24"
}
resource "azurerm_network_security_group" "nsg" {
name = "nsg-terraform-azure"
location = azurerm_resource_group.rg.location
resource_group_name = azurerm_resource_group.rg.name
}
resource "azurerm_network_security_rule" "nsg_rule" {
name = "nsg-rule-terraform-azure"
priority = 100
direction = "Inbound"
access = "Allow"
protocol = "Tcp"
source_port_range = "*"
destination_port_range = "80"
source_address_prefix = "*"
destination_address_prefix = "*"
resource_group_name = azurerm_resource_group.rg.name
network_security_group_name = azurerm_network_security_group.nsg.name
}
resource "azurerm_public_ip" "public_ip" {
name = "public-ip-terraform-azure"
location = azurerm_resource_group.rg.location
resource_group_name = azurerm_resource_group.rg.name
allocation_method = "Dynamic"
}
resource "azurerm_network_interface" "nic" {
name = "nic-terraform-azure"
location = azurerm_resource_group.rg.location
resource_group_name = azurerm_resource_group.rg.name
ip_configuration {
name = "ipconfig-terraform-azure"
subnet_id = azurerm_subnet.subnet.id
private_ip_address_allocation = "Dynamic"
public_ip_address_id = azurerm_public_ip.public_ip.id
}
}
resource "azurerm_virtual_machine" "vm" {
name = "vm-terraform-azure"
location = azurerm_resource_group.rg.location
resource_group_name = azurerm_resource_group.rg.name
network_interface_ids = [azurerm_network_interface.nic.id]
vm_size = "Standard_DS1_v2"
storage_image_reference {
publisher = "Canonical"
offer = "UbuntuServer"
sku = "16.04-LTS"
version = "latest"
}
storage_os_disk {
name = "osdisk-terraform-azure"
caching = "ReadWrite"
create_option = "FromImage"
managed_disk_type = "Standard_LRS"
}
os_profile {
computer_name = "vm-terraform-azure"
admin_username = "azureuser"
}
os_profile_linux_config {
disable_password_authentication = true
ssh_keys {
path = "/home/azureuser/.ssh/authorized_keys"
key_data = file("~/.ssh/id_rsa.pub")
}
}
}
Cada bloque que genera lo hace de manera inteligente, asocia unos recursos con otros, por ejemplo, el grupo de recursos de cada recurso (valga la redundancia) que me está sugiriendo lo está asociando al grupo de recursos que se ha configurado, lo mismo ocurre con la localización, todos van asociado a localización definida en el grupo de recursos, West Europe.
Esta claro que no tiene porque ser 100% funcional el código que nos está generando porque tendremos que modificar los nombres y aplicar las configuraciones deseadas, pero, nos está ahorrando tener que redactar bastante código. Hasta ahora todo el código que nos ha sugerido Copilot no contiene variables.
¿Qué ocurre si defino el nombre de los recursos como variables?
Si configuro name y location del grupo de recursos como variables, el siguiente bloque que me sugiere para la red virtual name es una variable pero address_space no.
Entonces voy a tomar la sugerencia como buena, pero voy a editar address_space para indicarle que es una variable y voy a ver a continuación si en el bloque que me sugiere de subnet address_prefixes lo configura como variable:
Y así es, ¡qué maravilla!
Copilot aprende la forma en que vamos escribiendo el código.
Voy a trabajar ahora con el archivo variables.tf y ver si es capaz de declarar todas las variables que son necesarias. El siguiente código es mi fichero main.tf.
terraform {
required_version = ">= 0.12"
required_providers {
azurerm = {
source = "hashicorp/azurerm"
version = "=2.0.0"
}
}
backend "azurerm" {
resource_group_name = "rg-terraform-azure"
storage_account_name = "terraformazurestorage"
container_name = "tfstate"
key = "terraform.tfstate"
}
}
provider "azurerm" {
version = "=2.0.0"
features {}
}
resource "azurerm_resource_group" "rg" {
name = var.name_rg
location = var.location
}
resource "azurerm_virtual_network" "vnet" {
name = var.name_vnet
address_space = var.address_space_vnet
location = azurerm_resource_group.rg.location
resource_group_name = azurerm_resource_group.rg.name
}
resource "azurerm_subnet" "subnet" {
name = var.name_subnet
resource_group_name = azurerm_resource_group.rg.name
virtual_network_name = azurerm_virtual_network.vnet.name
address_prefixes = var.address_prefixes_subnet
}
resource "azurerm_network_security_group" "nsg" {
name = var.name_nsg
location = azurerm_resource_group.rg.location
resource_group_name = azurerm_resource_group.rg.name
}
resource "azurerm_network_security_rule" "nsg_rule" {
name = var.name_nsg_rule
priority = var.priority_nsg_rule
direction = var.direction_nsg_rule
access = var.access_nsg_rule
protocol = var.protocol_nsg_rule
source_port_range = var.source_port_range_nsg_rule
destination_port_range = var.destination_port_range_nsg_rule
source_address_prefix = var.source_address_prefix_nsg_rule
destination_address_prefix = var.destination_address_prefix_nsg_rule
resource_group_name = azurerm_resource_group.rg.name
network_security_group_name = azurerm_network_security_group.nsg.name
}
En el fichero variables.tf comienzo escribiendo variable y automáticamente me sugiere la primera variable necesaria que es para rg_name, a partir de aquí va surgiendo cada una de las variables necesarias de forma ordenada, tan solo hay que aplicar los nombres y espacios de direcciones necesarios.
Hasta aquí mis primeras pruebas con Copilot, la primera impresión ha sido ¡no quiero dejar de usarlo! ya sea para configurar mis módulos o configurar infraestructura en Azure. Es una herramienta que le da un vuelco a la productividad porque ahorras mucho tiempo ‘picando código’, pero siempre es necesario saber de la tecnología que vas a usar para adaptar el código a las necesidades del proyecto que vas a ejecutar y corregir posibles errores.