Public Cloud OVHcloud - Terraform et montage de volumes additionnels
BMPCreated with Sketch.BMPZIPCreated with Sketch.ZIPXLSCreated with Sketch.XLSTXTCreated with Sketch.TXTPPTCreated with Sketch.PPTPNGCreated with Sketch.PNGPDFCreated with Sketch.PDFJPGCreated with Sketch.JPGGIFCreated with Sketch.GIFDOCCreated with Sketch.DOC Error Created with Sketch.
Frage

Terraform et montage de volumes additionnels

Von
cf027b8c0843bc2bb9a3
Erstellungsdatum 2021-10-04 09:13:24 (edited on 2024-09-04 11:26:57) in Public Cloud OVHcloud

Bonjour,

En m'inspirant des informations trouvées sur le guide d'OVH How to use Terraform, je tente de déployer une infrastructure via Terraform. Je bute sur la configuration des volumes additionnels.

Mon code est le suivant :
```hcl
resource "openstack_compute_instance_v2" "factory_vm" {
name = "factory.example.com"
provider = openstack.ovh
image_name = "Debian 10"
flavor_name = "s1-2"
key_pair = openstack_compute_keypair_v2.my_keypair.name
network {
name = "Ext-Net"
}
}

resource "openstack_blockstorage_volume_v2" "factory_data_volume" {
name = "factory_data_volume"
size = 10
provider = openstack.ovh
}

resource "openstack_compute_volume_attach_v2" "factory_volume_attached" {
instance_id = openstack_compute_instance_v2.factory_vm.id
volume_id = openstack_blockstorage_volume_v2.factory_data_volume.id
}
```

La commande `terraform apply` instancie bien la VM et le volume. Lorsque je me connecte sur la VM, ce volume apparait sous le nom `/dev/sdb` :

```bash
root@factory:~# lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sda 8:0 0 10G 0 disk
└─sda1 8:1 0 10G 0 part /
sdb 8:16 0 10G 0 disk
```

Mais je ne vois pas comment faire en sorte que :
* une table de partitions soit créée, avec une partition `/dev/sdb1` ;
* cette partition `/dev/sdb1` soit formatée en ext4 ;
* cette partition soit montée sur `/data`.

Une bonne âme pourrait-elle éclairer ma lanterne ?

Je la remercie par avance,

Sébastien


1 Antwort ( Latest reply on 2021-10-18 22:55:07 Von
cf027b8c0843bc2bb9a3
)

