Creación de varias instancias de recursos mediante el elemento copy
Hasta ahora ha declarado los recursos en una lista de recursos de una plantilla. Al implementar, se termina obteniendo una instancia de cada elemento especificado en la lista de recursos. Puede que quiera crear más de una instancia de un recurso específico. Por ejemplo, podría querer varias subredes en una red virtual.
Tenga en cuenta las siguientes preguntas y factores cuando esté pensando en crear muchas instancias e iterar entre las construcciones:
- ¿Necesito más de una copia?: en los escenarios más sencillos, probablemente no. En el caso de escenarios más avanzados, como las subredes o las máquinas virtuales, es posible que tenga que plantearse si necesita más de una copia de algo.
- ¿Dependo de un recurso?: Azure Resource Manager suele ser adecuado para averiguar qué se debe construir y en qué orden, de modo que las referencias dentro de la plantilla de Azure Resource Manager (ARM) funcionen. Hay situaciones en las que puede que tenga que especificar el orden.
- Defina un esquema de nomenclatura: Quiere asignar nombres descriptivos a los recursos. por ello, se basa en parámetros que se pasan en el momento de la implementación. Si tiene varias copias, tal vez quiera tener un control más granular y basar la nomenclatura en la iteración de la secuencia de copia en la que se encuentra actualmente.
- Configure y controle la creación de recursos: Puede que quiera limitar el número de recursos que se crean en un entorno de producción. Es posible hacerlo configurando la creación de recursos como serie o paralelo.
- Copie otros tipos: Los recursos no son lo único de lo que se pueden crear múltiples copias e iterarse. De hecho, puede hacer lo mismo con propiedades, variables y salidas.
- Primario-secundario: puede que tenga que configurar relaciones de primario a secundario en los recursos.
Creación de varias instancias
Puede usar construcciones en bucle para guardar las pulsaciones de teclas. Si lo que necesita se repite una y otra vez, es bastante parecido en nombre y tipo y solo hay ligeras diferencias, probablemente pueda beneficiarse de usar el elemento copy.
El elemento copy es un componente de JSON que se puede usar en muchos tipos de construcciones como recursos, propiedades, variables y salidas. La sintaxis del elemento copy consta de la clave copy e incluye una matriz como valor. Por ejemplo: "copy": []
.
La matriz toma un número de elementos y cada elemento es un objeto {}
que consta de un conjunto de propiedades. Cuáles son estas propiedades dependerá del tipo de construcción en la que se usen. Normalmente, todas las construcciones del elemento copy
tienen una propiedad en común: count
. Esta propiedad determina el número de instancias que se quiere de un determinado tipo de construcción. La mayoría de las construcciones también permiten una propiedad name
que le proporciona una referencia a la que puede remitirse en otros elementos del código. Otras propiedades utilizadas son específicas de la construcción.
Qué elegir
Podría preguntar: "Si puedo usar el elemento copy
en muchos tipos de construcciones, ¿cuáles debo elegir y cuándo, y se puede usar más de un tipo en una plantilla?".
Todo depende del caso de uso. Una iteración de recursos permite crear muchas copias de un recurso y su uso tiene sentido si, por ejemplo, necesita varias cuentas de almacenamiento. Por otro lado, una iteración de propiedades permite crear muchas propiedades dentro de un recurso. Se trata de ahorrar pulsaciones de teclas y tiempo, y usted sabe mejor que nadie dónde hay elementos repetidos en la plantilla.
El elemento copy
se puede usar en muchos lugares de la plantilla. Puede usar un elemento copy
para crear muchos recursos, pero también para crear muchas variables similares dentro de la misma plantilla.
Funcionamiento
El elemento copy
funciona con la instrucción copy
que se evalúa y reemplaza. El reemplazo es el resultado de lo que se define en la instrucción copy
, que se repite tantas veces como se indica en el campo copy
.
En el siguiente ejemplo se muestra el aspecto de una definición en la que se usa copy
:
"copy": [
{
"name": "dataDisks",
"count": 2,
"input": {
"diskSizeGB": 1023,
"lun": "[copyIndex('dataDisks')]",
"createOption": "Empty"
}
}
]
Fíjese en la entrada count: 2
. El valor 2
indica que quiere que la expresión anterior se expanda a dos entradas. El resultado es el siguiente:
"dataDisks": [
{
"lun": 0,
"createOption": "Empty",
"diskSizeGB": 1023
},
{
"lun": 1,
"createOption": "Empty",
"diskSizeGB": 1023
}
Puede verse que el valor de la propiedad name
se ha convertido en el nombre de la propiedad y el contenido de la propiedad input
se ha convertido en el elemento del JSON que se repite.
Nota:
La expresión de copy y su salida difieren en función del tipo de expresión que se utiliza. El ejemplo anterior da una buena idea de lo que sucede cuando una expresión se transforma en una serie de instrucciones repetidas.
Hay límites en cuanto a la cantidad que se puede copiar. Actualmente, el límite es de 800 entradas.
Importante
Para obtener más información sobre las limitaciones exactas, vea Iteración de recursos en las plantillas de ARM.
Control de la iteración
Hay funciones auxiliares que le ayudan a hacer referencia a índices específicos de la matriz. La función copyIndex()
devuelve el índice actual. Por ejemplo, respecto a la tercera entrada repetida, copyIndex()
devuelve el valor 2
. La sintaxis de copyIndex()
es similar a lo siguiente:
copyIndex(loopName, offset)
La función copyIndex()
tiene dos parámetros de entrada distintos, loopName
y offset
. El parámetro offset
es siempre opcional y se usa para desplazarlo del índice actual. Lo que se agregue como valor de offset
se agrega al índice actual. Si el índice actual devuelve 2
y se especifica 1
como desplazamiento, la función copyIndex()
devuelve 3
.
El parámetro loopName
es opcional o obligatorio, según dónde se use. Es obligatorio si se usa dentro de una construcción properties
, y opcional si se usa en una matriz resources
. Este es un ejemplo en el que es obligatorio:
"properties": {
"storageProfile": {
"copy": [
{
"name": "dataDisks",
"count": "[parameters('numberOfDataDisks')]",
"input": {
"diskSizeGB": 1023,
"lun": "[copyIndex('dataDisks')]",
"createOption": "Empty"
}
}
]
}
}
Observe cómo el elemento copy
se usa dentro de una construcción properties
, y copyIndex()
tiene loopName
especificado como copyIndex('dataDisks')
.
Veamos ahora este otro ejemplo en el que loopName
no es obligatorio:
{
"type": "Microsoft.Network/virtualNetworks",
"apiVersion": "2018-04-01",
"name": "[concat(parameters('vnetname'), copyIndex())]",
}
Muestra un recurso que se declara y se llama a copyIndex()
sin parámetros, ya que se usa en el contexto de un recurso.
Configurar la implementación
Cuando se usa el elemento copy
para los recursos, se termina creando numerosos recursos similares.
En ocasiones, es posible que desee controlar cómo se crean los recursos y en qué orden. Los motivos para controlar el orden pueden ser estos:
- Limitaciones del entorno. En función del entorno en el que se implemente, es posible que quiera limitar el grado en que el entorno se ve afectado por una implementación. En un entorno de producción, tiene sentido limitar el número de recursos que se ven afectados en un momento dado. Puede configurar un modo de implementación para controlar el número de recursos que se implementan simultáneamente.
- Dependencias. Podría depender de algo que ya exista antes de aventurarse a crear el recurso que necesita. Para expresar este tipo de dependencia, hay una construcción denominada
dependsOn
.
Modos de implementación y copy
Puede que quiera asegurarse de que un conjunto de recursos creados por la construcción copy
se cree antes de nada. En ese caso, debe expresar esta situación. Recuerde que lo que interviene aquí es el modo de implementación que Resource Manager usa. Se admiten dos modos:
- Serie. La configuración de un recurso en este modo de implementación significa que se creará uno tras otro. En este modo también se espera que se establezca la propiedad
batchSize
para determinar cuántos recursos se implementan con este modo. No se puede iniciar un nuevo lote antes de que se haya completado uno anterior. Puede que quiera limitar las cosas de este modo en un entorno de producción, por ejemplo, donde podría ser importante limitar el número de recursos afectados en un momento dado. - Paralelo. Se trata del modo de implementación predeterminado. La ventaja es un rendimiento elevado, por lo que la plantilla se procesa más rápidamente. Los inconvenientes son que no se puede garantizar el orden y podría no ser lo que se quiere para el entorno de producción.
Dependencias
En el contexto del elemento copy
, debe indicar al recurso con la dependencia qué sección está esperando. Esta dependencia se logra haciendo referencia a ella por su nombre con el siguiente JSON:
"resources": [
{
"type": "Microsoft.Storage/storageAccounts",
"apiVersion": "2019-04-01",
"name": "[concat(copyIndex(),'storage', uniqueString(resourceGroup().id))]",
"location": "[resourceGroup().location]",
"sku": {
"name": "Standard_LRS"
},
"kind": "Storage",
"copy": {
"name": "storagecopy",
"count": 3
},
"properties": {}
},
{
"type": "Microsoft.Compute/virtualMachines",
"apiVersion": "2015-06-15",
"name": "[concat('VM', uniqueString(resourceGroup().id))]",
"dependsOn": ["storagecopy"],
}
]
Fíjese en que el elemento copy
tiene una propiedad name
con el valor storagecopy
. El recurso dependiente, una cuenta de almacenamiento, está esperando a que la operación del elemento copy
finalice. Esto se expresa por medio de "dependsOn": ["storagecopy"]
.
Por lo tanto, la plantilla de ARM cambia a un modo de implementación serie entre estos dos recursos. Esto podría afectar a la velocidad de rendimiento de la implementación, pero usted ha expresado que le interesa un determinado orden de implementación, que ahora tiene prioridad.