{"id":24991255,"url":"https://github.com/stefaanc/terraform-provider-hosts","last_synced_at":"2025-08-03T04:03:00.328Z","repository":{"id":77671088,"uuid":"208287906","full_name":"stefaanc/terraform-provider-hosts","owner":"stefaanc","description":"a terraform provider to work with hosts-files","archived":false,"fork":false,"pushed_at":"2019-10-04T11:59:07.000Z","size":62523,"stargazers_count":5,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-04-19T10:34:56.705Z","etag":null,"topics":["hosts-file","terraform","terraform-plugins","terraform-provider","terraform-provider-hosts"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/stefaanc.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-09-13T15:02:07.000Z","updated_at":"2024-12-03T14:22:29.000Z","dependencies_parsed_at":"2023-08-25T12:24:34.684Z","dependency_job_id":null,"html_url":"https://github.com/stefaanc/terraform-provider-hosts","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/stefaanc/terraform-provider-hosts","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stefaanc%2Fterraform-provider-hosts","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stefaanc%2Fterraform-provider-hosts/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stefaanc%2Fterraform-provider-hosts/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stefaanc%2Fterraform-provider-hosts/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/stefaanc","download_url":"https://codeload.github.com/stefaanc/terraform-provider-hosts/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stefaanc%2Fterraform-provider-hosts/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":268492035,"owners_count":24258747,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-08-03T02:00:12.545Z","response_time":2577,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["hosts-file","terraform","terraform-plugins","terraform-provider","terraform-provider-hosts"],"created_at":"2025-02-04T13:47:42.813Z","updated_at":"2025-08-03T04:03:00.274Z","avatar_url":"https://github.com/stefaanc.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Terraform Provider Hosts\r\n\r\n**a terraform provider to work with hosts-files**\r\n\r\n\r\n\r\n\u003cbr/\u003e\r\n\r\n## Prerequisites\r\n\r\nTo build:\r\n- [GNU make](https://www.gnu.org/software/make/)\r\n- [Golang](https://golang.org/) \u003e= v1.13\r\n- [Terraform plugin SDK](https://github.com/hashicorp/terraform-plugin-sdk) ~= v1.0.0\r\n\r\nTo use:\r\n- [Terraform](https://terraform.io) \u003e= v0.12.9\r\n\r\nOptional:\r\n- [PSConsole](https://github.com/stefaanc/psconsole) for PowerShell\r\n\r\n\r\n\r\n\u003cbr\u003e\r\n\r\n## Building The Provider\r\n\r\n1. Clone the git-repository on your machine\r\n\r\n   ```shell\r\n   mkdir -p $my_repositories\r\n   cd $my_repositories\r\n   git clone git@github.com:stefaanc/terraform-provider-hosts\r\n   ```\r\n   \u003e `$my_repositories` must point to the directory where you want to clone the repository\r\n   \r\n2. Build the provider\r\n\r\n   ```shell\r\n   cd $my_repositories/terraform-provider=hosts\r\n   make release\r\n   ```\r\n\r\n   This will build the provider and put it in \r\n   - `%AppData%\\terraform.d\\plugins` on Windows\r\n   - `$HOME\\.terraform.d\\plugins` on Linux\r\n\u003cbr/\u003e\r\n\r\n \u003e :bulb:  \r\n \u003e The makefile provides more commands: `tidy`, `test`, `log`, `report`, `testacc`, `build`, ...\r\n    \r\n\r\n\r\n\u003cbr\u003e\r\n\r\n## Installing The Provider\r\n\r\n1. Download the provider to your machine\r\n\r\n   - go to [the releases tab on github](https://github.com/stefaanc/terraform-provider-hosts/releases)\r\n   - download the file that is appropriate for your machine\r\n\r\n2. Move the provider from your `Downloads` folder to\r\n\r\n   - `%AppData%\\terraform.d\\plugins` on Windows\r\n   - `$HOME\\.terraform.d\\plugins` on Linux\r\n\u003cbr/\u003e\r\n\r\n\u003e :bulb:  \r\n\u003e Alternatively, you can try our latest release-in-progress under the `releases` folder.  No guarantee though this will be a fully working provider.\r\n\r\n\r\n\r\n\u003cbr\u003e\r\n\r\n## Using The Provider\r\n\r\n\u003e :bulb:  \r\n\u003e You can find the following examples (and more) under the `examples` folder\r\n\r\n### provider \"hosts\"\r\n\r\nDefines a provider for a hosts-file.\r\n  \r\n```terraform\r\nprovider \"hosts\" {\r\n    file = \"./hosts-test.txt\"\r\n    zone = \"myzone\"\r\n}\r\n```\r\n\r\nArguments | \u0026nbsp;   | Description\r\n:---------|:--------:|:-----------\r\n`file`    | Optional | The path to the `hosts`-file \u003cbr/\u003e- defaults to `\"C:\\Windows\\System32\\drivers\\etc\\hosts\"` on Windows or `\"/etc/hosts2` on Linux\u003cbr/\u003e\u003cbr/\u003e The default file is usually good for production, but a different file can be specified for testing of your terraform configuration.\r\n`zone`    | Optional | The name of the zone in the `hosts`-file \u003cbr/\u003e- defaults to `\"external\"` \u003cbr/\u003e\u003cbr/\u003eA zone is a concept that was introduced to clearly split the records in the hosts-file in one or more sections that are managed by terraform and a section that is not managed by terraform.  See [Using Zones](#using-zones) for more information.\u003cbr/\u003e\u003cbr/\u003e The default `\"external\"` zone only allows you to use \"datasources\".  If you want to create and maintain \"resources\", then a zone-name (different from `\"external\"`) will need to be specified.\r\n\r\n\u003cbr\u003e\r\n\r\n### Data-sources\r\n\r\n#### data \"hosts_record\"\r\n\r\nReads a record from the hosts-file.  Records in a hosts-file look something like `1.1.1.1   myhost1 myhost1.local   # server myhost1`\r\n\r\n```terraform\r\ndata \"hosts_record\" \"myhost1\" {\r\n    name = \"myhost1\"\r\n}\r\n```\r\n\r\nArguments | \u0026nbsp;   | Description\r\n:---------|:--------:|:-----------\r\n`name`    | Required | A name of the record that is to be read.\u003cbr/\u003e\u003cbr/\u003e  A records can have multiple names, but only one of the names of the record should be enough to identify the record (provided no other records with the same name has been manually added by mistake).\u003cbr/\u003e\u003cbr/\u003e  In the illegal case where there are multiple records with the same name, the provider will not be able to find a **single** matching record. \r\n  \r\nExports     | \u0026nbsp;   | Description\r\n:-----------|:--------:|:-----------\r\n`record_id` | Computed | An internal `record_id` for the record that is read, for instance `1`\u003cbr/\u003e\u003cbr/\u003eRemark that the internal `record_id` does not persist over different terraform action.  It can change as records are added to or deleted from the hosts-file.\r\n`address`   | Computed | The address of the record that is read, for instance `\"1.1.1.1\"`. \r\n`names`     | Computed | An array of names for the record that is read, for instance `[ \"myhost1\", \"myhost1.local\" ]`. \r\n`comment`   | Computed | The comment of the record that is read, for instance `\" server myhost`\"`. \r\n\r\n\r\n\u003e :bulb:  \r\n\u003e It may be a good idea to add an `alias` to your provider configuration and a `provider` to your data-source configuration.  This avoids terraform going to the default \"production\" `hosts`-file when you (per accident) delete your provider configuration and run `terraform refresh` (or `terraform plan` or `terraform apply`).  Not doing this may silently update your terraform state with unwanted information from the \"production\" `hosts-file` instead of deleting the information. \r\n\u003e \r\n\u003e ```terraform\r\n\u003e provider \"hosts\" {\r\n\u003e     alias = \"external\"\r\n\u003e\r\n\u003e     file = \"./hosts-test.txt\"\r\n\u003e }\r\n\u003e\r\n\u003e data \"hosts_record\" \"myhost1\" {\r\n\u003e     provider = hosts.external\r\n\u003e\r\n\u003e     name = \"myhost1\"\r\n\u003e }\r\n\u003e ```\r\n\u003e\r\n\u003e When you now apply this config, then delete both the provider and datasource from the config, and then run `terraform refresh` (or `terraform plan` or `terraform apply`), you will get the following error\r\n\u003e \r\n\u003e ![](./docs/screenshots/config-delete-provider.png)\r\n\r\n\r\n\r\n\u003cbr\u003e\r\n\r\n### Resources\r\n\r\n#### resource \"hosts_record\"   \r\n\r\nManages a record in the hosts-file.  Records in a hosts-file look something like `111.111.111.111   myhost111 myhost111.local   # server myhost111`\r\n\r\n```terraform\r\nresource \"hosts_record\" \"myhost111\" {\r\n    address = \"111.111.111.111\"\r\n    names   = [ \"myhost111\", \"myhost111.local\" ]\r\n    comment = \"server myhost111\"\r\n    notes   = \"a first test-server\"\r\n}\r\n```\r\n\r\nArguments  | \u0026nbsp;   | Description\r\n-----------|:--------:|------------\r\n`address`  | Required | The IP address of the record that is to be created.\u003cbr/\u003e\u003cbr/\u003e When changing the address of a record, the old record will be deleted and a new record will be created.\r\n`names`    | Required | An array of names for the record that is to be created\u003cbr/\u003e\u003cbr/\u003e Remark that names are always converted to lower-case when written to the hosts-file and when written to the terraform state.\u003cbr/\u003e\u003cbr/\u003e When changing one of the names of a record, or when adding or dropping a name to the record, the old record will be deleted and a new record will be created.\r\n`comment`  | Optional | The comment for the record that is to be created\u003cbr\u003e- defaults to \"\"\r\n`notes`    | Optional | Notes about the record that is to be created\u003cbr\u003e- defaults to \"\"\u003cbr/\u003e\u003cbr/\u003e Remark that notes are not saved in the hosts-file.  This means that when you add notes, this will lead to a harmless terraform update action in order to save them in the terraform state, and do this every time you apply your configuration.\r\n  \r\nExports     | \u0026nbsp;   | Description\r\n:-----------|:--------:|:-----------\r\n`record_id` | Computed | An internal `record_id` for the record that is read, for instance `1`\u003cbr/\u003e\u003cbr/\u003eRemark that the internal `record_id` does not persist over different terraform action.  It can change as records are added to or deleted from the hosts-file.\r\n\r\n\u003e :bulb:  \r\n\u003e Remark that it is perfectly legal to have multiple records with the same `address`, but it is illegal to have multiple records with the same `name`.  The terraform `\"hosts_record\"`-resource doesn't allow to create records with such conflicting names.  However, externally managed records may have them by mistake.  \r\n\r\n**_Importing a hosts-record_**\r\n\r\nYou can import a record using any of the hosts-file's names as an import-ID.\r\n\r\n- Assuming you have an existing hosts-file.\r\n\r\n  ```text\r\n  ##### Start Of Terraform Zone: myzone ##########################################\r\n  999.999.999.999 myhost999.local\r\n  ##### End Of Terraform Zone: myzone ############################################\r\n  ```\r\n\r\n  \u003e :bulb:  \r\n  \u003e Remark that this will only work when the record is in a hosts-zone, because \"external \" records cannot be managed by terraform.\r\n\r\n- Assuming you have a `host_record` resource configuration, and this resource is not yet/anymore in the terraform state\r\n\r\n  ```terraform\r\n  provider \"hosts\" {\r\n      alias = \"myzone\"\r\n \r\n      file = \"./hosts-test.txt\"\r\n      zone = \"myzone\"\r\n  }\r\n\r\n  resource \"hosts_record\" \"myhost999\" {\r\n      provider = hosts.myzone\r\n\r\n      address = \"999.999.999.999\"\r\n      names   = [ \"myhost999\", \"myhost999.local\" ]\r\n      comment = \"server myhost999\"\r\n      notes   = \"my lost server\"\r\n  }\r\n  ```\r\n\r\n  When terraform tries to create it then this will fail since it already exists.  You can edit the hosts-file and delete the resource, and then re-create it using terraform.  However, this may be a bit more involved when you need to automate this.  Alternatively you can import it.\r\n\r\n- Run the terraform command using any of the names in the hosts-file.  The name doesn't have to be one of the names in the resource configuration.\r\n\r\n  ```shell\r\n  terraform import -provider=\"hosts.myzone\" \"host_record.myhost999\" \"myhost999.local\"\r\n  ```\r\n\r\n  The resource will be imported from the hosts-file into the terraform state, and the usual lifecycle will be applied next time `terraform apply` is run.\r\n\r\n  \u003e :bulb:  \r\n  \u003e Remark that without specifying a provider option, `terraform import` will use the default hosts provider (the provider without alias).  If there is no default provider specified in your configuration (all your providers have an alias), a provider with default values will be used (the default path to the \"production\" hosts-file and the default \"external\" zone).\r\n  \u003e Remark also that the provider used in the import command, does not have to be the same as the provider in the configuration of the resource.  However, this will lead to errors when applying the configuration, since both providers are pointing to a hosts-file on the same server.\r\n\r\n\r\n\r\n\u003cbr\u003e\r\n\r\n## Using Zones\r\n\r\nZones in a hosts-file are used to clearly split managed from unmanaged records.  It is bad practise to edit the managed zones manually, although it is the only way to clean them up when you loose the terraform state file.  Re-applying terraform will re-create the zones and the records that are still in use.\r\n\r\n```text\r\n1.1.1.1   myhost1 myhost1.local   # externally managed\r\n2.2.2.2   myhost2 myhost2.local   # externally managed\r\n3.3.3.3   myhost3 myhost3.local   # externally managed\r\n\r\n##### Start Of Terraform Zone: myzone1 #########################################\r\n111.111.111.111 myhost111 myhost111.local\r\n222.222.222.222 myhost222 myhost222.local\r\n333.333.333.333 myhost333 myhost333.local\r\n##### End Of Terraform Zone: myzone1 ###########################################\r\n##### Start Of Terraform Zone: myzone2 #########################################\r\n444.444.444.444 myhost444 myhost444.local\r\n555.555.555.555 myhost555 myhost555.local\r\n666.666.666.666 myhost666 myhost666.local\r\n##### End Of Terraform Zone: myzone2 ###########################################\r\n``` \r\n\r\n\u003e :information_source:  \r\n\u003e At this moment, zones are not automatically deleted when all its records are deleted.  You will need to manually delete such zones if you want to get rid of them.\r\n\r\n\r\n\r\n\u003cbr\u003e\r\n\r\n## More Information\r\n\r\n[**Resource lifecycle methods**](./docs/resource-lifecycle-methods.md)  \r\n[**API data structure**](./docs/api-data-structure.md)  \r\n\r\n\r\n\r\n\u003cbr\u003e\r\n\r\n## For Further Investigation\r\n\r\n- delete a zone from the hosts-file when all records in the zone are deleted - this will be solved if/when we introduce `hosts_zone` resources\r\n- delete a hosts-file when all zones \u0026 records are deleted and no external records exist - this will be solved if/when we introduce `hosts_file` resources\r\n- working with hosts-files on remote servers\r\n- provide a post create/delete action (the provisioners only work post-create), f.i. to restart a service that needs to be restarted after every change to the hosts-file\r\n- add acceptance tests\r\n- terraform-style documentation\r\n- test for memory leaks","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fstefaanc%2Fterraform-provider-hosts","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fstefaanc%2Fterraform-provider-hosts","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fstefaanc%2Fterraform-provider-hosts/lists"}