Hello Sébastien, je tombe par hasard sur ton sujet... du coup je réponds :)
il faut que tu crées un fichier cloud-init avec à l'intérieur de celui-ci les options de formatage et montage de ce disque qui s'appellera toujours sdb (ce nom varie en fonction des clouds et des hyperviseurs).
Ce fichier cloud-init est à renseigner dans ton bloc de ressource vm de Terraform (l'option 'user_data' de tête à confirmer dans la doc.)

Je te donne un exemple:

#cloud-config
disk_setup:
/dev/sdb:
table_type: 'gpt'
layout: True
overwrite: False
fs_setup:
- label: DATA_XFS
filesystem: 'xfs'
device: '/dev/sdb'
partition: 'auto'
mounts:
- [ LABEL=DATA_XFS, /mnt/data, xfs ]

Bonjour Matthieu,

Je te remercie pour ta réponse, même tardive, elle sera sans aucun doute utile à d'autres.

J'étais arrivé entre temps à la même conclusion (cloud-init) et j'aurais dû la publier ici même, mais je ne suis pas satisfait du script que j'ai écrit, très proche du tien :

```yaml
disk_setup:
/dev/sdb:
table_type: gpt
layout: True
overwrite: False

fs_setup:
- label: data
device: /dev/sdb
partition: 1
filesystem: ext4

mounts:
- [ /dev/sdb1, /data, "auto", "defaults,relatime", "0", "0" ]
```

Je ne suis pas satisfait de cette solution, car je crains qu'elle ne soit pas déterministe si je crée plusieurs volumes. En effet, je n'ai trouvé aucune information dans la documentation de Terraform me garantissant que l'ordre de déclaration des volumes dans le script Terraform détermine le nom de périphérique auquel ils seront associés. J'imagine que les requêtes à OpenStack sont asynchrones et qu'il se peut que le second volume soit créé avant premier et soit associé au nom `/dev/sdb`, alors que je m'attends à ce qu'il soit associé au nom `/dev/sdc`.

Mais tu me diras que si j'ai un tel besoin, je n'ai qu'à créer un volume plus gros et y créer plusieurs partitions. Je serai alors en mesure de savoir laquelle je monte où.

Quoi qu'il en soit, je te remercie encore une fois. Ta réponse confirme que la solution que j'avais trouvée dans mon coin n'est pas trop excentrique. :)

Sébastien

Hello, oui je suis d'accord avec toi. L'attribution du a, b, c, ... x est chronologique et arrive au moment où Terraform attache le disque virtuel au système. C'est pas très précis. Par contre, rien n'empêche d'exécuter les actions de formatage via un script lancé depuis cloud-init en filtrant sur les bonnes valeurs. Ainsi, on sera certain d'avoir en face les bons volumes associés aux disques.

Autre solution peut-être plus cadrée, voir la doc du 'block_device' et en particulier l'utilisation de l'option 'guest_format', qui te propose un formatage en ext2, ext3, ext4, xfs et swap:
https://registry.terraform.io/providers/terraform-provider-openstack/openstack/latest/docs/resources/compute_instance_v2#block_device

Salut a tous

Je ne maîtrise clairement pas terraform, je précise...
Cependant, est-ce qu'il ne serait pas plus "sage" de travailler avec l'UUID du disque plutôt que son point de montage ??

Avec ce dernier, vous serez certain de choper le bon disque, peut importe qu'il soit en sdb ou sdx !

Jalinn

Bonjour Jalinn,


est-ce qu'il ne serait pas plus "sage" de travailler avec l'UUID du disque plutôt que son point de montage ??


Il serait en effet plus sage de procéder ainsi et je voudrais bien le faire. Malheureusement, je ne dispose pas de cette information suffisamment en amont pour pouvoir l'injecter dans le script cloud-init. En effet, pour créer la VM et le volume, je dois utiliser trois commandes :
* la première instancie la VM ;
* la seconde instancie le volume ;
* la troisième lie le volume à l'instance.

Terraform ne dispose du nom du périphérique qu'à l'issue de la troisième commande alors que le script cloud-init est fourni en attribut de la première. Assez logiquement, si on fait référence à un attribut disponible en sortie de la troisième commande au sein de la première, Terraform se formalise et hurle au serpent qui se mord la queue. :(

Sébastien


Autre solution peut-être plus cadrée, voir la doc du 'block_device'


Je vais explorer cette piste et si elle donne des résultats intéressants, je posterai la solution ici même.

Merci, Sébastien


Autre solution peut-être plus cadrée, voir la doc du 'block_device'


Finalement, cette approche ne résout rien et s'avère même moins intéressante que la précédente.

Merci tout de même pour la piste,

Sébastien


Mais tu me diras que si j'ai un tel besoin, je n'ai qu'à créer un volume plus gros et y créer plusieurs partitions. Je serai alors en mesure de savoir laquelle je monte où.


Au final, c'est cette approche que j'ai adoptée :

```yaml
disk_setup:
/dev/sdb:
table_type: gpt
layout:
- 30
- 70
overwrite: false

fs_setup:
- label: var_opt_gitlab
device: /dev/sdb
partition: 1
filesystem: ext4
- label: var_lib_docker
device: /dev/sdb
partition: 2
filesystem: ext4

mounts:
- [ /dev/sdb1, /var/opt/gitlab, "auto", "defaults,relatime", "0", "0" ]
- [ /dev/sdb2, /var/lib/docker, "auto", "defaults,relatime", "0", "0" ]
```

Avec un volume de 100 Go, cela donne :

```bash
$ lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sda 8:0 0 10G 0 disk
├─sda1 8:1 0 9.9G 0 part /
├─sda14 8:14 0 3M 0 part
└─sda15 8:15 0 124M 0 part /boot/efi
sdb 8:16 0 100G 0 disk
├─sdb1 8:17 0 30G 0 part /var/opt/gitlab
└─sdb2 8:18 0 70G 0 part /var/lib/docker
```

Pas très extensible tout ça, mais ce n'est pas grave, c'est une infra jetable...

Sébastien