AWS – Importar Máquina Virtual

En el marketplace de Amazon AWS podemos elegir entre multitud de imágenes de máquinas virtuales que podemos utilizar como plantilla para crear nuestras máquinas virtuales. Sin embargo, en el ámbito empresarial, es muy común que cada cliente quiera incorporar en AWS sus propios Virtual Appliances (o plantillas de máquinas virtuales) por muchos motivos:

  • Quieren migrar a AWS servidores que ya tienen en otras plataformas de cloud o en sus propios centros de datos.
  • Ya tienen un estándar de maquina virtual con todo lo que necesitan.
  • El departamento de seguridad no se fía de los agentes que preinstala Amazon en sus imágenes de máquinas virtuales.
  • Tienen creadas diferentes plantillas para diferentes tipos de aplicaciones (bases de datos Oracle, Tomcat, Apache, etc.).
  • Y cientos de motivos más que pueden tener.

El caso, es que Amazon AWS permite importar tus propias máquinas virtuales.

Echa un vistazo al artículo Exportar una Máquina Virtual – OVA si no sabes como exportar tu máquina virtual.

Subir la plantilla del servidor virtual a un Bucket S3

Una vez que ya hemos exportado nuestra maquina virtual, la subiremos a un bucket S3, que utilizaremos como servicio de almacenamiento para poder importarla como AMI (Imagen de maquina virtual) en AWS.

Para este ejemplo, he creado el bucket «david-appliance» y la plantilla del servidor virtual se llama RHEL8.ova.

Imagen de maquina virtual (OVA) subida a un bucket S3

Creación del servicio del Rol de importación en Amazon AWS

Según podemos ver en la documentación oficial de Amazon sobre los requerimientos previos para importar nuestra propia plantilla de maquina virtual, tenemos que crear el servicio de rol de importación de máquinas virtuales.

Lo haremos de la siguiente manera:

[[email protected] ~]# cat trust-policy.json
{
   "Version": "2012-10-17",
   "Statement": [
      {
         "Effect": "Allow",
         "Principal": { "Service": "vmie.amazonaws.com" },
         "Action": "sts:AssumeRole",
         "Condition": {
            "StringEquals":{
               "sts:Externalid": "vmimport"
            }
         }
      }
   ]
}
[[email protected] ~]#


[[email protected] ~]# aws iam create-role --role-name vmimport --assume-role-policy-document "file://trust-policy.json"
{
    "Role": {
        "AssumeRolePolicyDocument": {
            "Version": "2012-10-17",
            "Statement": [
                {
                    "Action": "sts:AssumeRole",
                    "Effect": "Allow",
                    "Condition": {
                        "StringEquals": {
                            "sts:Externalid": "vmimport"
                        }
                    },
                    "Principal": {
                        "Service": "vmie.amazonaws.com"
                    }
                }
            ]
        },
        "RoleId": "AROAZLWVJ72OFPIJVBEFC",
        "CreateDate": "2022-08-09T04:02:19Z",
        "RoleName": "vmimport",
        "Path": "/",
        "Arn": "arn:aws:iam::643618700956:role/vmimport"
    }
}
[[email protected] ~]#

A continuación, crearemos la política del rol para que pueda actuar sobre el bucket S3 donde hemos subido la plantilla del servidor virtual:

[[email protected] ~]# cat role-policy.json
{
   "Version":"2012-10-17",
   "Statement":[
      {
         "Effect": "Allow",
         "Action": [
            "s3:GetBucketLocation",
            "s3:GetObject",
            "s3:ListBucket"
         ],
         "Resource": [
            "arn:aws:s3:::david-appliance",
            "arn:aws:s3:::david-appliance/*"
         ]
      },
      {
         "Effect": "Allow",
         "Action": [
            "s3:GetBucketLocation",
            "s3:GetObject",
            "s3:ListBucket",
            "s3:PutObject",
            "s3:GetBucketAcl"
         ],
         "Resource": [
            "arn:aws:s3:::david-appliance",
            "arn:aws:s3:::david-appliance/*"
         ]
      },
      {
         "Effect": "Allow",
         "Action": [
            "ec2:ModifySnapshotAttribute",
            "ec2:CopySnapshot",
            "ec2:RegisterImage",
            "ec2:Describe*"
         ],
         "Resource": "*"
      }
   ]
}
[[email protected] ~]#

[[email protected] ~]# aws iam put-role-policy --role-name vmimport --policy-name vmimport --policy-document "file://role-policy.json"
[[email protected] ~]#

