provider/nomad
This commit is contained in:
parent
8af241e501
commit
bb5f6498e2
|
@ -0,0 +1,49 @@
|
||||||
|
package nomad
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/hashicorp/nomad/api"
|
||||||
|
"github.com/hashicorp/terraform/helper/schema"
|
||||||
|
"github.com/hashicorp/terraform/terraform"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Provider() terraform.ResourceProvider {
|
||||||
|
return &schema.Provider{
|
||||||
|
Schema: map[string]*schema.Schema{
|
||||||
|
"address": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Required: true,
|
||||||
|
DefaultFunc: schema.EnvDefaultFunc("NOMAD_ADDR", nil),
|
||||||
|
Description: "URL of the root of the target Nomad agent.",
|
||||||
|
},
|
||||||
|
|
||||||
|
"region": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Optional: true,
|
||||||
|
DefaultFunc: schema.EnvDefaultFunc("NOMAD_REGION", ""),
|
||||||
|
Description: "Region of the target Nomad agent.",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
ConfigureFunc: providerConfigure,
|
||||||
|
|
||||||
|
ResourcesMap: map[string]*schema.Resource{
|
||||||
|
"nomad_job": resourceJob(),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func providerConfigure(d *schema.ResourceData) (interface{}, error) {
|
||||||
|
config := &api.Config{
|
||||||
|
Address: d.Get("address").(string),
|
||||||
|
Region: d.Get("region").(string),
|
||||||
|
}
|
||||||
|
|
||||||
|
client, err := api.NewClient(config)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to configure Nomad API: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return client, nil
|
||||||
|
}
|
|
@ -0,0 +1,44 @@
|
||||||
|
package nomad
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/hashicorp/terraform/helper/schema"
|
||||||
|
"github.com/hashicorp/terraform/terraform"
|
||||||
|
)
|
||||||
|
|
||||||
|
// How to run the acceptance tests for this provider:
|
||||||
|
//
|
||||||
|
// - Obtain an official Nomad release from https://nomadproject.io
|
||||||
|
// and extract the "nomad" binary
|
||||||
|
//
|
||||||
|
// - Run the following to start the Nomad agent in development mode:
|
||||||
|
// nomad agent -dev
|
||||||
|
//
|
||||||
|
// - Run the Terraform acceptance tests as usual:
|
||||||
|
// make testacc TEST=./builtin/providers/nomad
|
||||||
|
//
|
||||||
|
// The tests expect to be run in a fresh, empty Nomad server.
|
||||||
|
|
||||||
|
func TestProvider(t *testing.T) {
|
||||||
|
if err := Provider().(*schema.Provider).InternalValidate(); err != nil {
|
||||||
|
t.Fatalf("err: %s", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var testProvider *schema.Provider
|
||||||
|
var testProviders map[string]terraform.ResourceProvider
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
testProvider = Provider().(*schema.Provider)
|
||||||
|
testProviders = map[string]terraform.ResourceProvider{
|
||||||
|
"nomad": testProvider,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func testAccPreCheck(t *testing.T) {
|
||||||
|
if v := os.Getenv("NOMAD_ADDR"); v == "" {
|
||||||
|
os.Setenv("NOMAD_ADDR", "http://127.0.0.1:4646")
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,171 @@
|
||||||
|
package nomad
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/gob"
|
||||||
|
"fmt"
|
||||||
|
"log"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/hashicorp/nomad/api"
|
||||||
|
"github.com/hashicorp/nomad/jobspec"
|
||||||
|
"github.com/hashicorp/nomad/nomad/structs"
|
||||||
|
"github.com/hashicorp/terraform/helper/schema"
|
||||||
|
)
|
||||||
|
|
||||||
|
func resourceJob() *schema.Resource {
|
||||||
|
return &schema.Resource{
|
||||||
|
Create: resourceJobRegister,
|
||||||
|
Update: resourceJobRegister,
|
||||||
|
Delete: resourceJobDeregister,
|
||||||
|
Read: resourceJobRead,
|
||||||
|
Exists: resourceJobExists,
|
||||||
|
|
||||||
|
Schema: map[string]*schema.Schema{
|
||||||
|
"jobspec": {
|
||||||
|
Description: "Job specification. If you want to point to a file use the file() function.",
|
||||||
|
Required: true,
|
||||||
|
Type: schema.TypeString,
|
||||||
|
},
|
||||||
|
|
||||||
|
"deregister_on_destroy": {
|
||||||
|
Description: "If true, the job will be deregistered on destroy.",
|
||||||
|
Optional: true,
|
||||||
|
Default: true,
|
||||||
|
Type: schema.TypeBool,
|
||||||
|
},
|
||||||
|
|
||||||
|
"deregister_on_id_change": {
|
||||||
|
Description: "If true, the job will be deregistered when the job ID changes.",
|
||||||
|
Optional: true,
|
||||||
|
Default: true,
|
||||||
|
Type: schema.TypeBool,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func resourceJobRegister(d *schema.ResourceData, meta interface{}) error {
|
||||||
|
client := meta.(*api.Client)
|
||||||
|
|
||||||
|
// Get the jobspec itself
|
||||||
|
jobspecRaw := d.Get("jobspec").(string)
|
||||||
|
|
||||||
|
// Parse it
|
||||||
|
jobspecStruct, err := jobspec.Parse(strings.NewReader(jobspecRaw))
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("error parsing jobspec: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initialize and validate
|
||||||
|
jobspecStruct.Canonicalize()
|
||||||
|
if err := jobspecStruct.Validate(); err != nil {
|
||||||
|
return fmt.Errorf("Error validating job: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we have an ID and its not equal to this jobspec, then we
|
||||||
|
// have to deregister the old job before we register the new job.
|
||||||
|
prevId := d.Id()
|
||||||
|
if !d.Get("deregister_on_id_change").(bool) {
|
||||||
|
// If we aren't deregistering on ID change, just pretend we
|
||||||
|
// don't have a prior ID.
|
||||||
|
prevId = ""
|
||||||
|
}
|
||||||
|
if prevId != "" && prevId != jobspecStruct.ID {
|
||||||
|
log.Printf(
|
||||||
|
"[INFO] Deregistering %q before registering %q",
|
||||||
|
prevId, jobspecStruct.ID)
|
||||||
|
|
||||||
|
log.Printf("[DEBUG] Deregistering job: %q", prevId)
|
||||||
|
_, _, err := client.Jobs().Deregister(prevId, nil)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf(
|
||||||
|
"error deregistering previous job %q "+
|
||||||
|
"before registering new job %q: %s",
|
||||||
|
prevId, jobspecStruct.ID, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Success! Clear our state.
|
||||||
|
d.SetId("")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert it so that we can use it with the API
|
||||||
|
jobspecAPI, err := convertStructJob(jobspecStruct)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("error converting jobspec: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Register the job
|
||||||
|
_, _, err = client.Jobs().Register(jobspecAPI, nil)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("error applying jobspec: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
d.SetId(jobspecAPI.ID)
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func resourceJobDeregister(d *schema.ResourceData, meta interface{}) error {
|
||||||
|
client := meta.(*api.Client)
|
||||||
|
|
||||||
|
// If deregistration is disabled, then do nothing
|
||||||
|
if !d.Get("deregister_on_destroy").(bool) {
|
||||||
|
log.Printf(
|
||||||
|
"[WARN] Job %q will not deregister since 'deregister_on_destroy'"+
|
||||||
|
" is false", d.Id())
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
id := d.Id()
|
||||||
|
log.Printf("[DEBUG] Deregistering job: %q", id)
|
||||||
|
_, _, err := client.Jobs().Deregister(id, nil)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("error deregistering job: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func resourceJobExists(d *schema.ResourceData, meta interface{}) (bool, error) {
|
||||||
|
client := meta.(*api.Client)
|
||||||
|
|
||||||
|
id := d.Id()
|
||||||
|
log.Printf("[DEBUG] Checking if job exists: %q", id)
|
||||||
|
_, _, err := client.Jobs().Info(id, nil)
|
||||||
|
if err != nil {
|
||||||
|
// As of Nomad 0.4.1, the API client returns an error for 404
|
||||||
|
// rather than a nil result, so we must check this way.
|
||||||
|
if strings.Contains(err.Error(), "404") {
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return true, fmt.Errorf("error checking for job: %#v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return true, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func resourceJobRead(d *schema.ResourceData, meta interface{}) error {
|
||||||
|
// We don't do anything at the moment. Exists is used to
|
||||||
|
// remove non-existent jobs but read doesn't have to do anything.
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// convertStructJob is used to take a *structs.Job and convert it to an *api.Job.
|
||||||
|
//
|
||||||
|
// This is unfortunate but it is how Nomad itself does it (this is copied
|
||||||
|
// line for line from Nomad). We'll mimic them exactly to get this done.
|
||||||
|
func convertStructJob(in *structs.Job) (*api.Job, error) {
|
||||||
|
gob.Register([]map[string]interface{}{})
|
||||||
|
gob.Register([]interface{}{})
|
||||||
|
var apiJob *api.Job
|
||||||
|
buf := new(bytes.Buffer)
|
||||||
|
if err := gob.NewEncoder(buf).Encode(in); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if err := gob.NewDecoder(buf).Decode(&apiJob); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return apiJob, nil
|
||||||
|
}
|
|
@ -0,0 +1,283 @@
|
||||||
|
package nomad
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
r "github.com/hashicorp/terraform/helper/resource"
|
||||||
|
"github.com/hashicorp/terraform/terraform"
|
||||||
|
|
||||||
|
"github.com/hashicorp/nomad/api"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestResourceJob_basic(t *testing.T) {
|
||||||
|
r.Test(t, r.TestCase{
|
||||||
|
Providers: testProviders,
|
||||||
|
PreCheck: func() { testAccPreCheck(t) },
|
||||||
|
Steps: []r.TestStep{
|
||||||
|
r.TestStep{
|
||||||
|
Config: testResourceJob_initialConfig,
|
||||||
|
Check: testResourceJob_initialCheck,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
CheckDestroy: testResourceJob_checkDestroy("foo"),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestResourceJob_refresh(t *testing.T) {
|
||||||
|
r.Test(t, r.TestCase{
|
||||||
|
Providers: testProviders,
|
||||||
|
PreCheck: func() { testAccPreCheck(t) },
|
||||||
|
Steps: []r.TestStep{
|
||||||
|
r.TestStep{
|
||||||
|
Config: testResourceJob_initialConfig,
|
||||||
|
Check: testResourceJob_initialCheck,
|
||||||
|
},
|
||||||
|
|
||||||
|
// This should successfully cause the job to be recreated,
|
||||||
|
// testing the Exists function.
|
||||||
|
r.TestStep{
|
||||||
|
PreConfig: testResourceJob_deregister(t, "foo"),
|
||||||
|
Config: testResourceJob_initialConfig,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestResourceJob_disableDestroyDeregister(t *testing.T) {
|
||||||
|
r.Test(t, r.TestCase{
|
||||||
|
Providers: testProviders,
|
||||||
|
PreCheck: func() { testAccPreCheck(t) },
|
||||||
|
Steps: []r.TestStep{
|
||||||
|
r.TestStep{
|
||||||
|
Config: testResourceJob_noDestroy,
|
||||||
|
Check: testResourceJob_initialCheck,
|
||||||
|
},
|
||||||
|
|
||||||
|
// Destroy with our setting set
|
||||||
|
r.TestStep{
|
||||||
|
Destroy: true,
|
||||||
|
Config: testResourceJob_noDestroy,
|
||||||
|
Check: testResourceJob_checkExists,
|
||||||
|
},
|
||||||
|
|
||||||
|
// Re-apply without the setting set
|
||||||
|
r.TestStep{
|
||||||
|
Config: testResourceJob_initialConfig,
|
||||||
|
Check: testResourceJob_checkExists,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestResourceJob_idChange(t *testing.T) {
|
||||||
|
r.Test(t, r.TestCase{
|
||||||
|
Providers: testProviders,
|
||||||
|
PreCheck: func() { testAccPreCheck(t) },
|
||||||
|
Steps: []r.TestStep{
|
||||||
|
r.TestStep{
|
||||||
|
Config: testResourceJob_initialConfig,
|
||||||
|
Check: testResourceJob_initialCheck,
|
||||||
|
},
|
||||||
|
|
||||||
|
// Change our ID
|
||||||
|
r.TestStep{
|
||||||
|
Config: testResourceJob_updateConfig,
|
||||||
|
Check: testResourceJob_updateCheck,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
var testResourceJob_initialConfig = `
|
||||||
|
resource "nomad_job" "test" {
|
||||||
|
jobspec = <<EOT
|
||||||
|
job "foo" {
|
||||||
|
datacenters = ["dc1"]
|
||||||
|
type = "service"
|
||||||
|
group "foo" {
|
||||||
|
task "foo" {
|
||||||
|
driver = "raw_exec"
|
||||||
|
config {
|
||||||
|
command = "/bin/sleep"
|
||||||
|
args = ["1"]
|
||||||
|
}
|
||||||
|
|
||||||
|
resources {
|
||||||
|
cpu = 20
|
||||||
|
memory = 10
|
||||||
|
disk = 100
|
||||||
|
}
|
||||||
|
|
||||||
|
logs {
|
||||||
|
max_files = 3
|
||||||
|
max_file_size = 10
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
EOT
|
||||||
|
}
|
||||||
|
`
|
||||||
|
|
||||||
|
var testResourceJob_noDestroy = `
|
||||||
|
resource "nomad_job" "test" {
|
||||||
|
deregister_on_destroy = false
|
||||||
|
jobspec = <<EOT
|
||||||
|
job "foo" {
|
||||||
|
datacenters = ["dc1"]
|
||||||
|
type = "service"
|
||||||
|
group "foo" {
|
||||||
|
task "foo" {
|
||||||
|
driver = "raw_exec"
|
||||||
|
config {
|
||||||
|
command = "/bin/sleep"
|
||||||
|
args = ["1"]
|
||||||
|
}
|
||||||
|
|
||||||
|
resources {
|
||||||
|
cpu = 20
|
||||||
|
memory = 10
|
||||||
|
disk = 100
|
||||||
|
}
|
||||||
|
|
||||||
|
logs {
|
||||||
|
max_files = 3
|
||||||
|
max_file_size = 10
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
EOT
|
||||||
|
}
|
||||||
|
`
|
||||||
|
|
||||||
|
func testResourceJob_initialCheck(s *terraform.State) error {
|
||||||
|
resourceState := s.Modules[0].Resources["nomad_job.test"]
|
||||||
|
if resourceState == nil {
|
||||||
|
return fmt.Errorf("resource not found in state")
|
||||||
|
}
|
||||||
|
|
||||||
|
instanceState := resourceState.Primary
|
||||||
|
if instanceState == nil {
|
||||||
|
return fmt.Errorf("resource has no primary instance")
|
||||||
|
}
|
||||||
|
|
||||||
|
jobID := instanceState.ID
|
||||||
|
|
||||||
|
client := testProvider.Meta().(*api.Client)
|
||||||
|
job, _, err := client.Jobs().Info(jobID, nil)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("error reading back job: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if got, want := job.ID, jobID; got != want {
|
||||||
|
return fmt.Errorf("jobID is %q; want %q", got, want)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func testResourceJob_checkExists(s *terraform.State) error {
|
||||||
|
jobID := "foo"
|
||||||
|
|
||||||
|
client := testProvider.Meta().(*api.Client)
|
||||||
|
_, _, err := client.Jobs().Info(jobID, nil)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("error reading back job: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func testResourceJob_checkDestroy(jobID string) r.TestCheckFunc {
|
||||||
|
return func(*terraform.State) error {
|
||||||
|
client := testProvider.Meta().(*api.Client)
|
||||||
|
_, _, err := client.Jobs().Info(jobID, nil)
|
||||||
|
if err != nil && strings.Contains(err.Error(), "404") {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
if err == nil {
|
||||||
|
err = fmt.Errorf("not destroyed")
|
||||||
|
}
|
||||||
|
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func testResourceJob_deregister(t *testing.T, jobID string) func() {
|
||||||
|
return func() {
|
||||||
|
client := testProvider.Meta().(*api.Client)
|
||||||
|
_, _, err := client.Jobs().Deregister(jobID, nil)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("error deregistering job: %s", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var testResourceJob_updateConfig = `
|
||||||
|
resource "nomad_job" "test" {
|
||||||
|
jobspec = <<EOT
|
||||||
|
job "bar" {
|
||||||
|
datacenters = ["dc1"]
|
||||||
|
type = "service"
|
||||||
|
group "foo" {
|
||||||
|
task "foo" {
|
||||||
|
driver = "raw_exec"
|
||||||
|
config {
|
||||||
|
command = "/bin/sleep"
|
||||||
|
args = ["1"]
|
||||||
|
}
|
||||||
|
|
||||||
|
resources {
|
||||||
|
cpu = 20
|
||||||
|
memory = 10
|
||||||
|
disk = 100
|
||||||
|
}
|
||||||
|
|
||||||
|
logs {
|
||||||
|
max_files = 3
|
||||||
|
max_file_size = 10
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
EOT
|
||||||
|
}
|
||||||
|
`
|
||||||
|
|
||||||
|
func testResourceJob_updateCheck(s *terraform.State) error {
|
||||||
|
resourceState := s.Modules[0].Resources["nomad_job.test"]
|
||||||
|
if resourceState == nil {
|
||||||
|
return fmt.Errorf("resource not found in state")
|
||||||
|
}
|
||||||
|
|
||||||
|
instanceState := resourceState.Primary
|
||||||
|
if instanceState == nil {
|
||||||
|
return fmt.Errorf("resource has no primary instance")
|
||||||
|
}
|
||||||
|
|
||||||
|
jobID := instanceState.ID
|
||||||
|
|
||||||
|
client := testProvider.Meta().(*api.Client)
|
||||||
|
job, _, err := client.Jobs().Info(jobID, nil)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("error reading back job: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if got, want := job.ID, jobID; got != want {
|
||||||
|
return fmt.Errorf("jobID is %q; want %q", got, want)
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
// Verify foo doesn't exist
|
||||||
|
_, _, err := client.Jobs().Info("foo", nil)
|
||||||
|
if err == nil {
|
||||||
|
return fmt.Errorf("reading foo success")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
|
@ -34,6 +34,7 @@ import (
|
||||||
logentriesprovider "github.com/hashicorp/terraform/builtin/providers/logentries"
|
logentriesprovider "github.com/hashicorp/terraform/builtin/providers/logentries"
|
||||||
mailgunprovider "github.com/hashicorp/terraform/builtin/providers/mailgun"
|
mailgunprovider "github.com/hashicorp/terraform/builtin/providers/mailgun"
|
||||||
mysqlprovider "github.com/hashicorp/terraform/builtin/providers/mysql"
|
mysqlprovider "github.com/hashicorp/terraform/builtin/providers/mysql"
|
||||||
|
nomadprovider "github.com/hashicorp/terraform/builtin/providers/nomad"
|
||||||
nullprovider "github.com/hashicorp/terraform/builtin/providers/null"
|
nullprovider "github.com/hashicorp/terraform/builtin/providers/null"
|
||||||
openstackprovider "github.com/hashicorp/terraform/builtin/providers/openstack"
|
openstackprovider "github.com/hashicorp/terraform/builtin/providers/openstack"
|
||||||
packetprovider "github.com/hashicorp/terraform/builtin/providers/packet"
|
packetprovider "github.com/hashicorp/terraform/builtin/providers/packet"
|
||||||
|
@ -91,6 +92,7 @@ var InternalProviders = map[string]plugin.ProviderFunc{
|
||||||
"logentries": logentriesprovider.Provider,
|
"logentries": logentriesprovider.Provider,
|
||||||
"mailgun": mailgunprovider.Provider,
|
"mailgun": mailgunprovider.Provider,
|
||||||
"mysql": mysqlprovider.Provider,
|
"mysql": mysqlprovider.Provider,
|
||||||
|
"nomad": nomadprovider.Provider,
|
||||||
"null": nullprovider.Provider,
|
"null": nullprovider.Provider,
|
||||||
"openstack": openstackprovider.Provider,
|
"openstack": openstackprovider.Provider,
|
||||||
"packet": packetprovider.Provider,
|
"packet": packetprovider.Provider,
|
||||||
|
|
|
@ -35,6 +35,7 @@ body.layout-librato,
|
||||||
body.layout-logentries,
|
body.layout-logentries,
|
||||||
body.layout-mailgun,
|
body.layout-mailgun,
|
||||||
body.layout-mysql,
|
body.layout-mysql,
|
||||||
|
body.layout-nomad,
|
||||||
body.layout-openstack,
|
body.layout-openstack,
|
||||||
body.layout-packet,
|
body.layout-packet,
|
||||||
body.layout-postgresql,
|
body.layout-postgresql,
|
||||||
|
|
|
@ -0,0 +1,36 @@
|
||||||
|
---
|
||||||
|
layout: "nomad"
|
||||||
|
page_title: "Provider: Nomad"
|
||||||
|
sidebar_current: "docs-nomad-index"
|
||||||
|
description: |-
|
||||||
|
Nomad is a cluster scheduler. The Nomad provider exposes resources to interact with a Nomad cluster.
|
||||||
|
---
|
||||||
|
|
||||||
|
# Nomad Provider
|
||||||
|
|
||||||
|
[Nomad](https://www.nomadproject.io) is a cluster scheduler. The Nomad
|
||||||
|
provider exposes resources to interact with a Nomad cluster.
|
||||||
|
|
||||||
|
Use the navigation to the left to read about the available resources.
|
||||||
|
|
||||||
|
## Example Usage
|
||||||
|
|
||||||
|
```
|
||||||
|
# Configure the Nomad provider
|
||||||
|
provider "nomad" {
|
||||||
|
address = "nomad.mycompany.com"
|
||||||
|
region = "us-east-2"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Register a job
|
||||||
|
resource "nomad_job" "monitoring" {
|
||||||
|
jobspec = "${file("${path.module}/jobspec.hcl")}"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Argument Reference
|
||||||
|
|
||||||
|
The following arguments are supported:
|
||||||
|
|
||||||
|
* `address` - (Optional) The HTTP(S) API address of the Nomad agent to use. Defaults to `127.0.0.1:4646`. The `NOMAD_ADDR` environment variable can also be used.
|
||||||
|
* `region` - (Optional) The Nomad region to target. The `NOMAD_REGION` environment variable can also be used.
|
|
@ -0,0 +1,77 @@
|
||||||
|
---
|
||||||
|
layout: "nomad"
|
||||||
|
page_title: "Nomad: nomad_job"
|
||||||
|
sidebar_current: "docs-nomad-resource-job"
|
||||||
|
description: |-
|
||||||
|
Manages a job registered in Nomad.
|
||||||
|
---
|
||||||
|
|
||||||
|
# nomad\_job
|
||||||
|
|
||||||
|
Manages a job registered in Nomad.
|
||||||
|
|
||||||
|
This can be used to initialize your cluster with system jobs, common services,
|
||||||
|
and more. In day to day Nomad use it is common for developers to submit
|
||||||
|
jobs to Nomad directly, such as for general app deployment. In addition to
|
||||||
|
these apps, a Nomad cluster often runs core system services that are ideally
|
||||||
|
setup during infrastructure creation. This resource is ideal for the latter
|
||||||
|
type of job, but can be used to manage any job within Nomad.
|
||||||
|
|
||||||
|
## Example Usage
|
||||||
|
|
||||||
|
Registering a job from a jobspec file:
|
||||||
|
|
||||||
|
```
|
||||||
|
resource "nomad_job" "app" {
|
||||||
|
jobspec = "${file("${path.module}/job.hcl")}"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Registering a job from an inline jobspec. This is less realistic but
|
||||||
|
is an example of how it is possible. More likely, the contents will
|
||||||
|
be paired with something such as the
|
||||||
|
[template_file](https://www.terraform.io/docs/providers/template/d/file.html)
|
||||||
|
resource to render parameterized jobspecs.
|
||||||
|
|
||||||
|
```
|
||||||
|
resource "nomad_job" "app" {
|
||||||
|
jobspec = <<EOT
|
||||||
|
job "foo" {
|
||||||
|
datacenters = ["dc1"]
|
||||||
|
type = "service"
|
||||||
|
group "foo" {
|
||||||
|
task "foo" {
|
||||||
|
driver = "raw_exec"
|
||||||
|
config {
|
||||||
|
command = "/bin/sleep"
|
||||||
|
args = ["1"]
|
||||||
|
}
|
||||||
|
|
||||||
|
resources {
|
||||||
|
cpu = 20
|
||||||
|
memory = 10
|
||||||
|
disk = 100
|
||||||
|
}
|
||||||
|
|
||||||
|
logs {
|
||||||
|
max_files = 3
|
||||||
|
max_file_size = 10
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
EOT
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Argument Reference
|
||||||
|
|
||||||
|
The following arguments are supported:
|
||||||
|
|
||||||
|
* `jobspec` - (Required) The contents of the jobspec to register.
|
||||||
|
|
||||||
|
* `deregister_on_destroy` - (Optional) If true, the job will be deregistered
|
||||||
|
when this resource is destroyed in Terraform. Defaults to true.
|
||||||
|
|
||||||
|
* `deregister_on_id_change` - (Optional) If true, the job will be deregistered
|
||||||
|
if the ID of the job in the jobspec changes. Defaults to true.
|
|
@ -262,6 +262,10 @@
|
||||||
<a href="/docs/providers/mailgun/index.html">Mailgun</a>
|
<a href="/docs/providers/mailgun/index.html">Mailgun</a>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
|
<li<%= sidebar_current("docs-providers-nomad") %>>
|
||||||
|
<a href="/docs/providers/nomad/index.html">Nomad</a>
|
||||||
|
</li>
|
||||||
|
|
||||||
<li<%= sidebar_current("docs-providers-azurerm") %>>
|
<li<%= sidebar_current("docs-providers-azurerm") %>>
|
||||||
<a href="/docs/providers/azurerm/index.html">Microsoft Azure</a>
|
<a href="/docs/providers/azurerm/index.html">Microsoft Azure</a>
|
||||||
</li>
|
</li>
|
||||||
|
|
|
@ -0,0 +1,26 @@
|
||||||
|
<% wrap_layout :inner do %>
|
||||||
|
<% content_for :sidebar do %>
|
||||||
|
<div class="docs-sidebar hidden-print affix-top" role="complementary">
|
||||||
|
<ul class="nav docs-sidenav">
|
||||||
|
<li<%= sidebar_current("docs-home") %>>
|
||||||
|
<a href="/docs/providers/index.html">« Documentation Home</a>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li<%= sidebar_current("docs-nomad-index") %>>
|
||||||
|
<a href="/docs/providers/nomad/index.html">Nomad Provider</a>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li<%= sidebar_current(/^docs-nomad-resource/) %>>
|
||||||
|
<a href="#">Resources</a>
|
||||||
|
<ul class="nav nav-visible">
|
||||||
|
<li<%= sidebar_current("docs-nomad-resource-job") %>>
|
||||||
|
<a href="/docs/providers/nomad/r/job.html">nomad_job</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<% end %>
|
||||||
|
|
||||||
|
<%= yield %>
|
||||||
|
<% end %>
|
Loading…
Reference in New Issue