{"action":"created","issue":{"url":"https://api.github.com/repos/saltstack/salt/issues/39754","repository_url":"https://api.github.com/repos/saltstack/salt","labels_url":"https://api.github.com/repos/saltstack/salt/issues/39754/labels{/name}","comments_url":"https://api.github.com/repos/saltstack/salt/issues/39754/comments","events_url":"https://api.github.com/repos/saltstack/salt/issues/39754/events","html_url":"https://github.com/saltstack/salt/pull/39754","id":211069617,"number":39754,"title":"[WIP] terraform roster","user":{"login":"dmacvicar","id":15332,"avatar_url":"https://avatars1.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},"labels":[],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":5,"created_at":"2017-03-01T12:40:13Z","updated_at":"2017-03-03T14:24:05Z","closed_at":null,"pull_request":{"url":"https://api.github.com/repos/saltstack/salt/pulls/39754","html_url":"https://github.com/saltstack/salt/pull/39754","diff_url":"https://github.com/saltstack/salt/pull/39754.diff","patch_url":"https://github.com/saltstack/salt/pull/39754.patch"},"body":"\r\n### What does this PR do?\r\n\r\nImplements a dynamic roster from terraform current state file.\r\n\r\nCurrently supports libvirt and AWS resources.\r\n(For libvirt, see https://github.com/dmacvicar/terraform-provider-libvirt)\r\n\r\nFor libvirt resources, currently the first address of the first interface is chosen.\r\nFor AWS resources, the public_dns or the public_ip attributes are used.\r\n\r\nExample:\r\n\r\nGiven a simple salt-ssh tree with a Saltfile\r\n\r\n```yaml\r\nsalt-ssh:\r\n  config_dir: etc/salt\r\n  max_procs: 30\r\n  wipe_ssh: True\r\n```\r\n\r\nand etc/salt/master\r\n\r\n```yaml\r\nroot_dir: .\r\n  file_roots:\r\n    base:\r\n      - srv/salt\r\n  pillar_roots:\r\n    base:\r\n      - srv/pillar\r\n  roster: terraform\r\n```\r\n\r\nWe setup a terraform file that creates N virtual machines (libvirt_domain resources) setup\r\nwith cloud-init and the salt-ssh ssh key. In this case we set N to 2.\r\n\r\n```hcl\r\nprovider \"libvirt\" {\r\n  uri = \"qemu:///system\"\r\n}\r\n\r\nresource \"libvirt_cloudinit\" \"init\" {\r\n  name = \"test-init.iso\"\r\n  ssh_authorized_key = \"${file(\"etc/salt/pki/master/ssh/salt-ssh.rsa.pub\")}\"\r\n}\r\n\r\nresource \"libvirt_volume\" \"opensuse_leap\" {\r\n  name = \"opensuse_leap\"\r\n  source = \"http://r.opensu.se/Cloud:Images:Leap_42.3/images/openSUSE-Leap-42.3-OpenStack.x86_64.qcow2\"\r\n}\r\n\r\nresource \"libvirt_volume\" \"volume\" {\r\n  name = \"volume-${count.index}\"\r\n  base_volume_id = \"${libvirt_volume.opensuse_leap.id}\"\r\n  count = 2\r\n}\r\n\r\nresource \"libvirt_domain\" \"domain\" {\r\n  name = \"domain-${count.index}\"\r\n  memory = 1024\r\n  disk {\r\n       volume_id = \"${element(libvirt_volume.volume.*.id, count.index)}\"\r\n  }\r\n\r\n  network_interface {\r\n    network_name = \"default\"\r\n    hostname = \"minion${count.index}\"\r\n    wait_for_lease = 1\r\n  }\r\n  cloudinit = \"${libvirt_cloudinit.init.id}\"\r\n  count = 2\r\n}\r\n```\r\n\r\n```console\r\n$ terraform apply\r\nlibvirt_cloudinit.init: Creating...\r\n...\r\nlibvirt_volume.opensuse_leap: Creating...\r\n...\r\nlibvirt_domain.domain.1: Creating...\r\nlibvirt_domain.domain.0: Creating...\r\n...\r\nlibvirt_domain.domain.0: Creation complete\r\n...\r\nlibvirt_domain.domain.1: Creation complete\r\n\r\nApply complete! Resources: 5 added, 0 changed, 0 destroyed.\r\n\r\nThe state of your infrastructure has been saved to the path\r\nbelow. This state is required to modify and destroy your\r\ninfrastructure, so keep it safe. To inspect the complete state\r\n use the `terraform show` command.\r\n\r\nState path: terraform.tfstate\r\n```\r\n\r\nYou can start now using salt-ssh without any configuration.\r\n\r\n```console\r\n$ salt-ssh '*' test.ping\r\n  domain-0:\r\n    True\r\n  domain-1:\r\n    True\r\n```\r\n\r\n### What issues does this PR fix or reference?\r\n\r\nNone. I got inspired by an old post in the forum:\r\nhttps://groups.google.com/forum/#!topic/salt-users/HMav5sk7zQ0\r\n\r\nBut that roster was never shared or upstreamed.\r\n\r\n### Tests written?\r\n\r\nYes. One unit test (first roster with a test).\r\n\r\n## Feedback/Review needed\r\n\r\nI am looking for feedback on the following areas.\r\n\r\n* I am not sure if the ssh key handling is right the best way to achieve a zero-configuration solution.\r\n  (I kind of rely on setting the same key with cloud-init on the image)\r\n* Right now for libvirt I just use the first ip. May be a ranking like other rosters could be a good idea, but not sure how to reuse code there.\r\n* I had to refactor a bit flat roster in order to reuse it's matcher.\r\n\r\n//cc @pkazmierczak @meaksh @dincamihai @isbm "},"comment":{"url":"https://api.github.com/repos/saltstack/salt/issues/comments/283965746","html_url":"https://github.com/saltstack/salt/pull/39754#issuecomment-283965746","issue_url":"https://api.github.com/repos/saltstack/salt/issues/39754","id":283965746,"user":{"login":"dubb-b","id":26067927,"avatar_url":"https://avatars0.githubusercontent.com/u/26067927?v=3","gravatar_id":"","url":"https://api.github.com/users/dubb-b","html_url":"https://github.com/dubb-b","followers_url":"https://api.github.com/users/dubb-b/followers","following_url":"https://api.github.com/users/dubb-b/following{/other_user}","gists_url":"https://api.github.com/users/dubb-b/gists{/gist_id}","starred_url":"https://api.github.com/users/dubb-b/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/dubb-b/subscriptions","organizations_url":"https://api.github.com/users/dubb-b/orgs","repos_url":"https://api.github.com/users/dubb-b/repos","events_url":"https://api.github.com/users/dubb-b/events{/privacy}","received_events_url":"https://api.github.com/users/dubb-b/received_events","type":"User","site_admin":false},"created_at":"2017-03-03T14:24:05Z","updated_at":"2017-03-03T14:24:05Z","body":"@dmacvicar \r\n\r\nYou are right. I was thinking about the intent differently. My suggestion would not help now that I understand what you are doing more clearly."}}
{"actor":{"display_login":"dubb-b"}}