Importar la imagen de la maquina virtual en Amazon AWS

Una vez que ya están configurados todos los permisos previos, ya podemos importar la maquina virtual:

[[email protected] ~]# aws ec2 import-image --description "RHEL8 Appliance" --disk-containers Format=ova,UserBucket="{S3Bucket=david-appliance,S3Key=RHEL8.ova}" --architecture x86_64 --region eu-west-1
{
    "Status": "active",
    "Description": "RHEL8 Appliance",
    "Architecture": "x86_64",
    "SnapshotDetails": [
        {
            "UserBucket": {
                "S3Bucket": "david-appliance",
                "S3Key": "RHEL8.ova"
            },
            "DiskImageSize": 0.0,
            "Format": "OVA"
        }
    ],
    "Progress": "1",
    "StatusMessage": "pending",
    "ImportTaskId": "import-ami-0421422abf050e3b2"
}
[[email protected] ~]#

Si queremos revisar el progreso de la tarea, ejecutaremos el siguiente comando:

[[email protected] ~]# aws ec2 describe-import-image-tasks --region eu-west-1
{
    "ImportImageTasks": [
        {
            "Status": "deleted",
            "Description": "RHEL8 Appliance",
            "Tags": [],
            "Architecture": "x86_64",
            "SnapshotDetails": [
                {
                    "Status": "completed",
                    "DeviceName": "/dev/sde",
                    "DiskImageSize": 5541381120.0,
                    "UserBucket": {
                        "S3Bucket": "david-appliance",
                        "S3Key": "RHEL8.ova"
                    },
                    "Format": "VMDK"
                }
            ],
            "StatusMessage": "ClientError: DHCP client not installed.",
            "ImportTaskId": "import-ami-0533822beeade55d3"
        },
        {
            "Status": "active",
            "Description": "RHEL8 Appliance",
            "Tags": [],
            "Architecture": "x86_64",
            "SnapshotDetails": [
                {
                    "Status": "active",
                    "UserBucket": {
                        "S3Bucket": "david-appliance",
                        "S3Key": "RHEL8.ova"
                    },
                    "DiskImageSize": 5541381120.0,
                    "Format": "VMDK"
                }
            ],
            "Progress": "19",
            "StatusMessage": "converting",
            "ImportTaskId": "import-ami-0421422abf050e3b2"
        }
    ]
}
[[email protected] ~]#

Si tenemos varias tareas de importación concurrentes, también podemos consultar el estado de una de ellas a través de su identificador:

[[email protected] ~]# aws ec2 describe-import-image-tasks --import-task-ids import-ami-0421422abf050e3b2  --region eu-west-1
{
    "ImportImageTasks": [
        {
            "Status": "active",
            "Description": "RHEL8 Appliance",
            "Tags": [],
            "Architecture": "x86_64",
            "SnapshotDetails": [
                {
                    "Status": "active",
                    "UserBucket": {
                        "S3Bucket": "david-appliance",
                        "S3Key": "RHEL8.ova"
                    },
                    "DiskImageSize": 5541381120.0,
                    "Format": "VMDK"
                }
            ],
            "Progress": "19",
            "StatusMessage": "converting",
            "ImportTaskId": "import-ami-0421422abf050e3b2"
        }
    ]
}
[[email protected] ~]#

Los estados de las tareas son:

  • Active: La tarea de importación está en curso.
  • Deleting: La tarea de importación está siendo cancelada.
  • Deleted: La tarea de importación ha sido cancelada.
  • Updating: La tarea de importación se está actualizando.
  • Validating: La imagen de la máquina virtual se está validando.
  • Validated: La imagen de la máquina virtual se ha validado.
  • Converting: La imagen de la máquina virtual se está convirtiendo a formato AMI (máquina virtual de Amazon AWS).
  • Completed: La imagen de la máquina virtual ya se puede utilizar.
  Cambiar el tipo de instancia de Amazon AWS de T2 a T3.medium

Una vez finalizado, veremos una nueva AMI en nuestro repositorio de imágenes de maquinas virtuales y la podremos utilizar para crear un servidor nuevo a partir de esta imagen.

Error ClientError: DHCP client not installed

Si nos fijamos en el estado de la tarea anterior, podemos ver como ha finalizado incorrectamente, dando el error «ClientError: DHCP client not installed»:

"StatusMessage": "ClientError: DHCP client not installed.",

