Nota:
- Este tutorial requiere acceso a Oracle Cloud. Para registrarse en una cuenta gratuita, consulte Introducción a la capa gratuita de Oracle Cloud Infrastructure.
- Utiliza valores de ejemplo para las credenciales, el arrendamiento y los compartimentos de Oracle Cloud Infrastructure. Al finalizar el laboratorio, sustituya estos valores por otros específicos de su entorno en la nube.
Conecte una IP reservada a una instancia de Oracle Cloud Infrastructure Compute mediante Terraform y un script cloud-init
Introducción
En el mundo de la infraestructura como código (IaC), la automatización del aprovisionamiento y la configuración de instancias informáticas es esencial para despliegues en la nube eficientes y ampliables. Cuando se trata de asociar direcciones IP reservadas a instancias informáticas de Oracle Cloud Infrastructure (OCI), Terraform y cloud-init proporcionan una potente combinación.
En el módulo Terraform de recursos informáticos de OCI, no hay ninguna opción para asociar una IP reservada a una instancia informática mientras se crea la instancia. Solo se puede asociar una IP reservada después de crear la instancia. En esta entrada del blog, descubriremos cómo aprovechar Terraform y el script cloud-init para asociar una IP reservada a una instancia de OCI Compute sin problemas.
Objetivo
Asocie una IP reservada a una instancia de OCI Compute sin problemas mediante el script cloud-init y Terraform.
¿Qué es una IP reservada?
Una dirección IP reservada es una IP estática asignada a una instancia informática dentro de una red virtual. Garantiza una conectividad consistente para las aplicaciones que requieren una IP fija y simplifica la administración de la red. Las IP reservadas se suelen utilizar en escenarios como el equilibrio de carga, las reglas de firewall y la comunicación de red segura.
Requisitos
En primer lugar, necesita acceder a un entorno de OCI. Si no tiene una, puede crear fácilmente su instancia Siempre gratis, que incluye mucha capacidad gratuita y 300 dólares en créditos de prueba.
Cuando tenga un entorno, asegúrese de que el usuario se haya asignado a un grupo con permisos para gestionar la familia de almacenamiento y los recursos instance-family. Una práctica recomendada de seguridad le permite crear un usuario, en lugar de utilizar un usuario de consola que ya tiene permisos asignados. Si necesita ayuda, consulte los documentos para crear un grupo y otorgar los permisos adecuados a los usuarios.
- Cuenta de OCI
- Acceso a Terraform. Consulte este enlace para obtener más información.
- Subred pública, donde se iniciará la instancia. Debe estar asociado a un gateway de Internet.
- Subred privada, donde se crea la VNIC secundaria y se asigna la IP reservada. Debe estar asociado a un gateway de servicio.
- Grupo dinámico en el que los recursos del grupo necesitan los permisos para gestionar la familia de redes.
- Las políticas se deben configurar para la autenticación de principal de instancia.
Tarea 1: Configuración de un script de Terraform
Aquí, agregaremos un script cloud-init como metadatos a un módulo de instancia informática de creación de Terraform de OCI. Además, transferiremos el OCID de IP reservada y el OCID de subred privada a la máquina virtual de Compute como etiquetas de formato libre.
resource "oci_core_public_ip" "pubip" {
# In case of Multiple Instances has to be created, Provide the count in the vars file.
# This block creates a Reserved Public IP from Oracle IP Pool
count = var.instance_count
compartment_id = var.compartment_id
display_name = var.res_ip_display_name
lifetime = "RESERVED"
private_ip_id = ""
}
resource "oci_core_instance" "pubiptest" {
count = var.instance_count
compartment_id = var.compartment_id
availability_domain = data.oci_identity_availability_domains.ads.availability_domains[0].name
display_name = var.display_name
shape = var.shape
# We will pass Reserved Public IP OCID and Private Subnet OCID as a freeform tags to the instance
freeform_tags = {
"publicIP" = resource.oci_core_public_ip.pubip[count.index].id
"SubnetId" = var.private_subnet_id
}
create_vnic_details {
display_name = var.vnic_display_name
assign_public_ip = true
subnet_id = var.public_subnet_id
}
source_details {
source_type = var.source_type
source_id = var.source_id
}
metadata = {
ssh_authorized_keys = var.pub_key
user_data = "${base64encode(file("./cloud-init.sh"))}"
}
}
El script anterior creará una IP reservada (teniendo en cuenta el valor de la variable de recuento) y activará una instancia informática con IP efímera, que se conecta a la VNIC principal.
En los metadatos de recursos informáticos, transferiremos el script cloud-init, que asignará la IP reservada mediante la sustitución de la IP efímera existente.
Tarea 2: Descripción del script cloud-init
Tarea 2.1: Instalación de la CLI de OCI y otras herramientas necesarias
Utilice el siguiente comando para instalar OCI CLI y jq (análisis de JSON).
`sudo yum install -y python36-oci-cli jq`
Tarea 2.2: Recuperación de metadatos de instancia
-
Utilice el servicio de metadatos de instancia, que proporciona información sobre una instancia en ejecución de Networking, Volumes, etc. Recupera OCID de instancia, ID de compartimento, subnetID (OCID de subred privada transferido como etiqueta de formato libre) y publicIP (IPOCID reservado transferido como etiqueta de formato libre) mediante el servicio de metadatos de instancia que también incluye valores de etiquetas de formato libre.
metadata=$(curl -H 'Authorization: Bearer Oracle' http://169.254.169.254/opc/v2/instance) instanceid=$(echo $metadata | jq -r '.id') compartmentid=$(echo $metadata | jq -r '.compartmentId') subnetid=$(echo $metadata | jq -r '.freeformTags.SubnetId') publicIp=$(echo $metadata | jq -r '.freeformTags.publicIP') -
Recupere el OCID de VNIC principal, el ID de IP privada (OCID de IP privada asignado a VNIC principal), la IP pública de corta duración y el OCID de IP pública de corta duración con
oci-cliprimaryvnicid=$(curl -H 'Authorization: Bearer Oracle' http://169.254.169.254/opc/v1/vnics/ | jq -r '.[].vnicId') privateIpId=$(oci network private-ip list --vnic-id $primaryvnicid --auth instance_principal | jq -r '.data[].id') ephpublicIp=$(oci network vnic get --vnic-id $primaryvnicid --auth instance_principal | jq -r '.data."public-ip"') ephpublicIpId=$( oci network public-ip get --auth instance_principal --public-ip-address $ephpublicIp | jq -r '.data.id')
Tarea 2.3: Asociación de VNIC secundario
Conecte la VNIC secundaria a la máquina virtual de Compute que utilizará la subred privada ejecutando el siguiente comando.
oci compute instance attach-vnic --instance-id $instanceid --subnet-id $subnetid --auth instance_principal --wait
Tarea 2.4: Configuración de rutas
-
Una vez que se haya creado y conectado la VNIC secundaria a la máquina virtual, configuraremos la VNIC secundaria y la agregaremos a las rutas. Para configurar las rutas, utilizaremos el script proporcionado por Oracle.
wget https://docs.oracle.com/en-us/iaas/Content/Resources/Assets/secondary_vnic_all_configure.sh sudo chmod u+x ./secondary_vnic_all_configure.sh sudo ./secondary_vnic_all_configure.sh -c -
Una vez que haya finalizado la configuración, verá la nueva ruta agregada a las rutas de VM. Puede comprobarlo con el comando
sudo route -n.
Tarea 2.5: Hacer la ruta de VNIC secundaria como ruta por defecto
-
Obtenga la IP de gateway para la VNIC secundaria mediante IDMS. Se agregará a la tabla de rutas de instancia.
gatewayIP=$(curl http://169.254.169.254/opc/v1/vnics/ | jq -c '.[] | ( select(.vnicId=="'$secondaryvnicid'" ))' | jq -r '.virtualRouterIp') -
Obtenga la interfaz de red predeterminada con el siguiente comando.
iname=$(sudo ./secondary_vnic_all_configure.sh | awk '{print $8}' | awk 'END{print}') -
Ejecute el siguiente comando para agregar la ruta por defecto para que sea VNIC secundaria.
sudo route add default gw $gatewayIP dev $iname -
Confirme de nuevo con el comando
sudo route -n.
Tarea 2.6: Suprimir IP pública efímera
-
Suprima la IP pública de corta duración que está conectada a la VM. Ya que hemos convertido la VNIC secundaria en la ruta por defecto y la subred que tiene VNIC secundaria existe, tiene un gateway de servicios asociado, para que pueda hablar con otros servicios de OCI (en este caso, la VCN).
delpubIp=$(oci network public-ip delete --force --auth instance_principal --public-ip-id $ephpublicIpId --wait-for-state TERMINATED) -
Utilice el siguiente comando para comprobar si la IP efímera se ha suprimido correctamente.
checkIp=$(oci network vnic get --vnic-id $primaryvnicid --auth instance_principal | jq -r '.data."public-ip"')
Tarea 2.7: Asociación de IP reservada
Tenemos el OCID de IP pública de las etiquetas de formato libre y hemos suprimido la IP esférica, por lo que podemos conectar la IP reservada al VNIC primario. El siguiente comando asocia la IP reservada al VNIC primario de la instancia.
assign=$(oci network public-ip update --force --auth instance_principal --public-ip-id $publicIp --private-ip-id $privateIpId --wait-for-state ASSIGNED)
Tarea 2.8: Desasociar VNIC secundario
-
Hemos asociado el valor Reserved Public a la VNIC principal y ahora podemos desasociar la VNIC secundaria. Utilice el siguiente comando para desasociar la VNIC secundaria y actualizar las reglas de ruta según corresponda.
detach=$(oci compute instance detach-vnic --compartment-id $compartmentid --vnic-id $secondaryvnicid --force --auth instance_principal) sudo ./secondary_vnic_all_configure.sh -d -
El siguiente script muestra todos los pasos juntos. Este script se ha reintentado hasta 3 veces en caso de fallo y podemos configurar la notificación en caso de fallo mediante el servicio OCI Events.
#!/bin/bash # coding: utf-8 sudo yum install -y python36-oci-cli function getdetails() { # Fetch data using instance principal authentication metadata=$(curl -H 'Authorization: Bearer Oracle' http://169.254.169.254/opc/v2/instance) instanceid=$(echo $metadata | jq -r '.id') compartmentid=$(echo $metadata | jq -r '.compartmentId') subnetid=$(echo $metadata | jq -r '.freeformTags.SubnetId') publicIp=$(echo $metadata | jq -r '.freeformTags.publicIP') primaryvnicid=$(curl -H 'Authorization: Bearer Oracle' http://169.254.169.254/opc/v1/vnics/ | jq -r '.[].vnicId') privateIpId=$(oci network private-ip list --vnic-id $primaryvnicid --auth instance_principal | jq -r '.data[].id') ephpublicIp=$(oci network vnic get --vnic-id $primaryvnicid --auth instance_principal | jq -r '.data."public-ip"') ephpublicIpId=$( oci network public-ip get --auth instance_principal --public-ip-address $ephpublicIp | jq -r '.data.id') if [[ -z "$subnetid" || "$subnetid" == "" || ${#subnetid} == 0 || -z "$publicIp" || ${#publicIp} == 0 || -z "$instanceid" || -z "$compartmentid" || -z "$publicIpData" || -z "$privateIpId" || -z "$primaryvnicid" || -z "$ephpublicIp" || -z "$ephpublicIpId" ]]; then echo "Missing some details, retrying..." return 1 fi return 0 } # Retry the `getdetails` function thrice attachVNIC() { attachvnic=$(oci compute instance attach-vnic --instance-id $instanceid --subnet-id $subnetid --auth instance_principal --wait) } for i in {1..3}; do getdetails if [[ $? -eq 0 ]]; then attachVNIC if [[ -n "$attachvnic" ]]; then secondaryvnicid=$(echo $attachvnic | jq -r '.data.id') echo $secondaryvnicid check2VNICs=$(oci compute instance list-vnics --instance-id $instanceid --auth instance_principal | jq -r '.data[].id') echo $check2VNICs gatewayIP=$(curl http://169.254.169.254/opc/v1/vnics/ | jq -c '.[] | ( select(.vnicId=="'$secondaryvnicid'" ))' | jq -r '.virtualRouterIp') if [[ (-n "$gatewayIP") ]]; then echo $gatewayIP wget https://docs.oracle.com/en-us/iaas/Content/Resources/Assets/secondary_vnic_all_configure.sh sudo chmod u+x ./secondary_vnic_all_configure.sh sudo ./secondary_vnic_all_configure.sh -c iname=$(sudo ./secondary_vnic_all_configure.sh | awk '{print $8}' | awk 'END{print}') echo $iname sudo route add default gw $gatewayIP dev $iname route oci os ns get --auth instance_principal delpubIp=$(oci network public-ip delete --force --auth instance_principal --public-ip-id $ephpublicIpId --wait-for-state TERMINATED) checkIp=$(oci network vnic get --vnic-id $primaryvnicid --auth instance_principal | jq -r '.data."public-ip"') if [[ -z "$checkIp" || "$checkIp" == "null" ]]; then echo "Assigning Reserved IP" assign=$(oci network public-ip update --force --auth instance_principal --public-ip-id $publicIp --private-ip-id $privateIpId --wait-for-state ASSIGNED) detach=$(oci compute instance detach-vnic --compartment-id $compartmentid --vnic-id $secondaryvnicid --force --auth instance_principal) sudo ./secondary_vnic_all_configure.sh -d checkIp2=$(oci network vnic get --vnic-id $primaryvnicid --auth instance_principal | jq -r '.data."public-ip"') echo "Reserved IP $checkIp2" if [[ -z "$checkIp2" ]]; then oci compute instance update --instance-id $instanceid --freeform-tags '{"errorStatus":"Reserved IP Not Assigned","SubnetId":"'$subnetid'","publicIP":"'$publicIp'"}' --force --auth instance_principal exit; fi else oci compute instance update --instance-id $instanceid --freeform-tags '{"errorStatus":"Ephemeral IP Not Deleted","SubnetId":"'$subnetid'","publicIP":"'$publicIp'"}' --force --auth instance_principal exit; fi break; else oci compute instance update --instance-id $instanceid --freeform-tags '{"errorStatus":"Gateway IP not fetched","SubnetId":"'$subnetid'","publicIP":"'$publicIp'"}' --force --auth instance_principal exit; fi else break; fi fi done if [[ -z "$attachvnic" ]]; then echo "Failed" oci compute instance update --instance-id $instanceid --freeform-tags '{"errorStatus":"Secondary VNIC not attached","SubnetId":"'$subnetid'","publicIP":"'$publicIp'"}' --force --auth instance_principal exit fi checkVNICs2=$(oci compute instance list-vnics --instance-id $instanceid --auth instance_principal | jq -r '.data | length') if [[ "$checkVNICs2" > 1 ]]; then echo "Detaching Secondary VNIC Failed" oci compute instance update --instance-id $instanceid --freeform-tags '{"errorStatus":"Detaching Secondary VNIC Failed","SubnetId":"'$subnetid'","publicIP":"'$publicIp'"}' --force --auth instance_principal exit fi oci compute instance update --instance-id $instanceid --freeform-tags '{"SubnetId":"'$subnetid'","publicIP":"'$publicIp'"}' --force --auth instance_principal
Pasos Siguientes
Esta es una implementación de ejemplo y realice los cambios correspondientes antes de usarla como un script cloud-init. Esto se ha probado con Oracle Linux 8.
Si selecciona cualquier otro tipo de Linux, el procedimiento de instalación oci-cli cambiará. Para obtener más información, consulte Instalación de la CLI.
Enlaces relacionados
Agradecimientos
Autor: Rithesh Subramanian (arquitecto de OCI Cloud)
Más recursos de aprendizaje
Explore otros laboratorios en docs.oracle.com/learn o acceda a más contenido de aprendizaje gratuito en el canal YouTube de Oracle Learning. Además, visite education.oracle.com/learning-explorer para convertirse en un explorador de Oracle Learning.
Para obtener documentación sobre los productos, visite Oracle Help Center.
Attach a Reserved IP to an Oracle Cloud Infrastructure Compute Instance using Terraform and cloud-init Script
F82850-01
June 2023
Copyright © 2023, Oracle and/or its affiliates.