{"action":"created","issue":{"url":"https://api.github.com/repos/dmacvicar/terraform-provider-libvirt/issues/46","repository_url":"https://api.github.com/repos/dmacvicar/terraform-provider-libvirt","labels_url":"https://api.github.com/repos/dmacvicar/terraform-provider-libvirt/issues/46/labels{/name}","comments_url":"https://api.github.com/repos/dmacvicar/terraform-provider-libvirt/issues/46/comments","events_url":"https://api.github.com/repos/dmacvicar/terraform-provider-libvirt/issues/46/events","html_url":"https://github.com/dmacvicar/terraform-provider-libvirt/issues/46","id":163195488,"number":46,"title":"RFC: revisit how disks are added to domains","user":{"login":"flavio","id":22728,"avatar_url":"https://avatars.githubusercontent.com/u/22728?v=3","gravatar_id":"","url":"https://api.github.com/users/flavio","html_url":"https://github.com/flavio","followers_url":"https://api.github.com/users/flavio/followers","following_url":"https://api.github.com/users/flavio/following{/other_user}","gists_url":"https://api.github.com/users/flavio/gists{/gist_id}","starred_url":"https://api.github.com/users/flavio/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/flavio/subscriptions","organizations_url":"https://api.github.com/users/flavio/orgs","repos_url":"https://api.github.com/users/flavio/repos","events_url":"https://api.github.com/users/flavio/events{/privacy}","received_events_url":"https://api.github.com/users/flavio/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":3,"created_at":"2016-06-30T15:31:30Z","updated_at":"2016-07-11T22:15:29Z","closed_at":null,"body":"## The current state\r\n\r\nRight now to add a disk to a domain we must:\r\n\r\n  1. declare a volume\r\n  2. create a disk entry linked with the volume\r\n\r\n## The problems\r\n\r\nThese are the minor issues/annoyances:\r\n\r\n  * accidentally sharing a volume between different domains\r\n  * using `count` on a domain introduces quite some complexity: you have to use `count` also inside of the volume definition and you have to be careful when writing the link (the terraform `element` syntax is not exactly user friendly)\r\n  * a lot of typing: for each domain you have to define a dedicated volume\r\n\r\nThe biggest issue from my POV is that the volume life cycle is kinda disconnected from the one of the domain.\r\n\r\n### Doesn't play well when rebuilding a domain\r\n\r\nWhen you change a domain in a way that it forces its rebuild the following actions will happen:\r\n\r\n  * the domain will be deleted\r\n  * the volume won't be deleted\r\n  * a new domain will be created, the old volume will be used by it\r\n  * the new domain is started\r\n  * the provisioners of the domain are re-executed\r\n\r\nBad things can happen during the last step because most of the times the provisioners assume they are running on a \"vanilla\" system while they already ran against that volume.\r\n\r\n### Doesn't play well with changes\r\n\r\nImagine a domain has already been provisioned and the user changes its disks. The next apply will unlink the old volumes from the domain and link the freshly created ones.\r\n\r\nThis has two problems:\r\n\r\n  * there's no way to trigger the execution of the provisioners\r\n  * the old volume is left inside of the poll until the user removes its definition (which might be inside of another `.tf` file) or when the whole infra is brought to ashes\r\n\r\nAt the same time changing a linked volume won't cause the domain provisioners to be executed again. This is IMHO a pretty big issue.\r\n\r\n## How to fix that\r\n\r\n### Terraform original design\r\n\r\nTerraform was designed to handle cloud workloads. In this context there are two types of storage devices: ephemeral and persistent ones.\r\n\r\nEach instance has always an ephemeral disk. The life cycle of this disk is coupled with the instance. A change that forces the rebuilding of the instance will cause the disk to be deleted and the new instance will start with a clean slate.\r\n\r\nThe persistent storage is usually called volume and can be attached to an instance. This is not really tied to the life cycle of an instance, hence it can be used to store really important data that has to be preserved between instance rebuilds.\r\n\r\n### The proposal\r\n\r\nThere's no way to \"taint\" a linked resource. We cannot mark all the volumes linked to a domain as to be deleted whenever the domain is rebuilt. I think the feature is missing because it would not make sense inside of the original context for which Terraform has been designed.\r\nWe basically have to implement ephemeral and persistent storage with libvirt.\r\n\r\nThe persistent one is the simplest, we just have to use the `volume` resource to implement that. However we should introduce new directives to allow the user to create a volume from nothing (like by specifying just the size). This can be useful also outside of the context of this issue.\r\n\r\nThe ephemeral one is a bit tricky, especially from the user point of view. We could extend the disk type to have the following attributes:\r\n\r\n  * pool: target pool to use\r\n  * source: image to use. This is going to be uploaded to the `pool` and used directly (no linked disk underneath)\r\n  * base_volume_id: link against an already defined volume\r\n  * base_volume_pool: look for a base volume inside of that pool\r\n  * base_volume_name: link against a volume that is identified by a name instead of an internal terraform ID\r\n\r\nDefining a domain would be something like that:\r\n```json\r\nresource \"libvirt_domain\" \"chameleon\" {\r\n  name = \"chameleon\"\r\n  disk {\r\n    source = \"opensuse-leap.qcow2\"\r\n  }\r\n}\r\n```\r\n\r\nThis would cause the `opensuse-leap.qcow2` image to be uploaded to the `default` pool as a volume named: `<domain name>.img`, hence `chameleon.img`.\r\n\r\nEverything is still handled as a volume from the libvirt POV, however the domain resource has full responsibility at managing this volume. It's just a matter of extending the create, delete and update functions of the domain resource. \r\n\r\n### The usability question\r\n\r\nEphemeral and persistent volumes have still to be added as disks to a domain. How can we differentiate between what is going to survive domain rebuilds and what is going to be nuked every time?\r\n\r\nWe could define persistent volumes in this way:\r\n```json\r\ndisk {\r\n  volume_id = \"${...}\"\r\n}```\r\n\r\nAnd ephemeral ones in this way:\r\n```json\r\ndisk {\r\n   base_volume_{id|name} = \"...\"\r\n}\r\n```\r\n\r\nHowever I think it could lead to confusion among users...\r\n\r\n## Feedback\r\n\r\nWhat do you think about the whole thing?\r\n\r\nIf you are interested I can share a POF I made (it supports create and delete of ephemeral disks created with `source`).\r\n"},"comment":{"url":"https://api.github.com/repos/dmacvicar/terraform-provider-libvirt/issues/comments/231882254","html_url":"https://github.com/dmacvicar/terraform-provider-libvirt/issues/46#issuecomment-231882254","issue_url":"https://api.github.com/repos/dmacvicar/terraform-provider-libvirt/issues/46","id":231882254,"user":{"login":"dmacvicar","id":15332,"avatar_url":"https://avatars.githubusercontent.com/u/15332?v=3","gravatar_id":"","url":"https://api.github.com/users/dmacvicar","html_url":"https://github.com/dmacvicar","followers_url":"https://api.github.com/users/dmacvicar/followers","following_url":"https://api.github.com/users/dmacvicar/following{/other_user}","gists_url":"https://api.github.com/users/dmacvicar/gists{/gist_id}","starred_url":"https://api.github.com/users/dmacvicar/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/dmacvicar/subscriptions","organizations_url":"https://api.github.com/users/dmacvicar/orgs","repos_url":"https://api.github.com/users/dmacvicar/repos","events_url":"https://api.github.com/users/dmacvicar/events{/privacy}","received_events_url":"https://api.github.com/users/dmacvicar/received_events","type":"User","site_admin":false},"created_at":"2016-07-11T22:15:29Z","updated_at":"2016-07-11T22:15:29Z","body":"I do agree this is a tricky issue and at some point I thought about making the full disk definition part of the domain.\r\n\r\nI am not completely against it, but I don't see yourself convinced about this being the right solution either.\r\n\r\nIf there is a way that we can reuse part of the code from the volume handling and that is more or less elegant I would be ok on allowing the volume definition to be \"embedded\" in the disk definition so that it is completely part of the domain.\r\n\r\nNow, where I disagree with you is in the proposal:\r\n\r\n>source: image to use. This is going to be uploaded to the pool and used directly (no linked disk underneath)\r\n>base_volume_id: link against an already defined volume\r\n>base_volume_pool: look for a base volume inside of that pool\r\n>base_volume_name: link against a volume that is identified by a name instead of an internal terraform ID\r\n\r\nWhat is the point of `source`? If you have an *ephemeral disk* there are only 2 possibilities:\r\n\r\n* You want to use a base volume (which is completely independent). In this case the .qcow2 name is private and handled by the resource, and destroyed. The user should not even know about it. `size` is determined by the base image.\r\n* You don't want to use a base volume (eg. preinstalled OS), then the only relevant attribute is `size`. The volume itself is created and destroyed with the domain and the user should not even know much about it.\r\n\r\nIn both cases the user may want to say in which pool the volume is, but I am not even sure about this. The provider could create a private volume only for these disks if we want to make things simpler.\r\n\r\nSo only the `base_volume[id|pool|name]` or `size` are relevant IMHO."}}
{"actor":{"display_login":"dmacvicar"}}