Uno de los requerimientos de importación de maquinas virtuales de Amazon AWS, es que puedan establecer comunicación con el servidor de DHCP. Para ello, en la maquina que exportamos tendremos que habilitar el servicio DHCP (cliente).

Servicio DHCP habilitado antes de exportar servidor virtual a Amazon AWS

En Linux RedHat 8 o en Centos 8, como es el ejemplo que estay utilizando para hacer esta guía, simplemente, instalaremos el paquete dhclient.

dnf install -y dhclient

Por otra parte, en la configuración de la maquina virtual, asignaremos una tarjeta de red que permita conectividad por DHCP. En el caso de VirtualBox, lo haremos de la siguiente manera:

  • Vamos al menú File –> Preferences –> Network y creamos una tarjeta de red NAT con DHCP Habilitado
Habilitar tarjeta de red en VirtualBox con soporte para DHCP
  • Asignaremos esta tarjeta de red a la maquina virtual que queramos exportar:
Oracle VirtualBox - Asignar tarjeta de red a servidor virtual
Asignamos la tarjeta de red «NatNetwork» que habíamos creado anteriormente con el cliente DHCP habilitado
  • Por último, cuando exportemos la maquina virtual, lo haremos con todas las tarjetas de red.
VIrtual Box - Exportar servidor virtual con todas las tarjetas de red

A continuación, volvemos a repetir los pasos de importación de la maquina virtual con el nuevo fichero OVA generado y subido a un contenedor de S3:

  • Importamos la imagen:
[[email protected] ~]# aws ec2 import-image --description "Centos8 Appliance" --disk-containers Format=ova,UserBucket="{S3Bucket=david-appliance,S3Key=Centos8.ova}" --architecture x86_64 --region eu-west-1
{
    "Status": "active",
    "Description": "Centos8 Appliance",
    "Architecture": "x86_64",
    "SnapshotDetails": [
        {
            "UserBucket": {
                "S3Bucket": "david-appliance",
                "S3Key": "Centos8.ova"
            },
            "DiskImageSize": 0.0,
            "Format": "OVA"
        }
    ],
    "Progress": "1",
    "StatusMessage": "pending",
    "ImportTaskId": "import-ami-06fa105bcc3f94f75"
}
[[email protected] ~]#
  • Revisamos el progreso de la tarea. Ahora está convirtiendo el fichero a una AMI o imagen de maquina virtual de Amazon AWS (converting):
[[email protected] ~]# aws ec2 describe-import-image-tasks --region eu-west-1 --import-task-ids import-ami-06fa105bcc3f94f75
{
    "ImportImageTasks": [
        {
            "Status": "active",
            "Description": "Centos8 Appliance",
            "Tags": [],
            "Architecture": "x86_64",
            "SnapshotDetails": [
                {
                    "Status": "active",
                    "UserBucket": {
                        "S3Bucket": "david-appliance",
                        "S3Key": "Centos8.ova"
                    },
                    "DiskImageSize": 1153167872.0,
                    "Format": "VMDK"
                }
            ],
            "Progress": "19",
            "StatusMessage": "converting",
            "ImportTaskId": "import-ami-06fa105bcc3f94f75"
        }
    ]
}
[[email protected] ~]#
  • El proceso de importación sigue su curso (updating):
[[email protected] ~]# aws ec2 describe-import-image-tasks --region eu-west-1 --import-task-ids import-ami-06fa105bcc3f94f75
{
    "ImportImageTasks": [
        {
            "Status": "active",
            "Description": "Centos8 Appliance",
            "Tags": [],
            "Architecture": "x86_64",
            "SnapshotDetails": [
                {
                    "Status": "completed",
                    "DeviceName": "/dev/sde",
                    "DiskImageSize": 1153167872.0,
                    "UserBucket": {
                        "S3Bucket": "david-appliance",
                        "S3Key": "Centos8.ova"
                    },
                    "Format": "VMDK"
                }
            ],
            "Progress": "27",
            "StatusMessage": "updating",
            "ImportTaskId": "import-ami-06fa105bcc3f94f75"
        }
    ]
}
[[email protected] ~]#
  • Todavía no ha terminado (booting):
