├── main.tf ├── provider.go ├── main.go ├── .gitignore ├── README.md └── resource_ichdj_joke.go /main.tf: -------------------------------------------------------------------------------- 1 | resource "ichdj_random_joke" "first" { 2 | name = "first" 3 | } 4 | 5 | output "joke" { 6 | value = "${ichdj_random_joke.first.joke}" 7 | } 8 | -------------------------------------------------------------------------------- /provider.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "github.com/hashicorp/terraform/helper/schema" 5 | ) 6 | 7 | func Provider() *schema.Provider { 8 | return &schema.Provider{ 9 | ResourcesMap: map[string]*schema.Resource{ 10 | "ichdj_random_joke": resourceRandomJoke(), 11 | }, 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "github.com/hashicorp/terraform/plugin" 5 | "github.com/hashicorp/terraform/terraform" 6 | ) 7 | 8 | func main() { 9 | plugin.Serve(&plugin.ServeOpts{ 10 | ProviderFunc: func() terraform.ResourceProvider { 11 | return Provider() 12 | }, 13 | }) 14 | } 15 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | # Created by https://www.gitignore.io/api/terraform,vim,go 3 | # Edit at https://www.gitignore.io/?templates=terraform,vim,go 4 | 5 | ### Go ### 6 | # Binaries for programs and plugins 7 | *.exe 8 | *.exe~ 9 | *.dll 10 | *.so 11 | *.dylib 12 | 13 | # Test binary, built with `go test -c` 14 | *.test 15 | 16 | # Output of the go coverage tool, specifically when used with LiteIDE 17 | *.out 18 | 19 | # Dependency directories (remove the comment below to include it) 20 | # vendor/ 21 | 22 | ### Go Patch ### 23 | /vendor/ 24 | /Godeps/ 25 | 26 | ### Terraform ### 27 | # Local .terraform directories 28 | **/.terraform/* 29 | 30 | # .tfstate files 31 | *.tfstate 32 | *.tfstate.* 33 | 34 | # Crash log files 35 | crash.log 36 | 37 | # Ignore any .tfvars files that are generated automatically for each Terraform run. Most 38 | # .tfvars files are managed as part of configuration and so should be included in 39 | # version control. 40 | # 41 | # example.tfvars 42 | 43 | # Ignore override files as they are usually used to override resources locally and so 44 | # are not checked in 45 | override.tf 46 | override.tf.json 47 | *_override.tf 48 | *_override.tf.json 49 | 50 | # Include override files you do wish to add to version control using negated pattern 51 | # !example_override.tf 52 | 53 | # Include tfplan files to ignore the plan output of command: terraform plan -out=tfplan 54 | # example: *tfplan* 55 | 56 | ### Vim ### 57 | # Swap 58 | [._]*.s[a-v][a-z] 59 | [._]*.sw[a-p] 60 | [._]s[a-rt-v][a-z] 61 | [._]ss[a-gi-z] 62 | [._]sw[a-p] 63 | 64 | # Session 65 | Session.vim 66 | Sessionx.vim 67 | 68 | # Temporary 69 | .netrwhist 70 | *~ 71 | # Auto-generated tag files 72 | tags 73 | # Persistent undo 74 | [._]*.un~ 75 | 76 | # End of https://www.gitignore.io/api/terraform,vim,go 77 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Dad Joke Terraform Provider 2 | 3 | That's right: a Terraform provider that let's you declare dad jokes as resources. 4 | 5 | ![Feels Good](https://i.kym-cdn.com/entries/icons/original/000/006/077/so_good.png) 6 | 7 | I feel the same way. 8 | 9 | ## Why The Weird Name? 10 | 11 | This provider interfaces with the [icanhazdadjoke](https://icanhazdadjoke.com/) API, hence the "ichdj" at the end of the provider name ("**I** **C**an **H**az **D**ad **J**oke"). 12 | 13 | ## Usage 14 | 15 | **NOTE**: Compiled only for Linux thus far. 16 | 17 | 1. Obtain the `terraform-provider-ichdj` binary from the [releases page](https://github.com/aidanSoles/terraform-provider-ichdj/releases). You can also unzip the `terraform-provider-ichdj-.zip` file to get the provider binary. 18 | 2. Place the provider binary in the same directory as your dad joke resource declarations (`terraform` will look in your current directory for missing providers). **NOTE**: If you don't want to have a binary sitting next to your `*.tf` files, a more elegant solution can be found [here](https://www.terraform.io/docs/configuration/providers.html#third-party-plugins). 19 | 3. Declare your desired dad joke resources (basic example shown below, and in [main.tf](https://github.com/aidanSoles/terraform-provider-ichdj/blob/master/main.tf)), then `terraform init`, `terraform plan`, and `terraform apply`! 20 | 21 | ``` 22 | resource "ichdj_random_joke" "first" { 23 | name = "first" 24 | } 25 | 26 | output "joke" { 27 | value = "${ichdj_random_joke.first.joke}" 28 | } 29 | ``` 30 | 31 | ## Compilation 32 | 33 | To compile the provider yourself, [set up Go on your local system](https://golang.org/doc/install), clone this repo, and run: 34 | 35 | ``` 36 | go build -o terraform-provider-ichdj 37 | ``` 38 | 39 | in the project's root directory. 40 | -------------------------------------------------------------------------------- /resource_ichdj_joke.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "encoding/json" 5 | "github.com/hashicorp/terraform/helper/schema" 6 | "io/ioutil" 7 | "log" 8 | "net/http" 9 | "time" 10 | ) 11 | 12 | func resourceRandomJoke() *schema.Resource { 13 | return &schema.Resource{ 14 | Create: resourceRandomJokeCreate, 15 | Read: resourceRandomJokeRead, 16 | Update: resourceRandomJokeUpdate, 17 | Delete: resourceRandomJokeDelete, 18 | 19 | Schema: map[string]*schema.Schema{ 20 | 21 | "name": &schema.Schema{ 22 | Type: schema.TypeString, 23 | Optional: true, 24 | ForceNew: false, 25 | }, 26 | 27 | "joke": &schema.Schema{ 28 | Type: schema.TypeString, 29 | Computed: true, 30 | }, 31 | 32 | "status": &schema.Schema{ 33 | Type: schema.TypeInt, 34 | Computed: true, 35 | }, 36 | }, 37 | } 38 | } 39 | 40 | type RespJsonDecoded struct { 41 | Id string `json:"id"` 42 | Joke string `json:"joke"` 43 | Status int64 `json:"status"` 44 | } 45 | 46 | func resourceRandomJokeCreate(d *schema.ResourceData, m interface{}) error { 47 | // Initialize new GET request. 48 | req, err := http.NewRequest("GET", "https://icanhazdadjoke.com/", nil) 49 | 50 | if err != nil { 51 | log.Printf("[INFO] Could not initialize 'http.NewRequest' to 'https://icanhazdadjoke.com/'.") 52 | return err 53 | } 54 | 55 | req.Header.Set("Accept", "application/json") 56 | 57 | client := &http.Client{ 58 | Timeout: time.Second * 5, 59 | } 60 | 61 | resp, _ := client.Do(req) 62 | defer resp.Body.Close() 63 | respBody, err := ioutil.ReadAll(resp.Body) 64 | 65 | if err != nil { 66 | log.Printf("[INFO] Could not read response body.") 67 | return err 68 | } 69 | 70 | var respJsonDecoded RespJsonDecoded 71 | // Convert respBody to format json.Unmarshal expects (bytes). 72 | err = json.Unmarshal([]byte(string(respBody)), &respJsonDecoded) 73 | 74 | if err != nil { 75 | log.Printf("[INFO] Could not unmarshal JSON response.") 76 | return err 77 | } 78 | 79 | d.SetId(respJsonDecoded.Id) // Set Terraform ID as joke ID. 80 | d.Set("joke", respJsonDecoded.Joke) 81 | d.Set("status", respJsonDecoded.Status) 82 | 83 | return nil 84 | } 85 | 86 | func resourceRandomJokeRead(d *schema.ResourceData, m interface{}) error { 87 | return nil 88 | } 89 | 90 | func resourceRandomJokeUpdate(d *schema.ResourceData, m interface{}) error { 91 | return resourceRandomJokeRead(d, m) 92 | } 93 | 94 | func resourceRandomJokeDelete(d *schema.ResourceData, m interface{}) error { 95 | d.SetId("") 96 | return nil 97 | } 98 | --------------------------------------------------------------------------------