[[email protected] ~]# aws ec2 describe-import-image-tasks --region eu-west-1 --import-task-ids import-ami-06fa105bcc3f94f75
{
    "ImportImageTasks": [
        {
            "Status": "active",
            "LicenseType": "BYOL",
            "Description": "Centos8 Appliance",
            "Tags": [],
            "Platform": "Linux",
            "Architecture": "x86_64",
            "SnapshotDetails": [
                {
                    "Status": "completed",
                    "DeviceName": "/dev/sda1",
                    "DiskImageSize": 1153167872.0,
                    "UserBucket": {
                        "S3Bucket": "david-appliance",
                        "S3Key": "Centos8.ova"
                    },
                    "Format": "VMDK"
                }
            ],
            "Progress": "39",
            "StatusMessage": "booting",
            "ImportTaskId": "import-ami-06fa105bcc3f94f75"
        }
    ]
}
[[email protected] ~]#
  • Preparando la AMI para que la podamos utilizar y desplegar servidores en EC2 con nuestra imagen personalizada:
[[email protected] ~]# aws ec2 describe-import-image-tasks --region eu-west-1 --import-task-ids import-ami-06fa105bcc3f94f75
{
    "ImportImageTasks": [
        {
            "Status": "active",
            "LicenseType": "BYOL",
            "Description": "Centos8 Appliance",
            "Tags": [],
            "Platform": "Linux",
            "Architecture": "x86_64",
            "SnapshotDetails": [
                {
                    "Status": "completed",
                    "DeviceName": "/dev/sda1",
                    "DiskImageSize": 1153167872.0,
                    "UserBucket": {
                        "S3Bucket": "david-appliance",
                        "S3Key": "Centos8.ova"
                    },
                    "Format": "VMDK"
                }
            ],
            "Progress": "51",
            "StatusMessage": "preparing ami",
            "ImportTaskId": "import-ami-06fa105bcc3f94f75"
        }
    ]
}
[[email protected] ~]#
  • Esperamos unos minutos más y vemos que el proceso ha finalizado:
[[email protected] ~]# aws ec2 describe-import-image-tasks --region eu-west-1 --import-task-ids import-ami-06fa105bcc3f94f75
{
    "ImportImageTasks": [
        {
            "Status": "completed",
            "LicenseType": "BYOL",
            "Description": "Centos8 Appliance",
            "Tags": [],
            "ImageId": "ami-024e3f583774671fb",
            "Platform": "Linux",
            "Architecture": "x86_64",
            "SnapshotDetails": [
                {
                    "Status": "completed",
                    "DeviceName": "/dev/sda1",
                    "Format": "VMDK",
                    "DiskImageSize": 1153167872.0,
                    "SnapshotId": "snap-05dba6c779979ca5c",
                    "UserBucket": {
                        "S3Bucket": "david-appliance",
                        "S3Key": "Centos8.ova"
                    }
                }
            ],
            "ImportTaskId": "import-ami-06fa105bcc3f94f75"
        }
    ]
}
[[email protected] ~]#

Si ahora vamos al menú AMI de EC2, encontraremos esta imagen en nuestro repositorio privado con ID 06fa105bcc3f94f75:

Amazon AWS - AMI personalizada (On Premise)

Incorporando nuestra propia licencia a la imagen AMI

Si no especificamos lo contrario durante el proceso de importación, la licencia por defecto de la imagen AMI, será de tipo “aws”. Para especificar nuestra propia licencia, añadiremos el parámetro –license-type byol al comando de importación. Tomando como ejemplo el comando anterior, sería:

aws ec2 import-image --description "Centos8 Appliance" --disk-containers Format=ova,UserBucket="{S3Bucket=david-appliance,S3Key=Centos8.ova}" --architecture x86_64 --region eu-west-1 --license-type byol

Asignar un nombre a una AMI

Con el comando import anterior no hemos asignado ningún nombre a la AMI. Añadirle un nombre nos puede ser muy útil para nuestro control de versiones o identificar la imagen fácilmente. Lo haremos de la siguiente manera:

[[email protected] ~]# aws ec2 create-tags --resources ami-0460231bd3319ac66 --tags 'Key=Name,Value=Centos8-20220821'
[[email protected] ~]# aws ec2 describe-tags --filters 'Name=resource-id,Values=ami-0460231bd3319ac66'
{
    "Tags": [
        {
            "ResourceType": "image",
            "ResourceId": "ami-0460231bd3319ac66",
            "Value": "Centos8-20220821",
            "Key": "Name"
        }
    ]
}
[[email protected] ~]#

Desde la consola de AWS, también veremos el nombre asignado a la AMI:

Asignar un nombre a una AMI de Amazon AWS

Te puede interesar

Compárteme

Contenido Relacionado

Deja un comentario