diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml
index fbf1bad9..43ef980d 100644
--- a/.github/workflows/test.yaml
+++ b/.github/workflows/test.yaml
@@ -10,22 +10,22 @@ jobs:
strategy:
fail-fast: false
matrix:
- go-version: [1.20.x, 1.21.x]
+ consul-version: [1.16.2, 1.17.0-rc1]
os: [ubuntu-latest]
runs-on: ${{ matrix.os }}
steps:
- name: Install Go
uses: actions/setup-go@4d34df0c2316fe8122ab82dc22947d607c0c91f9 # v4.0.0
with:
- go-version: ${{ matrix.go-version }}
+ go-version: 1.21.x
- name: Checkout code
uses: actions/checkout@8f4b7f84864484a7bf31766abe9204da3cbe65b3 # v3.5.0
- name: Run go tests
run: make test
- name: Run OSS acceptance tests
run: |
- curl -LO https://releases.hashicorp.com/consul/1.16.2/consul_1.16.2_linux_amd64.zip
- sudo unzip consul_1.16.2_linux_amd64.zip consul -d /usr/local/bin
+ curl -LO https://releases.hashicorp.com/consul/${{ matrix.consul-version }}/consul_${{ matrix.consul-version }}_linux_amd64.zip
+ sudo unzip consul_${{ matrix.consul-version }}_linux_amd64.zip consul -d /usr/local/bin
SKIP_REMOTE_DATACENTER_TESTS=1 make testacc TESTARGS="-count=1"
- name: Run go vet
run: make vet
@@ -36,7 +36,7 @@ jobs:
- name: Install Go
uses: actions/setup-go@4d34df0c2316fe8122ab82dc22947d607c0c91f9 # v4.0.0
with:
- go-version: 1.20.x
+ go-version: 1.21.x
- name: Checkout code
uses: actions/checkout@8f4b7f84864484a7bf31766abe9204da3cbe65b3 # v3.5.0
- name: Install tfplugindocs
@@ -45,7 +45,9 @@ jobs:
sudo unzip tfplugindocs_0.16.0_linux_amd64.zip tfplugindocs -d /usr/local/bin
rm -f tfplugindocs_0.16.0_linux_amd64.zip
- name: Generate the documentation
- run: tfplugindocs generate --ignore-deprecated true
+ run: |
+ terraform fmt -recursive .
+ tfplugindocs generate --ignore-deprecated true
- name: Fail if repository has changes
run: |
git status --short
diff --git a/consul/data_source_consul_acl_role.go b/consul/data_source_consul_acl_role.go
index ca0e2a79..8d80f304 100644
--- a/consul/data_source_consul_acl_role.go
+++ b/consul/data_source_consul_acl_role.go
@@ -13,72 +13,123 @@ func dataSourceConsulACLRole() *schema.Resource {
return &schema.Resource{
Read: datasourceConsulACLRoleRead,
+ Description: "The `consul_acl_role` data source returns the information related to a [Consul ACL Role](https://www.consul.io/api/acl/roles.html).",
+
Schema: map[string]*schema.Schema{
// Filters
"name": {
- Type: schema.TypeString,
- Required: true,
+ Type: schema.TypeString,
+ Description: "The name of the ACL Role.",
+ Required: true,
},
"namespace": {
- Type: schema.TypeString,
- Optional: true,
+ Type: schema.TypeString,
+ Description: "The namespace to lookup the role.",
+ Optional: true,
},
"partition": {
- Type: schema.TypeString,
- Optional: true,
+ Type: schema.TypeString,
+ Description: "The partition to lookup the role.",
+ Optional: true,
},
// Out parameters
"description": {
- Type: schema.TypeString,
- Computed: true,
+ Type: schema.TypeString,
+ Description: "The description of the ACL Role.",
+ Computed: true,
},
"policies": {
- Type: schema.TypeList,
- Computed: true,
+ Type: schema.TypeList,
+ Description: "The list of policies associated with the ACL Role.",
+ Computed: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"name": {
- Computed: true,
- Type: schema.TypeString,
+ Computed: true,
+ Type: schema.TypeString,
+ Description: "The name of the policy.",
},
"id": {
- Computed: true,
- Type: schema.TypeString,
+ Computed: true,
+ Type: schema.TypeString,
+ Description: "The ID of the policy.",
},
},
},
},
"service_identities": {
- Type: schema.TypeList,
- Computed: true,
+ Type: schema.TypeList,
+ Description: "The list of service identities associated with the ACL Role.",
+ Computed: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"service_name": {
- Type: schema.TypeString,
- Optional: true,
+ Type: schema.TypeString,
+ Description: "The name of the service.",
+ Optional: true,
},
"datacenters": {
- Type: schema.TypeSet,
- Optional: true,
- Elem: &schema.Schema{Type: schema.TypeString},
+ Type: schema.TypeSet,
+ Description: "Specifies the datacenters the effective policy is valid within.",
+ Optional: true,
+ Elem: &schema.Schema{Type: schema.TypeString},
},
},
},
},
"node_identities": {
- Type: schema.TypeList,
- Computed: true,
+ Type: schema.TypeList,
+ Description: "The list of node identities associated with the ACL Role.",
+ Computed: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"node_name": {
- Type: schema.TypeString,
- Computed: true,
+ Type: schema.TypeString,
+ Description: "The name of the node.",
+ Computed: true,
},
"datacenter": {
- Type: schema.TypeString,
- Computed: true,
+ Type: schema.TypeString,
+ Description: "Specifies the nodes datacenter. This will result in effective policy only being valid in that datacenter.",
+ Computed: true,
+ },
+ },
+ },
+ },
+ "templated_policies": {
+ Type: schema.TypeList,
+ Computed: true,
+ Description: "The list of templated policies that should be applied to the token.",
+ Elem: &schema.Resource{
+ Schema: map[string]*schema.Schema{
+ "template_name": {
+ Type: schema.TypeString,
+ Computed: true,
+ Description: "The name of the templated policies.",
+ },
+ "template_variables": {
+ Type: schema.TypeList,
+ Description: "The templated policy variables.",
+ Computed: true,
+ Elem: &schema.Resource{
+ Schema: map[string]*schema.Schema{
+ "name": {
+ Type: schema.TypeString,
+ Computed: true,
+ Description: "The name of node, workload identity or service.",
+ },
+ },
+ },
+ },
+ "datacenters": {
+ Type: schema.TypeList,
+ Computed: true,
+ Description: "Specifies the datacenters the effective policy is valid within.",
+ Elem: &schema.Schema{
+ Type: schema.TypeString,
+ },
},
},
},
@@ -123,6 +174,15 @@ func datasourceConsulACLRoleRead(d *schema.ResourceData, meta interface{}) error
}
}
+ templatedPolicies := make([]map[string]interface{}, len(role.TemplatedPolicies))
+ for i, tp := range role.TemplatedPolicies {
+ templatedPolicies[i] = map[string]interface{}{
+ "template_name": tp.TemplateName,
+ "datacenters": tp.Datacenters,
+ "template_variables": getTemplateVariables(tp),
+ }
+ }
+
d.SetId(role.ID)
sw := newStateWriter(d)
@@ -130,6 +190,7 @@ func datasourceConsulACLRoleRead(d *schema.ResourceData, meta interface{}) error
sw.set("policies", policies)
sw.set("service_identities", identities)
sw.set("node_identities", nodeIdentities)
+ sw.set("templated_policies", templatedPolicies)
return sw.error()
}
diff --git a/consul/data_source_consul_acl_role_test.go b/consul/data_source_consul_acl_role_test.go
index ae831907..83e30b2c 100644
--- a/consul/data_source_consul_acl_role_test.go
+++ b/consul/data_source_consul_acl_role_test.go
@@ -11,7 +11,7 @@ import (
)
func TestAccDataACLRole_basic(t *testing.T) {
- providers, _ := startTestServer(t)
+ providers, client := startTestServer(t)
resource.Test(t, resource.TestCase{
Providers: providers,
@@ -37,6 +37,20 @@ func TestAccDataACLRole_basic(t *testing.T) {
resource.TestCheckResourceAttr("data.consul_acl_role.test", "service_identities.0.service_name", "foo"),
),
},
+ {
+ Config: testAccDataSourceACLRoleConfigBasicTemplatedPolicies,
+ SkipFunc: skipIfConsulVersionLT(client, "1.17.0"),
+ Check: resource.ComposeAggregateTestCheckFunc(
+ resource.TestCheckResourceAttr("data.consul_acl_role.test", "templated_policies.#", "2"),
+ resource.TestCheckResourceAttr("data.consul_acl_role.test", "templated_policies.0.datacenters.#", "1"),
+ resource.TestCheckResourceAttr("data.consul_acl_role.test", "templated_policies.0.datacenters.0", "world"),
+ resource.TestCheckResourceAttr("data.consul_acl_role.test", "templated_policies.0.template_variables.#", "1"),
+ resource.TestCheckResourceAttr("data.consul_acl_role.test", "templated_policies.0.template_variables.0.name", "web"),
+ resource.TestCheckResourceAttr("data.consul_acl_role.test", "templated_policies.0.template_name", "builtin/service"),
+ resource.TestCheckResourceAttr("data.consul_acl_role.test", "templated_policies.1.template_variables.#", "0"),
+ resource.TestCheckResourceAttr("data.consul_acl_role.test", "templated_policies.1.template_name", "builtin/dns"),
+ ),
+ },
},
})
}
@@ -70,13 +84,14 @@ func TestAccDataACLRole_namespaceEE(t *testing.T) {
})
}
-const testAccDataSourceACLRoleConfigNotFound = `
+const (
+ testAccDataSourceACLRoleConfigNotFound = `
data "consul_acl_role" "test" {
name = "not-found"
}
`
-const testAccDataSourceACLRoleConfigBasic = `
+ testAccDataSourceACLRoleConfigBasic = `
resource "consul_acl_policy" "test-read" {
name = "test-role"
rules = "node \"\" { policy = \"read\" }"
@@ -105,14 +120,57 @@ data "consul_acl_role" "test" {
name = consul_acl_role.test.name
}
`
-const testAccDataSourceACLRoleConfigNamespaceCE = `
+
+ testAccDataSourceACLRoleConfigBasicTemplatedPolicies = `
+resource "consul_acl_policy" "test-read" {
+ name = "test-role"
+ rules = "node \"\" { policy = \"read\" }"
+ datacenters = [ "dc1" ]
+}
+
+resource "consul_acl_role" "test" {
+ name = "foo"
+ description = "bar"
+
+ policies = [
+ consul_acl_policy.test-read.id
+ ]
+
+ service_identities {
+ service_name = "foo"
+ }
+
+ node_identities {
+ node_name = "hello"
+ datacenter = "world"
+ }
+
+ templated_policies {
+ template_name = "builtin/service"
+ datacenters = ["world"]
+ template_variables {
+ name = "web"
+ }
+ }
+
+ templated_policies {
+ template_name = "builtin/dns"
+ datacenters = ["world"]
+ }
+}
+
+data "consul_acl_role" "test" {
+ name = consul_acl_role.test.name
+}
+`
+ testAccDataSourceACLRoleConfigNamespaceCE = `
data "consul_acl_role" "test" {
name = "test"
namespace = "test-data-role"
}
`
-const testAccDataSourceACLRoleConfigNamespaceEE = `
+ testAccDataSourceACLRoleConfigNamespaceEE = `
resource "consul_namespace" "test" {
name = "test-data-role"
}
@@ -142,3 +200,4 @@ data "consul_acl_role" "test" {
namespace = consul_namespace.test.name
}
`
+)
diff --git a/consul/data_source_consul_acl_token.go b/consul/data_source_consul_acl_token.go
index 1b716caa..edc21380 100644
--- a/consul/data_source_consul_acl_token.go
+++ b/consul/data_source_consul_acl_token.go
@@ -13,30 +13,37 @@ func dataSourceConsulACLToken() *schema.Resource {
return &schema.Resource{
Read: dataSourceConsulACLTokenRead,
+ Description: "The `consul_acl_token` data source returns the information related to the `consul_acl_token` resource with the exception of its secret ID.\n\nIf you want to get the secret ID associated with a token, use the [`consul_acl_token_secret_id` data source](/docs/providers/consul/d/acl_token_secret_id.html).",
+
Schema: map[string]*schema.Schema{
// Filters
"accessor_id": {
- Required: true,
- Type: schema.TypeString,
+ Required: true,
+ Description: "The accessor ID of the ACL token.",
+ Type: schema.TypeString,
},
"namespace": {
- Type: schema.TypeString,
- Optional: true,
+ Type: schema.TypeString,
+ Description: "The namespace to lookup the ACL token.",
+ Optional: true,
},
"partition": {
- Type: schema.TypeString,
- Optional: true,
+ Type: schema.TypeString,
+ Description: "The partition to lookup the ACL token.",
+ Optional: true,
},
// Out parameters
"description": {
- Type: schema.TypeString,
- Computed: true,
+ Type: schema.TypeString,
+ Description: "The description of the ACL token.",
+ Computed: true,
},
"policies": {
- Type: schema.TypeList,
- Computed: true,
+ Type: schema.TypeList,
+ Description: "A list of policies associated with the ACL token.",
+ Computed: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"name": {
@@ -51,8 +58,9 @@ func dataSourceConsulACLToken() *schema.Resource {
},
},
"roles": {
- Type: schema.TypeList,
- Computed: true,
+ Type: schema.TypeList,
+ Description: "List of roles linked to the token",
+ Computed: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"id": {
@@ -65,12 +73,11 @@ func dataSourceConsulACLToken() *schema.Resource {
},
},
},
- Description: "List of roles.",
},
"service_identities": {
Type: schema.TypeList,
Computed: true,
- Description: "The list of service identities that should be applied to the token.",
+ Description: "The list of service identities attached to the token.",
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"service_name": {
@@ -92,7 +99,7 @@ func dataSourceConsulACLToken() *schema.Resource {
"node_identities": {
Type: schema.TypeList,
Computed: true,
- Description: "The list of node identities that should be applied to the token.",
+ Description: "The list of node identities attached to the token.",
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"node_name": {
@@ -108,9 +115,46 @@ func dataSourceConsulACLToken() *schema.Resource {
},
},
},
+ "templated_policies": {
+ Type: schema.TypeList,
+ Computed: true,
+ Description: "The list of templated policies that should be applied to the token.",
+ Elem: &schema.Resource{
+ Schema: map[string]*schema.Schema{
+ "template_name": {
+ Type: schema.TypeString,
+ Computed: true,
+ Description: "The name of the templated policies.",
+ },
+ "template_variables": {
+ Type: schema.TypeList,
+ Description: "The templated policy variables.",
+ Computed: true,
+ Elem: &schema.Resource{
+ Schema: map[string]*schema.Schema{
+ "name": {
+ Type: schema.TypeString,
+ Computed: true,
+ Description: "The name of node, workload identity or service.",
+ },
+ },
+ },
+ },
+ "datacenters": {
+ Type: schema.TypeList,
+ Computed: true,
+ Description: "Specifies the datacenters the effective policy is valid within.",
+ Elem: &schema.Schema{
+ Type: schema.TypeString,
+ },
+ },
+ },
+ },
+ },
"local": {
- Type: schema.TypeBool,
- Computed: true,
+ Type: schema.TypeBool,
+ Description: "Whether the ACL token is local to the datacenter it was created within.",
+ Computed: true,
},
"expiration_time": {
Type: schema.TypeString,
@@ -162,6 +206,15 @@ func dataSourceConsulACLTokenRead(d *schema.ResourceData, meta interface{}) erro
}
}
+ templatedPolicies := make([]map[string]interface{}, len(aclToken.TemplatedPolicies))
+ for i, tp := range aclToken.TemplatedPolicies {
+ templatedPolicies[i] = map[string]interface{}{
+ "template_name": tp.TemplateName,
+ "datacenters": tp.Datacenters,
+ "template_variables": getTemplateVariables(tp),
+ }
+ }
+
var expirationTime string
if aclToken.ExpirationTime != nil {
expirationTime = aclToken.ExpirationTime.Format(time.RFC3339)
@@ -176,6 +229,7 @@ func dataSourceConsulACLTokenRead(d *schema.ResourceData, meta interface{}) erro
sw.set("roles", roles)
sw.set("service_identities", serviceIdentities)
sw.set("node_identities", nodeIdentities)
+ sw.set("templated_policies", templatedPolicies)
sw.set("expiration_time", expirationTime)
return sw.error()
diff --git a/consul/data_source_consul_acl_token_test.go b/consul/data_source_consul_acl_token_test.go
index d3aa446d..de9ceca3 100644
--- a/consul/data_source_consul_acl_token_test.go
+++ b/consul/data_source_consul_acl_token_test.go
@@ -10,7 +10,7 @@ import (
)
func TestAccDataACLToken_basic(t *testing.T) {
- providers, _ := startTestServer(t)
+ providers, client := startTestServer(t)
resource.Test(t, resource.TestCase{
Providers: providers,
@@ -36,6 +36,20 @@ func TestAccDataACLToken_basic(t *testing.T) {
resource.TestCheckResourceAttr("data.consul_acl_token.read", "service_identities.0.service_name", "hello"),
),
},
+ {
+ Config: testAccDataACLTokenConfigTemplatedPolicies,
+ SkipFunc: skipIfConsulVersionLT(client, "1.17.0"),
+ Check: resource.ComposeAggregateTestCheckFunc(
+ resource.TestCheckResourceAttr("data.consul_acl_token.read", "templated_policies.#", "2"),
+ resource.TestCheckResourceAttr("data.consul_acl_token.read", "templated_policies.0.datacenters.#", "1"),
+ resource.TestCheckResourceAttr("data.consul_acl_token.read", "templated_policies.0.datacenters.0", "world"),
+ resource.TestCheckResourceAttr("data.consul_acl_token.read", "templated_policies.0.template_variables.#", "1"),
+ resource.TestCheckResourceAttr("data.consul_acl_token.read", "templated_policies.0.template_variables.0.name", "web"),
+ resource.TestCheckResourceAttr("data.consul_acl_token.read", "templated_policies.0.template_name", "builtin/service"),
+ resource.TestCheckResourceAttr("data.consul_acl_token.read", "templated_policies.1.template_variables.#", "0"),
+ resource.TestCheckResourceAttr("data.consul_acl_token.read", "templated_policies.1.template_name", "builtin/dns"),
+ ),
+ },
},
})
}
@@ -69,7 +83,8 @@ func TestAccDataACLToken_namespaceEE(t *testing.T) {
})
}
-const testAccDataACLTokenConfig = `
+const (
+ testAccDataACLTokenConfig = `
resource "consul_acl_policy" "test" {
name = "test-token"
rules = "node \"\" { policy = \"read\" }"
@@ -97,14 +112,55 @@ data "consul_acl_token" "read" {
}
`
-const testAccDataACLTokenConfigNamespaceCE = `
+ testAccDataACLTokenConfigTemplatedPolicies = `
+resource "consul_acl_policy" "test" {
+ name = "test-token"
+ rules = "node \"\" { policy = \"read\" }"
+ datacenters = [ "dc1" ]
+}
+
+resource "consul_acl_token" "test" {
+ description = "test"
+ policies = ["${consul_acl_policy.test.name}"]
+ local = false
+
+ service_identities {
+ service_name = "hello"
+ datacenters = ["world"]
+ }
+
+ node_identities {
+ node_name = "foo"
+ datacenter = "bar"
+ }
+
+ templated_policies {
+ template_name = "builtin/service"
+ datacenters = ["world"]
+ template_variables {
+ name = "web"
+ }
+ }
+
+ templated_policies {
+ template_name = "builtin/dns"
+ datacenters = ["world"]
+ }
+}
+
+data "consul_acl_token" "read" {
+ accessor_id = "${consul_acl_token.test.id}"
+}
+`
+
+ testAccDataACLTokenConfigNamespaceCE = `
data "consul_acl_token" "read" {
accessor_id = "foo"
namespace = "test-data-token"
}
`
-const testAccDataACLTokenConfigNamespaceEE = `
+ testAccDataACLTokenConfigNamespaceEE = `
resource "consul_namespace" "test" {
name = "test-data-token"
}
@@ -128,3 +184,4 @@ data "consul_acl_token" "read" {
namespace = consul_namespace.test.name
}
`
+)
diff --git a/consul/resource_consul_acl_binding_rule.go b/consul/resource_consul_acl_binding_rule.go
index ddd7103d..2febe6ac 100644
--- a/consul/resource_consul_acl_binding_rule.go
+++ b/consul/resource_consul_acl_binding_rule.go
@@ -17,6 +17,8 @@ func resourceConsulACLBindingRule() *schema.Resource {
Update: resourceConsulACLBindingRuleUpdate,
Delete: resourceConsulACLBindingRuleDelete,
+ Description: "Starting with Consul 1.5.0, the consul_acl_binding_rule resource can be used to managed Consul ACL binding rules.",
+
Schema: map[string]*schema.Schema{
"auth_method": {
Type: schema.TypeString,
@@ -34,12 +36,13 @@ func resourceConsulACLBindingRule() *schema.Resource {
"selector": {
Type: schema.TypeString,
Optional: true,
- Description: "The expression used to math this rule against valid identities returned from an auth method validation.",
+ Description: "The expression used to match this rule against valid identities returned from an auth method validation.",
},
"bind_type": {
Type: schema.TypeString,
Required: true,
+ ForceNew: true,
Description: "Specifies the way the binding rule affects a token created at login.",
},
@@ -49,10 +52,27 @@ func resourceConsulACLBindingRule() *schema.Resource {
Description: "The name to bind to a token at login-time.",
},
+ "bind_vars": {
+ Type: schema.TypeList,
+ MaxItems: 1,
+ Description: "The variables used when binding rule type is `templated-policy`. Can be lightly templated using HIL `${foo}` syntax from available field names.",
+ Optional: true,
+ Elem: &schema.Resource{
+ Schema: map[string]*schema.Schema{
+ "name": {
+ Type: schema.TypeString,
+ Optional: true,
+ Description: "The name of node, workload identity or service.",
+ },
+ },
+ },
+ },
+
"namespace": {
- Type: schema.TypeString,
- Optional: true,
- ForceNew: true,
+ Type: schema.TypeString,
+ Description: "The namespace to create the binding rule within.",
+ Optional: true,
+ ForceNew: true,
},
"partition": {
@@ -102,6 +122,13 @@ func resourceConsulACLBindingRuleRead(d *schema.ResourceData, meta interface{})
sw.set("namespace", rule.Namespace)
sw.set("partition", rule.Partition)
+ if rule.BindVars != nil {
+ bindVars := []map[string]interface{}{
+ {"name": rule.BindVars.Name},
+ }
+ sw.set("bind_vars", bindVars)
+ }
+
return sw.error()
}
@@ -134,7 +161,7 @@ func resourceConsulACLBindingRuleDelete(d *schema.ResourceData, meta interface{}
func getBindingRule(d *schema.ResourceData, meta interface{}) *consulapi.ACLBindingRule {
_, _, wOpts := getClient(d, meta)
- return &consulapi.ACLBindingRule{
+ bindingRule := &consulapi.ACLBindingRule{
ID: d.Id(),
Description: d.Get("description").(string),
AuthMethod: d.Get("auth_method").(string),
@@ -143,4 +170,17 @@ func getBindingRule(d *schema.ResourceData, meta interface{}) *consulapi.ACLBind
BindType: consulapi.BindingRuleBindType(d.Get("bind_type").(string)),
Namespace: wOpts.Namespace,
}
+
+ if bindVars, ok := d.GetOk("bind_vars.0"); ok {
+ tv := bindVars.(map[string]interface{})
+
+ processedVars := &consulapi.ACLTemplatedPolicyVariables{}
+ if tv["name"] != nil {
+ processedVars.Name = tv["name"].(string)
+ }
+
+ bindingRule.BindVars = processedVars
+ }
+
+ return bindingRule
}
diff --git a/consul/resource_consul_acl_binding_rule_test.go b/consul/resource_consul_acl_binding_rule_test.go
index 70086705..9e207dbf 100644
--- a/consul/resource_consul_acl_binding_rule_test.go
+++ b/consul/resource_consul_acl_binding_rule_test.go
@@ -50,6 +50,28 @@ func TestAccConsulACLBindingRule_basic(t *testing.T) {
resource.TestCheckResourceAttr("consul_acl_binding_rule.test", "bind_name", "minikube2"),
),
},
+ {
+ Config: testResourceACLBindingRuleConfig_templatedPolicyWithNoVariables,
+ SkipFunc: skipIfConsulVersionLT(client, "1.17.0"),
+ Check: resource.ComposeTestCheckFunc(
+ resource.TestCheckResourceAttr("consul_acl_binding_rule.test", "auth_method", "minikube2"),
+ resource.TestCheckResourceAttr("consul_acl_binding_rule.test", "description", ""),
+ resource.TestCheckResourceAttr("consul_acl_binding_rule.test", "selector", "serviceaccount.namespace==default2"),
+ resource.TestCheckResourceAttr("consul_acl_binding_rule.test", "bind_type", "templated-policy"),
+ resource.TestCheckResourceAttr("consul_acl_binding_rule.test", "bind_name", "builtin/dns"),
+ ),
+ },
+ {
+ Config: testResourceACLBindingRuleConfig_templatedPolicyWithVariables,
+ SkipFunc: skipIfConsulVersionLT(client, "1.17.0"),
+ Check: resource.ComposeTestCheckFunc(
+ resource.TestCheckResourceAttr("consul_acl_binding_rule.test", "auth_method", "minikube2"),
+ resource.TestCheckResourceAttr("consul_acl_binding_rule.test", "description", ""),
+ resource.TestCheckResourceAttr("consul_acl_binding_rule.test", "selector", "serviceaccount.namespace==default2"),
+ resource.TestCheckResourceAttr("consul_acl_binding_rule.test", "bind_type", "templated-policy"),
+ resource.TestCheckResourceAttr("consul_acl_binding_rule.test", "bind_name", "builtin/service"),
+ ),
+ },
{
Config: testResourceACLBindingRuleConfig_wrongType,
ExpectError: regexp.MustCompile(`Invalid Binding Rule: unknown BindType "foobar"`),
@@ -105,7 +127,8 @@ func testBindingRuleDestroy(client *consulapi.Client) func(s *terraform.State) e
}
}
-const testResourceACLBindingRuleConfigBasic = `
+const (
+ testResourceACLBindingRuleConfigBasic = `
resource "consul_acl_auth_method" "test" {
name = "minikube"
type = "kubernetes"
@@ -128,7 +151,7 @@ resource "consul_acl_binding_rule" "test" {
bind_name = "minikube"
}`
-const testResourceACLBindingRuleConfigBasic_Update = `
+ testResourceACLBindingRuleConfigBasic_Update = `
resource "consul_acl_auth_method" "test" {
name = "minikube2"
type = "kubernetes"
@@ -150,7 +173,7 @@ resource "consul_acl_binding_rule" "test" {
bind_name = "minikube2"
}`
-const testResourceACLBindingRuleConfig_namespaceCE = `
+ testResourceACLBindingRuleConfig_namespaceCE = `
resource "consul_acl_auth_method" "test" {
name = "minikube"
type = "kubernetes"
@@ -174,7 +197,7 @@ resource "consul_acl_binding_rule" "test" {
namespace = "test-binding-rule"
}`
-const testResourceACLBindingRuleConfig_namespaceEE = `
+ testResourceACLBindingRuleConfig_namespaceEE = `
resource "consul_namespace" "test" {
name = "test-binding-rule"
}
@@ -203,7 +226,7 @@ resource "consul_acl_binding_rule" "test" {
namespace = consul_namespace.test.name
}`
-const testResourceACLBindingRuleConfig_node = `
+ testResourceACLBindingRuleConfig_node = `
resource "consul_acl_auth_method" "test" {
name = "minikube2"
type = "kubernetes"
@@ -225,7 +248,54 @@ resource "consul_acl_binding_rule" "test" {
bind_name = "minikube2"
}`
-const testResourceACLBindingRuleConfig_wrongType = `
+ testResourceACLBindingRuleConfig_templatedPolicyWithNoVariables = `
+resource "consul_acl_auth_method" "test" {
+ name = "minikube2"
+ type = "kubernetes"
+ description = "dev minikube cluster"
+
+ config = {
+ Host = "https://192.0.2.42:8443"
+ CACert = <<-EOF
+` + testCert + `
+ EOF
+ ServiceAccountJWT = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c"
+ }
+}
+
+resource "consul_acl_binding_rule" "test" {
+ auth_method = "${consul_acl_auth_method.test.name}"
+ selector = "serviceaccount.namespace==default2"
+ bind_type = "templated-policy"
+ bind_name = "builtin/dns"
+}`
+
+ testResourceACLBindingRuleConfig_templatedPolicyWithVariables = `
+resource "consul_acl_auth_method" "test" {
+ name = "minikube2"
+ type = "kubernetes"
+ description = "dev minikube cluster"
+
+ config = {
+ Host = "https://192.0.2.42:8443"
+ CACert = <<-EOF
+` + testCert + `
+ EOF
+ ServiceAccountJWT = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c"
+ }
+}
+
+resource "consul_acl_binding_rule" "test" {
+ auth_method = "${consul_acl_auth_method.test.name}"
+ selector = "serviceaccount.namespace==default2"
+ bind_type = "templated-policy"
+ bind_name = "builtin/service"
+ bind_vars {
+ name = "api"
+ }
+}`
+
+ testResourceACLBindingRuleConfig_wrongType = `
resource "consul_acl_auth_method" "test" {
name = "minikube2"
type = "kubernetes"
@@ -246,3 +316,4 @@ resource "consul_acl_binding_rule" "test" {
bind_type = "foobar"
bind_name = "minikube2"
}`
+)
diff --git a/consul/resource_consul_acl_role.go b/consul/resource_consul_acl_role.go
index 94d8e1ca..44e3650d 100644
--- a/consul/resource_consul_acl_role.go
+++ b/consul/resource_consul_acl_role.go
@@ -7,8 +7,8 @@ import (
"fmt"
consulapi "github.com/hashicorp/consul/api"
+ "github.com/hashicorp/go-multierror"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
- "github.com/hashicorp/terraform-plugin-sdk/helper/validation"
)
func resourceConsulACLRole() *schema.Resource {
@@ -21,6 +21,8 @@ func resourceConsulACLRole() *schema.Resource {
State: schema.ImportStatePassthrough,
},
+ Description: "The `consul_acl_role` can be used to manage [Consul ACL roles](https://developer.hashicorp.com/consul/docs/security/acl/acl-roles).",
+
Schema: map[string]*schema.Schema{
"name": {
Type: schema.TypeString,
@@ -36,10 +38,9 @@ func resourceConsulACLRole() *schema.Resource {
Type: schema.TypeSet,
Optional: true,
Elem: &schema.Schema{
- ValidateFunc: validation.IsUUID,
- Type: schema.TypeString,
+ Type: schema.TypeString,
},
- Description: "The list of policies that should be applied to the role.",
+ Description: "The list of policies that should be applied to the role. Both the policy ID or its name can be used.",
},
"service_identities": {
Type: schema.TypeSet,
@@ -81,10 +82,48 @@ func resourceConsulACLRole() *schema.Resource {
},
},
},
+ "templated_policies": {
+ Type: schema.TypeList,
+ Optional: true,
+ Description: "The list of templated policies that should be applied to the token.",
+ Elem: &schema.Resource{
+ Schema: map[string]*schema.Schema{
+ "template_name": {
+ Type: schema.TypeString,
+ Required: true,
+ Description: "The name of the templated policies.",
+ },
+ "template_variables": {
+ Type: schema.TypeList,
+ MaxItems: 1,
+ Description: "The templated policy variables.",
+ Optional: true,
+ Elem: &schema.Resource{
+ Schema: map[string]*schema.Schema{
+ "name": {
+ Type: schema.TypeString,
+ Optional: true,
+ Description: "The name of node, workload identity or service.",
+ },
+ },
+ },
+ },
+ "datacenters": {
+ Type: schema.TypeList,
+ Optional: true,
+ Description: "Specifies the datacenters the effective policy is valid within.",
+ Elem: &schema.Schema{
+ Type: schema.TypeString,
+ },
+ },
+ },
+ },
+ },
"namespace": {
- Type: schema.TypeString,
- Optional: true,
- ForceNew: true,
+ Type: schema.TypeString,
+ Description: "The namespace to create the role within.",
+ Optional: true,
+ ForceNew: true,
},
"partition": {
Type: schema.TypeString,
@@ -97,12 +136,15 @@ func resourceConsulACLRole() *schema.Resource {
}
func resourceConsulACLRoleCreate(d *schema.ResourceData, meta interface{}) error {
- client, _, wOpts := getClient(d, meta)
+ client, qOpts, wOpts := getClient(d, meta)
ACL := client.ACL()
- role := getRole(d, meta)
+ role, err := getRole(d, client, qOpts)
+ if err != nil {
+ return err
+ }
name := role.Name
- role, _, err := ACL.RoleCreate(role, wOpts)
+ role, _, err = ACL.RoleCreate(role, wOpts)
if err != nil {
return fmt.Errorf("failed to create role '%s': %s", name, err)
}
@@ -125,8 +167,21 @@ func resourceConsulACLRoleRead(d *schema.ResourceData, meta interface{}) error {
}
policies := make([]string, len(role.Policies))
+ // byName indicates which policies where set using their name by the user
+ byName := map[string]struct{}{}
+ for _, raw := range d.Get("policies").(*schema.Set).List() {
+ identifier := raw.(string)
+ policy, isID, _ := getPolicyByIdOrName(identifier, client, qOpts)
+ if policy != nil && !isID {
+ byName[identifier] = struct{}{}
+ }
+ }
for i, policy := range role.Policies {
- policies[i] = policy.ID
+ if _, found := byName[policy.Name]; found {
+ policies[i] = policy.Name
+ } else {
+ policies[i] = policy.ID
+ }
}
serviceIdentities := make([]map[string]interface{}, len(role.ServiceIdentities))
@@ -145,6 +200,15 @@ func resourceConsulACLRoleRead(d *schema.ResourceData, meta interface{}) error {
}
}
+ templatedPolicies := make([]interface{}, len(role.TemplatedPolicies))
+ for i, tp := range role.TemplatedPolicies {
+ templatedPolicies[i] = map[string]interface{}{
+ "template_name": tp.TemplateName,
+ "datacenters": tp.Datacenters,
+ "template_variables": getTemplateVariables(tp),
+ }
+ }
+
sw := newStateWriter(d)
sw.set("name", role.Name)
@@ -152,6 +216,7 @@ func resourceConsulACLRoleRead(d *schema.ResourceData, meta interface{}) error {
sw.set("policies", policies)
sw.set("service_identities", serviceIdentities)
sw.set("node_identities", nodeIdentities)
+ sw.set("templated_policies", templatedPolicies)
sw.set("namespace", role.Namespace)
sw.set("partition", role.Partition)
@@ -159,13 +224,16 @@ func resourceConsulACLRoleRead(d *schema.ResourceData, meta interface{}) error {
}
func resourceConsulACLRoleUpdate(d *schema.ResourceData, meta interface{}) error {
- client, _, wOpts := getClient(d, meta)
+ client, qOpts, wOpts := getClient(d, meta)
ACL := client.ACL()
- role := getRole(d, meta)
+ role, err := getRole(d, client, qOpts)
+ if err != nil {
+ return err
+ }
role.ID = d.Id()
- role, _, err := ACL.RoleUpdate(role, wOpts)
+ role, _, err = ACL.RoleUpdate(role, wOpts)
if err != nil {
return fmt.Errorf("failed to update role '%s': %s", d.Id(), err)
}
@@ -186,21 +254,26 @@ func resourceConsulACLRoleDelete(d *schema.ResourceData, meta interface{}) error
return nil
}
-func getRole(d *schema.ResourceData, meta interface{}) *consulapi.ACLRole {
- _, qOpts, _ := getClient(d, meta)
+func getRole(d *schema.ResourceData, client *consulapi.Client, qOpts *consulapi.QueryOptions) (*consulapi.ACLRole, error) {
roleName := d.Get("name").(string)
role := &consulapi.ACLRole{
Name: roleName,
Description: d.Get("description").(string),
Namespace: qOpts.Namespace,
}
- policies := make([]*consulapi.ACLRolePolicyLink, 0)
+
for _, raw := range d.Get("policies").(*schema.Set).List() {
- policies = append(policies, &consulapi.ACLRolePolicyLink{
- ID: raw.(string),
- })
+ identifier := raw.(string)
+ link, err := getACLRolePolicyLink(identifier, client, qOpts)
+ if err != nil {
+ return nil, err
+ }
+ if link == nil {
+ return nil, fmt.Errorf("failed to find policy %q", identifier)
+ }
+
+ role.Policies = append(role.Policies, link)
}
- role.Policies = policies
for _, raw := range d.Get("service_identities").(*schema.Set).List() {
s := raw.(map[string]interface{})
@@ -224,5 +297,66 @@ func getRole(d *schema.ResourceData, meta interface{}) *consulapi.ACLRole {
})
}
- return role
+ for key, tp := range d.Get("templated_policies").([]interface{}) {
+ t := tp.(map[string]interface{})
+
+ datacenters := []string{}
+ for _, d := range t["datacenters"].([]interface{}) {
+ datacenters = append(datacenters, d.(string))
+ }
+
+ templatedPolicy := &consulapi.ACLTemplatedPolicy{
+ Datacenters: datacenters,
+ TemplateName: t["template_name"].(string),
+ }
+
+ if templatedVariables, ok := d.GetOk(fmt.Sprint("templated_policies.", key, ".template_variables.0")); ok {
+ tv := templatedVariables.(map[string]interface{})
+ templatedPolicy.TemplateVariables = &consulapi.ACLTemplatedPolicyVariables{}
+
+ if tv["name"] != nil {
+ templatedPolicy.TemplateVariables.Name = tv["name"].(string)
+ }
+ }
+ role.TemplatedPolicies = append(role.TemplatedPolicies, templatedPolicy)
+ }
+
+ return role, nil
+}
+
+// getPolicyByIdOrName looks for a policy in Consul first by ID, then by name if
+// it found nothing. It also returns a boolean indicating whether the identifier
+// given is the ID or the name
+func getPolicyByIdOrName(identifier string, client *consulapi.Client, qOpts *consulapi.QueryOptions) (*consulapi.ACLPolicy, bool, error) {
+ var errResult *multierror.Error
+
+ policy, _, err := client.ACL().PolicyRead(identifier, qOpts)
+ errResult = multierror.Append(errResult, err)
+ if policy != nil {
+ return policy, true, errResult.ErrorOrNil()
+ }
+
+ policy, _, err = client.ACL().PolicyReadByName(identifier, qOpts)
+ if policy != nil && err == nil {
+ // we ignore the initial error that might have happened in client.ACL().PolicyRead()
+ return policy, false, nil
+ }
+
+ errResult = multierror.Append(errResult, err)
+ return policy, false, errResult.ErrorOrNil()
+}
+
+func getACLRolePolicyLink(identifier string, client *consulapi.Client, qOpts *consulapi.QueryOptions) (*consulapi.ACLRolePolicyLink, error) {
+ policy, isID, err := getPolicyByIdOrName(identifier, client, qOpts)
+ if err != nil {
+ return nil, fmt.Errorf("failed to read policy %q: %w", identifier, err)
+ }
+ if policy == nil {
+ return nil, nil
+ }
+
+ if isID {
+ return &consulapi.ACLLink{ID: identifier}, nil
+ }
+ return &consulapi.ACLLink{Name: identifier}, nil
}
diff --git a/consul/resource_consul_acl_role_policy_attachment.go b/consul/resource_consul_acl_role_policy_attachment.go
new file mode 100644
index 00000000..cfd756d2
--- /dev/null
+++ b/consul/resource_consul_acl_role_policy_attachment.go
@@ -0,0 +1,141 @@
+// Copyright (c) HashiCorp, Inc.
+// SPDX-License-Identifier: MPL-2.0
+
+package consul
+
+import (
+ "fmt"
+ "strings"
+
+ consulapi "github.com/hashicorp/consul/api"
+ "github.com/hashicorp/terraform-plugin-sdk/helper/schema"
+)
+
+func resourceConsulACLRolePolicyAttachment() *schema.Resource {
+ return &schema.Resource{
+ Create: resourceConsulACLRolePolicyAttachmentCreate,
+ Read: resourceConsulACLRolePolicyAttachmentRead,
+ Delete: resourceConsulACLRolePolicyAttachmentDelete,
+ Importer: &schema.ResourceImporter{
+ State: schema.ImportStatePassthrough,
+ },
+
+ Description: "The `consul_acl_role_policy_attachment` resource links a Consul ACL role and an ACL policy. The link is implemented through an update to the Consul ACL role.\n\n~> **NOTE:** This resource is only useful to attach policies to an ACL role that has been created outside the current Terraform configuration. If the ACL role you need to attach a policy to has been created in the current Terraform configuration and will only be used in it, you should use the `policies` attribute of [`consul_acl_role`](/docs/providers/consul/r/acl_role.html).",
+
+ Schema: map[string]*schema.Schema{
+ "role_id": {
+ Type: schema.TypeString,
+ ForceNew: true,
+ Required: true,
+ Description: "The id of the role.",
+ },
+ "policy": {
+ Type: schema.TypeString,
+ ForceNew: true,
+ Required: true,
+ Description: "The policy name.",
+ },
+ },
+ }
+}
+
+func resourceConsulACLRolePolicyAttachmentCreate(d *schema.ResourceData, meta interface{}) error {
+ client, qOpts, wOpts := getClient(d, meta)
+
+ roleID := d.Get("role_id").(string)
+
+ role, _, err := client.ACL().RoleRead(roleID, qOpts)
+ if err != nil {
+ return fmt.Errorf("role '%s' not found", roleID)
+ }
+
+ newPolicyName := d.Get("policy").(string)
+ for _, iPolicy := range role.Policies {
+ if iPolicy.Name == newPolicyName {
+ return fmt.Errorf("policy '%s' already attached to role", newPolicyName)
+ }
+ }
+
+ role.Policies = append(role.Policies, &consulapi.ACLRolePolicyLink{
+ Name: newPolicyName,
+ })
+
+ _, _, err = client.ACL().RoleUpdate(role, wOpts)
+ if err != nil {
+ return fmt.Errorf("error updating role '%q' to set new policy attachment: '%s'", roleID, err)
+ }
+
+ id := fmt.Sprintf("%s:%s", roleID, newPolicyName)
+
+ d.SetId(id)
+
+ return resourceConsulACLRolePolicyAttachmentRead(d, meta)
+}
+
+func resourceConsulACLRolePolicyAttachmentRead(d *schema.ResourceData, meta interface{}) error {
+ client, qOpts, _ := getClient(d, meta)
+
+ id := d.Id()
+
+ roleID, policyName, err := parseTwoPartID(id, "role", "policy")
+ if err != nil {
+ return fmt.Errorf("invalid role policy attachment id '%q'", id)
+ }
+
+ role, _, err := client.ACL().RoleRead(roleID, qOpts)
+ if err != nil {
+ if strings.Contains(err.Error(), "role not found") {
+ d.SetId("")
+ return nil
+ }
+ return fmt.Errorf("failed to read token '%s': %v", id, err)
+ }
+
+ policyFound := false
+ for _, iPolicy := range role.Policies {
+ if iPolicy.Name == policyName {
+ policyFound = true
+ break
+ }
+ }
+ if !policyFound {
+ d.SetId("")
+ return nil
+ }
+
+ sw := newStateWriter(d)
+ sw.set("role_id", roleID)
+ sw.set("policy", policyName)
+
+ return sw.error()
+}
+
+func resourceConsulACLRolePolicyAttachmentDelete(d *schema.ResourceData, meta interface{}) error {
+ client, qOpts, wOpts := getClient(d, meta)
+
+ id := d.Id()
+
+ roleID, policyName, err := parseTwoPartID(id, "role", "policy")
+ if err != nil {
+ return fmt.Errorf("invalid role policy attachment id '%q'", id)
+ }
+
+ role, _, err := client.ACL().RoleRead(roleID, qOpts)
+ if err != nil {
+ return fmt.Errorf("role '%s' not found", roleID)
+ }
+
+ for i, iPolicy := range role.Policies {
+ if iPolicy.Name == policyName {
+ role.Policies = append(role.Policies[:i], role.Policies[i+1:]...)
+ break
+ }
+ }
+
+ _, _, err = client.ACL().RoleUpdate(role, wOpts)
+ if err != nil {
+ return fmt.Errorf("error updating role '%q' to remove policy attachment: '%s'", roleID, err)
+ }
+
+ return nil
+}
diff --git a/consul/resource_consul_acl_role_policy_attachment_test.go b/consul/resource_consul_acl_role_policy_attachment_test.go
new file mode 100644
index 00000000..9735ec86
--- /dev/null
+++ b/consul/resource_consul_acl_role_policy_attachment_test.go
@@ -0,0 +1,149 @@
+// Copyright (c) HashiCorp, Inc.
+// SPDX-License-Identifier: MPL-2.0
+
+package consul
+
+import (
+ "fmt"
+ "testing"
+
+ consulapi "github.com/hashicorp/consul/api"
+ "github.com/hashicorp/terraform-plugin-sdk/helper/resource"
+ "github.com/hashicorp/terraform-plugin-sdk/terraform"
+)
+
+func testAccCheckConsulACLRolePolicyAttachmentDestroy(client *consulapi.Client) func(s *terraform.State) error {
+ return func(s *terraform.State) error {
+ for _, rs := range s.RootModule().Resources {
+ if rs.Type != "consul_acl_role_policy_attachment" {
+ continue
+ }
+ roleID, policyName, err := parseTwoPartID(rs.Primary.ID, "role", "policy")
+ if err != nil {
+ return fmt.Errorf("Invalid role policy attachment id '%q'", rs.Primary.ID)
+ }
+ role, _, _ := client.ACL().RoleRead(roleID, nil)
+ if role != nil {
+ for _, iPolicy := range role.Policies {
+ if iPolicy.Name == policyName {
+ return fmt.Errorf("role policy attachment %q still exists", rs.Primary.ID)
+ }
+ }
+ }
+ }
+ return nil
+ }
+
+}
+
+func testAccCheckRolePolicyID(client *consulapi.Client) func(s *terraform.State) error {
+ return func(s *terraform.State) error {
+ rs, ok := s.RootModule().Resources["consul_acl_role.test_role"]
+ if !ok {
+ return fmt.Errorf("Not Found: consul_acl_role.test_role")
+ }
+
+ roleID := rs.Primary.Attributes["id"]
+ if roleID == "" {
+ return fmt.Errorf("No token ID is set")
+ }
+
+ _, _, err := client.ACL().RoleRead(roleID, nil)
+ if err != nil {
+ return fmt.Errorf("Unable to retrieve role %q", roleID)
+ }
+
+ // Make sure the policy has then same role_id
+ rs, ok = s.RootModule().Resources["consul_acl_role_policy_attachment.test"]
+ if !ok {
+ return fmt.Errorf("Not Found: consul_acl_role_policy_attachment.test")
+ }
+
+ policyTokenID := rs.Primary.Attributes["role_id"]
+ if policyTokenID == "" {
+ return fmt.Errorf("No policy role_id is set")
+ }
+
+ if policyTokenID != roleID {
+ return fmt.Errorf("%s != %s", policyTokenID, roleID)
+ }
+
+ return nil
+ }
+}
+
+func TestAccConsulACLRolePolicyAttachment_basic(t *testing.T) {
+ providers, client := startTestServer(t)
+
+ resource.Test(t, resource.TestCase{
+ Providers: providers,
+ CheckDestroy: testAccCheckConsulACLRolePolicyAttachmentDestroy(client),
+ Steps: []resource.TestStep{
+ {
+ Config: testResourceACLRolePolicyAttachmentConfigBasic,
+ Check: resource.ComposeTestCheckFunc(
+ testAccCheckRolePolicyID(client),
+ resource.TestCheckResourceAttr("consul_acl_role_policy_attachment.test", "policy", "test-attachment"),
+ ),
+ },
+ {
+ Config: testResourceACLRolePolicyAttachmentConfigUpdate,
+ Check: resource.ComposeTestCheckFunc(
+ testAccCheckRolePolicyID(client),
+ resource.TestCheckResourceAttr("consul_acl_role_policy_attachment.test", "policy", "test2"),
+ ),
+ },
+ {
+ Config: testResourceACLRolePolicyAttachmentConfigUpdate,
+ },
+ {
+ Config: testResourceACLRolePolicyAttachmentConfigUpdate,
+ ResourceName: "consul_acl_role_policy_attachment.test",
+ ImportState: true,
+ ImportStateVerify: true,
+ },
+ },
+ })
+}
+
+const testResourceACLRolePolicyAttachmentConfigBasic = `
+resource "consul_acl_policy" "test_policy" {
+ name = "test-attachment"
+ rules = "node \"\" { policy = \"read\" }"
+ datacenters = [ "dc1" ]
+}
+
+resource "consul_acl_role" "test_role" {
+ name = "test"
+
+ lifecycle {
+ ignore_changes = ["policies"]
+ }
+}
+
+resource "consul_acl_role_policy_attachment" "test" {
+ role_id = consul_acl_role.test_role.id
+ policy = consul_acl_policy.test_policy.name
+}
+`
+
+const testResourceACLRolePolicyAttachmentConfigUpdate = `
+// Using another resource to force the update of consul_acl_role
+resource "consul_acl_policy" "test2" {
+ name = "test2"
+ rules = "node \"\" { policy = \"read\" }"
+ datacenters = [ "dc1" ]
+}
+
+resource "consul_acl_role" "test_role" {
+ name = "test"
+
+ lifecycle {
+ ignore_changes = ["policies"]
+ }
+}
+
+resource "consul_acl_role_policy_attachment" "test" {
+ role_id = consul_acl_role.test_role.id
+ policy = consul_acl_policy.test2.name
+}`
diff --git a/consul/resource_consul_acl_role_test.go b/consul/resource_consul_acl_role_test.go
index 9d1ecfd4..bf1d0726 100644
--- a/consul/resource_consul_acl_role_test.go
+++ b/consul/resource_consul_acl_role_test.go
@@ -5,7 +5,6 @@ package consul
import (
"fmt"
- "regexp"
"testing"
consulapi "github.com/hashicorp/consul/api"
@@ -51,8 +50,19 @@ func TestAccConsulACLRole_basic(t *testing.T) {
),
},
{
- Config: testResourceACLRoleConfigPolicyName,
- ExpectError: regexp.MustCompile(`expected "policies.0" to be a valid UUID`),
+ Config: testResourceACLRoleConfigUpdateTemplatedPolicies,
+ SkipFunc: skipIfConsulVersionLT(client, "1.17.0"),
+ Check: resource.ComposeAggregateTestCheckFunc(
+ resource.TestCheckResourceAttr("consul_acl_role.test", "templated_policies.#", "2"),
+ resource.TestCheckResourceAttr("consul_acl_role.test", "templated_policies.0.datacenters.#", "1"),
+ resource.TestCheckResourceAttr("consul_acl_role.test", "templated_policies.0.datacenters.0", "wide"),
+ resource.TestCheckResourceAttr("consul_acl_role.test", "templated_policies.0.template_variables.#", "1"),
+ resource.TestCheckResourceAttr("consul_acl_role.test", "templated_policies.0.template_variables.0.name", "api"),
+ resource.TestCheckResourceAttr("consul_acl_role.test", "templated_policies.0.template_name", "builtin/service"),
+ resource.TestCheckResourceAttr("consul_acl_role.test", "templated_policies.1.template_variables.#", "0"),
+ resource.TestCheckResourceAttr("consul_acl_role.test", "templated_policies.1.template_name", "builtin/dns"),
+ resource.TestCheckResourceAttr("consul_acl_role.test", "templated_policies.1.template_variables.#", "0"),
+ ),
},
{
Config: testResourceACLRoleConfigUpdate,
@@ -60,6 +70,19 @@ func TestAccConsulACLRole_basic(t *testing.T) {
ImportState: true,
ImportStateVerify: true,
},
+ {
+ Config: testResourceACLRoleConfigPolicyName,
+ Check: resource.ComposeAggregateTestCheckFunc(
+ resource.TestCheckResourceAttr("consul_acl_role.test", "description", ""),
+ resource.TestCheckResourceAttrSet("consul_acl_role.test", "id"),
+ resource.TestCheckResourceAttr("consul_acl_role.test", "name", "baz"),
+ resource.TestCheckResourceAttr("consul_acl_role.test", "namespace", ""),
+ resource.TestCheckResourceAttr("consul_acl_role.test", "node_identities.#", "0"),
+ resource.TestCheckResourceAttr("consul_acl_role.test", "policies.#", "1"),
+ resource.TestCheckResourceAttr("consul_acl_role.test", "policies.2198728100", "test-role"),
+ resource.TestCheckResourceAttr("consul_acl_role.test", "service_identities.#", "0"),
+ ),
+ },
},
})
}
@@ -111,7 +134,8 @@ func testRoleDestroy(client *consulapi.Client) func(s *terraform.State) error {
}
}
-const testResourceACLRoleConfigBasic = `
+const (
+ testResourceACLRoleConfigBasic = `
resource "consul_acl_policy" "test-read" {
name = "test-role"
rules = "node \"\" { policy = \"read\" }"
@@ -131,7 +155,7 @@ resource "consul_acl_role" "test" {
}
}`
-const testResourceACLRoleConfigUpdate = `
+ testResourceACLRoleConfigUpdate = `
resource "consul_acl_role" "test" {
name = "baz"
@@ -145,20 +169,53 @@ resource "consul_acl_role" "test" {
}
}`
-const testResourceACLRoleConfigPolicyName = `
+ testResourceACLRoleConfigUpdateTemplatedPolicies = `
+resource "consul_acl_role" "test" {
+ name = "baz"
+
+ service_identities {
+ service_name = "bar"
+ }
+
+ node_identities {
+ node_name = "hello"
+ datacenter = "world"
+ }
+
+ templated_policies {
+ template_name = "builtin/service"
+ datacenters = ["wide"]
+ template_variables {
+ name = "api"
+ }
+ }
+
+ templated_policies {
+ template_name = "builtin/dns"
+ datacenters = ["wide"]
+ }
+}`
+
+ testResourceACLRoleConfigPolicyName = `
+resource "consul_acl_policy" "test-read" {
+ name = "test-role"
+ rules = "node \"\" { policy = \"read\" }"
+ datacenters = [ "dc1" ]
+}
+
resource "consul_acl_role" "test" {
name = "baz"
- policies = ["test"]
+ policies = [consul_acl_policy.test-read.name]
}`
-const testResourceACLRoleNamespaceCE = `
+ testResourceACLRoleNamespaceCE = `
resource "consul_acl_role" "test" {
name = "test"
namespace = "test-role"
}
`
-const testResourceACLRoleNamespaceEE = `
+ testResourceACLRoleNamespaceEE = `
resource "consul_namespace" "test" {
name = "test-role"
}
@@ -168,3 +225,4 @@ resource "consul_acl_role" "test" {
namespace = consul_namespace.test.name
}
`
+)
diff --git a/consul/resource_consul_acl_token.go b/consul/resource_consul_acl_token.go
index 7b6f70f9..3f6d99e7 100644
--- a/consul/resource_consul_acl_token.go
+++ b/consul/resource_consul_acl_token.go
@@ -24,18 +24,20 @@ func resourceConsulACLToken() *schema.Resource {
State: schema.ImportStatePassthrough,
},
+ Description: "The `consul_acl_token` resource writes an ACL token into Consul.\n\n~> **NOTE:** The `consul_acl_token` resource does not save the secret ID of the generated token to the Terraform state to avoid leaking it when it is not needed. If you need to get the secret ID after creating the ACL token you can use the [`consul_acl_token_secret_id`](/docs/providers/consul/r/acl_token.html) datasource.",
+
Schema: map[string]*schema.Schema{
"accessor_id": {
Type: schema.TypeString,
ForceNew: true,
Computed: true,
Optional: true,
- Description: "The token id.",
+ Description: "The uuid of the token. If omitted, Consul will generate a random uuid.",
},
"description": {
Type: schema.TypeString,
Optional: true,
- Description: "The token description.",
+ Description: "The description of the token.",
},
"policies": {
Type: schema.TypeSet,
@@ -43,7 +45,7 @@ func resourceConsulACLToken() *schema.Resource {
Elem: &schema.Schema{
Type: schema.TypeString,
},
- Description: "List of policies.",
+ Description: "The list of policies attached to the token.",
},
"roles": {
Type: schema.TypeSet,
@@ -51,7 +53,7 @@ func resourceConsulACLToken() *schema.Resource {
Elem: &schema.Schema{
Type: schema.TypeString,
},
- Description: "List of roles",
+ Description: "The list of roles attached to the token.",
},
"service_identities": {
Type: schema.TypeList,
@@ -89,7 +91,44 @@ func resourceConsulACLToken() *schema.Resource {
"datacenter": {
Type: schema.TypeString,
Required: true,
- Description: "Specifies the node's datacenter.",
+ Description: "The datacenter of the node.",
+ },
+ },
+ },
+ },
+ "templated_policies": {
+ Type: schema.TypeList,
+ Optional: true,
+ Description: "The list of templated policies that should be applied to the token.",
+ Elem: &schema.Resource{
+ Schema: map[string]*schema.Schema{
+ "template_name": {
+ Type: schema.TypeString,
+ Required: true,
+ Description: "The name of the templated policies.",
+ },
+ "template_variables": {
+ Type: schema.TypeList,
+ MaxItems: 1,
+ Description: "The templated policy variables.",
+ Optional: true,
+ Elem: &schema.Resource{
+ Schema: map[string]*schema.Schema{
+ "name": {
+ Type: schema.TypeString,
+ Optional: true,
+ Description: "The name of node, workload identity or service.",
+ },
+ },
+ },
+ },
+ "datacenters": {
+ Type: schema.TypeList,
+ Optional: true,
+ Description: "Specifies the datacenters the effective policy is valid within.",
+ Elem: &schema.Schema{
+ Type: schema.TypeString,
+ },
},
},
},
@@ -98,19 +137,20 @@ func resourceConsulACLToken() *schema.Resource {
Type: schema.TypeBool,
ForceNew: true,
Optional: true,
- Description: "Flag to set the token local to the current datacenter.",
+ Description: "The flag to set the token local to the current datacenter.",
},
"expiration_time": {
Type: schema.TypeString,
ForceNew: true,
Optional: true,
- ValidateFunc: validation.ValidateRFC3339TimeString,
+ ValidateFunc: validation.IsRFC3339Time,
Description: "If set this represents the point after which a token should be considered revoked and is eligible for destruction.",
},
"namespace": {
- Type: schema.TypeString,
- Optional: true,
- ForceNew: true,
+ Type: schema.TypeString,
+ Description: "The namespace to create the token within.",
+ Optional: true,
+ ForceNew: true,
},
"partition": {
Type: schema.TypeString,
@@ -189,6 +229,15 @@ func resourceConsulACLTokenRead(d *schema.ResourceData, meta interface{}) error
}
}
+ templatedPolicies := make([]interface{}, len(aclToken.TemplatedPolicies))
+ for i, tp := range aclToken.TemplatedPolicies {
+ templatedPolicies[i] = map[string]interface{}{
+ "template_name": tp.TemplateName,
+ "datacenters": tp.Datacenters,
+ "template_variables": getTemplateVariables(tp),
+ }
+ }
+
sw := newStateWriter(d)
sw.set("accessor_id", aclToken.AccessorID)
sw.set("description", aclToken.Description)
@@ -196,6 +245,7 @@ func resourceConsulACLTokenRead(d *schema.ResourceData, meta interface{}) error
sw.set("roles", roles)
sw.set("service_identities", serviceIdentities)
sw.set("node_identities", nodeIdentities)
+ sw.set("templated_policies", templatedPolicies)
sw.set("local", aclToken.Local)
sw.set("expiration_time", expirationTime)
sw.set("namespace", aclToken.Namespace)
@@ -204,6 +254,16 @@ func resourceConsulACLTokenRead(d *schema.ResourceData, meta interface{}) error
return sw.error()
}
+func getTemplateVariables(templatedPolicy *consulapi.ACLTemplatedPolicy) []map[string]interface{} {
+ if templatedPolicy == nil || templatedPolicy.TemplateVariables == nil {
+ return nil
+ }
+
+ return []map[string]interface{}{
+ {"name": templatedPolicy.TemplateVariables.Name},
+ }
+}
+
func resourceConsulACLTokenUpdate(d *schema.ResourceData, meta interface{}) error {
client, _, wOpts := getClient(d, meta)
@@ -289,6 +349,31 @@ func getToken(d *schema.ResourceData) *consulapi.ACLToken {
}
aclToken.NodeIdentities = nodeIdentities
+ for key, tp := range d.Get("templated_policies").([]interface{}) {
+ t := tp.(map[string]interface{})
+
+ datacenters := []string{}
+ for _, d := range t["datacenters"].([]interface{}) {
+ datacenters = append(datacenters, d.(string))
+ }
+
+ templatedPolicy := &consulapi.ACLTemplatedPolicy{
+ Datacenters: datacenters,
+ TemplateName: t["template_name"].(string),
+ }
+
+ if templatedVariables, ok := d.GetOk(fmt.Sprint("templated_policies.", key, ".template_variables.0")); ok {
+ tv := templatedVariables.(map[string]interface{})
+
+ templatedPolicy.TemplateVariables = &consulapi.ACLTemplatedPolicyVariables{}
+
+ if tv["name"] != nil {
+ templatedPolicy.TemplateVariables.Name = tv["name"].(string)
+ }
+ }
+ aclToken.TemplatedPolicies = append(aclToken.TemplatedPolicies, templatedPolicy)
+ }
+
expirationTime := d.Get("expiration_time").(string)
if expirationTime != "" {
// the string has already been validated so there is no need to check
diff --git a/consul/resource_consul_acl_token_test.go b/consul/resource_consul_acl_token_test.go
index 2014b5e4..35b4f0de 100644
--- a/consul/resource_consul_acl_token_test.go
+++ b/consul/resource_consul_acl_token_test.go
@@ -45,6 +45,7 @@ func TestAccConsulACLToken_basic(t *testing.T) {
resource.TestCheckResourceAttr("consul_acl_token.test", "node_identities.#", "0"),
resource.TestCheckResourceAttrSet("consul_acl_token.test", "policies.#"),
resource.TestCheckResourceAttr("consul_acl_token.test", "service_identities.#", "0"),
+ resource.TestCheckResourceAttr("consul_acl_token.test", "templated_policies.#", "0"),
),
},
{
@@ -69,6 +70,20 @@ func TestAccConsulACLToken_basic(t *testing.T) {
{
Config: testResourceACLTokenConfigUpdate,
},
+ {
+ Config: testResourceACLTokenConfigUpdateTemplatedPolicies,
+ SkipFunc: skipIfConsulVersionLT(client, "1.17.0"),
+ Check: resource.ComposeAggregateTestCheckFunc(
+ resource.TestCheckResourceAttr("consul_acl_token.test", "templated_policies.#", "2"),
+ resource.TestCheckResourceAttr("consul_acl_token.test", "templated_policies.0.datacenters.#", "1"),
+ resource.TestCheckResourceAttr("consul_acl_token.test", "templated_policies.0.datacenters.0", "world"),
+ resource.TestCheckResourceAttr("consul_acl_token.test", "templated_policies.0.template_variables.#", "1"),
+ resource.TestCheckResourceAttr("consul_acl_token.test", "templated_policies.0.template_variables.0.name", "web"),
+ resource.TestCheckResourceAttr("consul_acl_token.test", "templated_policies.0.template_name", "builtin/service"),
+ resource.TestCheckResourceAttr("consul_acl_token.test", "templated_policies.1.template_variables.#", "0"),
+ resource.TestCheckResourceAttr("consul_acl_token.test", "templated_policies.1.template_name", "builtin/dns"),
+ ),
+ },
{
Config: testResourceACLTokenConfigRole,
Check: resource.ComposeAggregateTestCheckFunc(
@@ -82,6 +97,7 @@ func TestAccConsulACLToken_basic(t *testing.T) {
resource.TestCheckResourceAttr("consul_acl_token.test", "roles.#", "1"),
resource.TestCheckResourceAttr("consul_acl_token.test", "roles.1785148924", "test"),
resource.TestCheckResourceAttr("consul_acl_token.test", "service_identities.#", "0"),
+ resource.TestCheckResourceAttr("consul_acl_token.test", "templated_policies.#", "0"),
),
},
},
@@ -155,7 +171,8 @@ func TestAccConsulACLToken_namespaceEE(t *testing.T) {
})
}
-const testResourceACLTokenConfigBasic = `
+const (
+ testResourceACLTokenConfigBasic = `
resource "consul_acl_policy" "test" {
name = "test-token-basic"
rules = "node \"\" { policy = \"read\" }"
@@ -168,7 +185,30 @@ resource "consul_acl_token" "test" {
local = true
}`
-const testResourceACLTokenConfigUpdate = `
+ testResourceACLTokenConfigUpdate = `
+// Using another resource to force the update of consul_acl_token
+resource "consul_acl_policy" "test2" {
+ name = "test2"
+ rules = "node \"\" { policy = \"read\" }"
+ datacenters = [ "dc1" ]
+}
+
+resource "consul_acl_token" "test" {
+ description = "test"
+ policies = ["${consul_acl_policy.test2.name}"]
+
+ service_identities {
+ service_name = "hello"
+ datacenters = ["world"]
+ }
+
+ node_identities {
+ node_name = "foo"
+ datacenter = "bar"
+ }
+}`
+
+ testResourceACLTokenConfigUpdateTemplatedPolicies = `
// Using another resource to force the update of consul_acl_token
resource "consul_acl_policy" "test2" {
name = "test2"
@@ -189,9 +229,22 @@ resource "consul_acl_token" "test" {
node_name = "foo"
datacenter = "bar"
}
+
+ templated_policies {
+ template_name = "builtin/service"
+ datacenters = ["world"]
+ template_variables {
+ name = "web"
+ }
+ }
+
+ templated_policies {
+ template_name = "builtin/dns"
+ datacenters = ["world"]
+ }
}`
-const testResourceACLTokenConfigRole = `
+ testResourceACLTokenConfigRole = `
resource "consul_acl_role" "test" {
name = "test"
}
@@ -201,13 +254,13 @@ resource "consul_acl_token" "test" {
roles = [consul_acl_role.test.name]
}`
-const testResourceACLTokenConfigNamespaceCE = `
+ testResourceACLTokenConfigNamespaceCE = `
resource "consul_acl_token" "test" {
description = "test"
namespace = "test"
}`
-const testResourceACLTokenConfigNamespaceEE = `
+ testResourceACLTokenConfigNamespaceEE = `
resource "consul_namespace" "test" {
name = "test-token"
}
@@ -215,3 +268,4 @@ resource "consul_acl_token" "test" {
description = "test"
namespace = consul_namespace.test.name
}`
+)
diff --git a/consul/resource_consul_config_entry.go b/consul/resource_consul_config_entry.go
index 142798f9..a4d1b453 100644
--- a/consul/resource_consul_config_entry.go
+++ b/consul/resource_consul_config_entry.go
@@ -177,6 +177,14 @@ func makeConfigEntry(kind, name, config, namespace, partition string) (consulapi
return nil, fmt.Errorf("failed to unmarshal configMap: %v", err)
}
+ switch kind {
+ case consulapi.HTTPRoute, consulapi.TCPRoute, consulapi.APIGateway:
+ // The Status attribute is read-only so we don't need to send it to the
+ // server in resourceConsulConfigEntryUpdate() and must ignore it when
+ // suppressing the diff in diffConfigJSON()
+ delete(configMap, "Status")
+ }
+
configMap["kind"] = kind
configMap["name"] = name
configMap["Namespace"] = namespace
diff --git a/consul/resource_consul_config_entry_ce_test.go b/consul/resource_consul_config_entry_ce_test.go
index 6390d265..c044eb9e 100644
--- a/consul/resource_consul_config_entry_ce_test.go
+++ b/consul/resource_consul_config_entry_ce_test.go
@@ -133,6 +133,9 @@ func TestAccConsulConfigEntryCE_basic(t *testing.T) {
ResourceName: "consul_config_entry.service_intentions",
ImportStateId: "default/default/service-defaults/api",
},
+ {
+ Config: testAccConsulConfigEntryCE_HTTPRoute,
+ },
},
})
}
@@ -841,3 +844,20 @@ resource "consul_config_entry" "jwt_provider" {
})
}
`
+
+const testAccConsulConfigEntryCE_HTTPRoute = `
+resource "consul_config_entry" "http_route" {
+ kind = "http-route"
+ name = "test"
+
+ config_json = jsonencode({
+ Hostnames = null
+ Rules = null
+
+ Parents = [{
+ Kind = "api-gateway"
+ Name = "test"
+ }]
+ })
+}
+`
diff --git a/consul/resource_provider.go b/consul/resource_provider.go
index c32e164b..887a457b 100644
--- a/consul/resource_provider.go
+++ b/consul/resource_provider.go
@@ -228,6 +228,7 @@ func Provider() terraform.ResourceProvider {
"consul_acl_auth_method": resourceConsulACLAuthMethod(),
"consul_acl_binding_rule": resourceConsulACLBindingRule(),
"consul_acl_policy": resourceConsulACLPolicy(),
+ "consul_acl_role_policy_attachment": resourceConsulACLRolePolicyAttachment(),
"consul_acl_role": resourceConsulACLRole(),
"consul_acl_token_policy_attachment": resourceConsulACLTokenPolicyAttachment(),
"consul_acl_token_role_attachment": resourceConsulACLTokenRoleAttachment(),
diff --git a/consul/resource_provider_test.go b/consul/resource_provider_test.go
index 7c074db8..f89f6d99 100644
--- a/consul/resource_provider_test.go
+++ b/consul/resource_provider_test.go
@@ -5,6 +5,7 @@ package consul
import (
"encoding/json"
+ "fmt"
"net/http"
"os"
"os/exec"
@@ -13,8 +14,10 @@ import (
"testing"
"time"
+ "github.com/hashicorp/consul/api"
consulapi "github.com/hashicorp/consul/api"
"github.com/hashicorp/consul/sdk/testutil/retry"
+ "github.com/hashicorp/go-version"
"github.com/hashicorp/terraform-plugin-sdk/helper/resource"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
"github.com/hashicorp/terraform-plugin-sdk/terraform"
@@ -503,6 +506,31 @@ func skipTestOnConsulEnterpriseEdition(t *testing.T) {
}
}
+func skipIfConsulVersionLT(client *api.Client, expected string) func() (bool, error) {
+ return func() (bool, error) {
+ expected, err := version.NewVersion(expected)
+ if err != nil {
+ return false, fmt.Errorf("failed to parse version: %v", err)
+ }
+
+ data, err := client.Agent().Version()
+ if err != nil {
+ return false, err
+ }
+ v, ok := data["HumanVersion"].(string)
+ if !ok {
+ return false, fmt.Errorf("failed to find version in %#v", data)
+ }
+
+ current, err := version.NewVersion(v)
+ if err != nil {
+ return false, fmt.Errorf("failed to parse version: %v", err)
+ }
+
+ return current.LessThan(expected), nil
+ }
+}
+
// lintignore: AT004
var testHeaderConfig = `
provider "consul" {
diff --git a/docs/data-sources/acl_role.md b/docs/data-sources/acl_role.md
index d2373ec0..5444d171 100644
--- a/docs/data-sources/acl_role.md
+++ b/docs/data-sources/acl_role.md
@@ -1,19 +1,18 @@
---
-layout: "consul"
-page_title: "Consul: consul_acl_role"
-sidebar_current: "docs-consul-data-source-acl-role"
+# generated by https://github.com/hashicorp/terraform-plugin-docs
+page_title: "consul_acl_role Data Source - terraform-provider-consul"
+subcategory: ""
description: |-
- Provides information about a Consul ACL Role.
+ The consul_acl_role data source returns the information related to a Consul ACL Role https://www.consul.io/api/acl/roles.html.
---
-# consul_acl_role
+# consul_acl_role (Data Source)
-The `consul_acl_role` data source returns the information related to a
-[Consul ACL Role](https://www.consul.io/api/acl/roles.html).
+The `consul_acl_role` data source returns the information related to a [Consul ACL Role](https://www.consul.io/api/acl/roles.html).
## Example Usage
-```hcl
+```terraform
data "consul_acl_role" "test" {
name = "example-role"
}
@@ -23,22 +22,66 @@ output "consul_acl_role" {
}
```
+
+## Schema
-## Argument Reference
+### Required
-The following arguments are supported:
+- `name` (String) The name of the ACL Role.
-* `name` - (Required) The name of the ACL Role.
-* `namespace` - (Optional, Enterprise Only) The namespace to lookup the role.
-* `partition` - (Optional, Enterprise Only) The partition to lookup the role.
+### Optional
-## Attributes Reference
+- `namespace` (String) The namespace to lookup the role.
+- `partition` (String) The partition to lookup the role.
-The following attributes are exported:
+### Read-Only
-* `name` - The name of the ACL Role.
-* `namespace` - The namespace to lookup the role.
-* `description` - The description of the ACL Role.
-* `policies` - The list of policies associated with the ACL Role. Each entry has an `id` and a `name` attribute.
-* `service_identities` - The list of service identities associated with the ACL Role. Each entry has a `service_name` attribute and a list of `datacenters`.
-* `node_identities` - The list of node identities associated with the ACL Role. Each entry has a `node_name` and a `datacenter` attributes.
+- `description` (String) The description of the ACL Role.
+- `id` (String) The ID of this resource.
+- `node_identities` (List of Object) The list of node identities associated with the ACL Role. (see [below for nested schema](#nestedatt--node_identities))
+- `policies` (List of Object) The list of policies associated with the ACL Role. (see [below for nested schema](#nestedatt--policies))
+- `service_identities` (List of Object) The list of service identities associated with the ACL Role. (see [below for nested schema](#nestedatt--service_identities))
+- `templated_policies` (List of Object) The list of templated policies that should be applied to the token. (see [below for nested schema](#nestedatt--templated_policies))
+
+
+### Nested Schema for `node_identities`
+
+Read-Only:
+
+- `datacenter` (String)
+- `node_name` (String)
+
+
+
+### Nested Schema for `policies`
+
+Read-Only:
+
+- `id` (String)
+- `name` (String)
+
+
+
+### Nested Schema for `service_identities`
+
+Read-Only:
+
+- `datacenters` (Set of String)
+- `service_name` (String)
+
+
+
+### Nested Schema for `templated_policies`
+
+Read-Only:
+
+- `datacenters` (List of String)
+- `template_name` (String)
+- `template_variables` (List of Object) (see [below for nested schema](#nestedobjatt--templated_policies--template_variables))
+
+
+### Nested Schema for `templated_policies.template_variables`
+
+Read-Only:
+
+- `name` (String)
diff --git a/docs/data-sources/acl_token.md b/docs/data-sources/acl_token.md
index 8e62605b..59c30535 100644
--- a/docs/data-sources/acl_token.md
+++ b/docs/data-sources/acl_token.md
@@ -1,48 +1,102 @@
---
-layout: "consul"
-page_title: "Consul: consul_acl_token"
-sidebar_current: "docs-consul-data-source-acl-token"
+# generated by https://github.com/hashicorp/terraform-plugin-docs
+page_title: "consul_acl_token Data Source - terraform-provider-consul"
+subcategory: ""
description: |-
- Provides information about a Consul ACL Token.
+ The consul_acl_token data source returns the information related to the consul_acl_token resource with the exception of its secret ID.
+ If you want to get the secret ID associated with a token, use the consul_acl_token_secret_id data source.
---
-# consul_acl_token
+# consul_acl_token (Data Source)
-The `consul_acl_token` data source returns the information related to the
-`consul_acl_token` resource with the exception of its secret ID.
+The `consul_acl_token` data source returns the information related to the `consul_acl_token` resource with the exception of its secret ID.
-If you want to get the secret ID associated with a token, use the
-[`consul_acl_token_secret_id` data source](/docs/providers/consul/d/acl_token_secret_id.html).
+If you want to get the secret ID associated with a token, use the [`consul_acl_token_secret_id` data source](/docs/providers/consul/d/acl_token_secret_id.html).
## Example Usage
-```hcl
+```terraform
data "consul_acl_token" "test" {
accessor_id = "00000000-0000-0000-0000-000000000002"
}
output "consul_acl_policies" {
- value = "${data.consul_acl_token.test.policies}"
+ value = data.consul_acl_token.test.policies
}
```
+
+## Schema
-## Argument Reference
+### Required
-The following arguments are supported:
+- `accessor_id` (String) The accessor ID of the ACL token.
-* `accessor_id` - (Required) The accessor ID of the ACL token.
-* `namespace` - (Optional, Enterprise Only) The namespace to lookup the ACL token.
-* `partition` - (Optional, Enterprise Only) The partition to lookup the ACL token.
+### Optional
-## Attributes Reference
+- `namespace` (String) The namespace to lookup the ACL token.
+- `partition` (String) The partition to lookup the ACL token.
-The following attributes are exported:
+### Read-Only
-* `description` - The description of the ACL token.
-* `policies` - A list of policies associated with the ACL token. Each entry has an `id` and a `name` attribute.
-* `roles` - The list of roles attached to the token.
-* `service_identities` - The list of service identities attached to the token. Each entry has a `service_name` and a `datacenters` attribute.
-* `node_identities` - The list of node identities attached to the token. Each entry has a `node_name` and a `datacenter` attributes.
-* `local` - Whether the ACL token is local to the datacenter it was created within.
-* `expiration_time` - If set this represents the point after which a token should be considered revoked and is eligible for destruction.
+- `description` (String) The description of the ACL token.
+- `expiration_time` (String) If set this represents the point after which a token should be considered revoked and is eligible for destruction.
+- `id` (String) The ID of this resource.
+- `local` (Boolean) Whether the ACL token is local to the datacenter it was created within.
+- `node_identities` (List of Object) The list of node identities attached to the token. (see [below for nested schema](#nestedatt--node_identities))
+- `policies` (List of Object) A list of policies associated with the ACL token. (see [below for nested schema](#nestedatt--policies))
+- `roles` (List of Object) List of roles linked to the token (see [below for nested schema](#nestedatt--roles))
+- `service_identities` (List of Object) The list of service identities attached to the token. (see [below for nested schema](#nestedatt--service_identities))
+- `templated_policies` (List of Object) The list of templated policies that should be applied to the token. (see [below for nested schema](#nestedatt--templated_policies))
+
+
+### Nested Schema for `node_identities`
+
+Read-Only:
+
+- `datacenter` (String)
+- `node_name` (String)
+
+
+
+### Nested Schema for `policies`
+
+Read-Only:
+
+- `id` (String)
+- `name` (String)
+
+
+
+### Nested Schema for `roles`
+
+Read-Only:
+
+- `id` (String)
+- `name` (String)
+
+
+
+### Nested Schema for `service_identities`
+
+Read-Only:
+
+- `datacenters` (List of String)
+- `service_name` (String)
+
+
+
+### Nested Schema for `templated_policies`
+
+Read-Only:
+
+- `datacenters` (List of String)
+- `template_name` (String)
+- `template_variables` (List of Object) (see [below for nested schema](#nestedobjatt--templated_policies--template_variables))
+
+
+### Nested Schema for `templated_policies.template_variables`
+
+Read-Only:
+
+- `name` (String)
diff --git a/docs/resources/acl_binding_rule.md b/docs/resources/acl_binding_rule.md
index 8bb8c0c8..c1e5ea6e 100644
--- a/docs/resources/acl_binding_rule.md
+++ b/docs/resources/acl_binding_rule.md
@@ -1,64 +1,63 @@
---
-layout: "consul"
-page_title: "Consul: consul_acl_binding_rule"
-sidebar_current: "docs-consul-resource-acl-binding-rule"
+# generated by https://github.com/hashicorp/terraform-plugin-docs
+page_title: "consul_acl_binding_rule Resource - terraform-provider-consul"
+subcategory: ""
description: |-
- Allows Terraform to create an ACL binding rule
+ Starting with Consul 1.5.0, the consulaclbinding_rule resource can be used to managed Consul ACL binding rules.
---
-# consul_acl_binding_rule
-
-Starting with Consul 1.5.0, the consul_acl_binding_rule resource can be used to
-managed Consul ACL binding rules.
+# consul_acl_binding_rule (Resource)
+Starting with Consul 1.5.0, the consul_acl_binding_rule resource can be used to managed Consul ACL binding rules.
## Example Usage
-```hcl
+```terraform
resource "consul_acl_auth_method" "minikube" {
- name = "minikube"
- type = "kubernetes"
- description = "dev minikube cluster"
-
- config = {
- Host = "https://192.0.2.42:8443"
- CACert = "-----BEGIN CERTIFICATE-----\n...-----END CERTIFICATE-----\n"
- ServiceAccountJWT = "eyJhbGciOiJSUzI1NiIsImtpZCI6IiJ9..."
- }
+ name = "minikube"
+ type = "kubernetes"
+ description = "dev minikube cluster"
+
+ config = {
+ Host = "https://192.0.2.42:8443"
+ CACert = "-----BEGIN CERTIFICATE-----\n...-----END CERTIFICATE-----\n"
+ ServiceAccountJWT = "eyJhbGciOiJSUzI1NiIsImtpZCI6IiJ9..."
+ }
}
resource "consul_acl_binding_rule" "test" {
- auth_method = "${consul_acl_auth_method.minikube.name}"
- description = "foobar"
- selector = "serviceaccount.namespace==default"
- bind_type = "service"
- bind_name = "minikube"
+ auth_method = consul_acl_auth_method.minikube.name
+ description = "foobar"
+ selector = "serviceaccount.namespace==default"
+ bind_type = "service"
+ bind_name = "minikube"
}
```
-## Argument Reference
+
+## Schema
+
+### Required
+
+- `auth_method` (String) The name of the ACL auth method this rule apply.
+- `bind_name` (String) The name to bind to a token at login-time.
+- `bind_type` (String) Specifies the way the binding rule affects a token created at login.
+
+### Optional
-The following arguments are supported:
+- `bind_vars` (Block List, Max: 1) The variables used when binding rule type is `templated-policy`. Can be lightly templated using HIL `${foo}` syntax from available field names. (see [below for nested schema](#nestedblock--bind_vars))
+- `description` (String) A free form human readable description of the binding rule.
+- `namespace` (String) The namespace to create the binding rule within.
+- `partition` (String) The partition the ACL binding rule is associated with.
+- `selector` (String) The expression used to match this rule against valid identities returned from an auth method validation.
-* `auth_method` - (Required) The name of the ACL auth method this rule apply.
-* `description` - (Optional) A free form human readable description of the binding rule.
-* `selector` - (Optional) The expression used to math this rule against valid identities returned from an auth method validation.
-* `bind_type` - (Required) Specifies the way the binding rule affects a token created at login.
-* `bind_name` - (Required) The name to bind to a token at login-time.
-* `namespace` - (Optional, Enterprise Only) The namespace to create the binding rule within.
-* `partition` - (Optional, Enterprise Only) The partition the ACL binding rule is associated with.
+### Read-Only
+- `id` (String) The ID of this resource.
-## Attributes Reference
+
+### Nested Schema for `bind_vars`
-The following attributes are exported:
+Optional:
-* `id` - The ID of the the binding rule.
-* `auth_method` - The name of the ACL auth method this rule apply.
-* `description` - A free form human readable description of the
-binding rule.
-* `selector` - The expression used to math this rule against valid
-identities returned from an auth method validation.
-* `bind_type` - Specifies the way the binding rule affects a token
-created at login.
-* `bind_name` - The name to bind to a token at login-time.
+- `name` (String) The name of node, workload identity or service.
diff --git a/docs/resources/acl_role.md b/docs/resources/acl_role.md
index 11dd8ff6..fe8258d5 100644
--- a/docs/resources/acl_role.md
+++ b/docs/resources/acl_role.md
@@ -1,78 +1,103 @@
---
-layout: "consul"
-page_title: "Consul: consul_acl_role"
-sidebar_current: "docs-consul-resource-acl-role"
+# generated by https://github.com/hashicorp/terraform-plugin-docs
+page_title: "consul_acl_role Resource - terraform-provider-consul"
+subcategory: ""
description: |-
- Allows Terraform to create an ACL role
+ The consul_acl_role can be used to manage Consul ACL roles https://developer.hashicorp.com/consul/docs/security/acl/acl-roles.
---
-# consul_acl_role
-
-Starting with Consul 1.5.0, the consul_acl_role can be used to managed Consul ACL roles.
+# consul_acl_role (Resource)
+The `consul_acl_role` can be used to manage [Consul ACL roles](https://developer.hashicorp.com/consul/docs/security/acl/acl-roles).
## Example Usage
-```hcl
+```terraform
resource "consul_acl_policy" "read-policy" {
- name = "read-policy"
- rules = "node \"\" { policy = \"read\" }"
- datacenters = [ "dc1" ]
+ name = "read-policy"
+ rules = "node \"\" { policy = \"read\" }"
+ datacenters = ["dc1"]
}
resource "consul_acl_role" "read" {
- name = "foo"
- description = "bar"
+ name = "foo"
+ description = "bar"
- policies = [
- "${consul_acl_policy.read-policy.id}"
- ]
+ policies = [
+ consul_acl_policy.read-policy.id
+ ]
- service_identities {
- service_name = "foo"
- }
+ service_identities {
+ service_name = "foo"
+ }
}
```
-## Argument Reference
+
+## Schema
+
+### Required
+
+- `name` (String) The name of the ACL role.
+
+### Optional
+
+- `description` (String) A free form human readable description of the role.
+- `namespace` (String) The namespace to create the role within.
+- `node_identities` (Block List) The list of node identities that should be applied to the role. (see [below for nested schema](#nestedblock--node_identities))
+- `partition` (String) The partition the ACL role is associated with.
+- `policies` (Set of String) The list of policies that should be applied to the role. Both the policy ID or its name can be used.
+- `service_identities` (Block Set) The list of service identities that should be applied to the role. (see [below for nested schema](#nestedblock--service_identities))
+- `templated_policies` (Block List) The list of templated policies that should be applied to the token. (see [below for nested schema](#nestedblock--templated_policies))
+
+### Read-Only
+
+- `id` (String) The ID of this resource.
+
+
+### Nested Schema for `node_identities`
-The following arguments are supported:
+Required:
-* `name` - (Required) The name of the ACL role.
-* `description` - (Optional) A free form human readable description of the role.
-* `policies` - (Optional) The list of policies that should be applied to the role.
-* `service_identities` - (Optional) The list of service identities that should be applied to the role.
-* `node_identities` - (Optional) The list of node identities that should be applied to the role.
-* `namespace` - (Optional, Enterprise Only) The namespace to create the role within.
-* `partition` - (Optional, Enterprise Only) The partition the ACL role is associated with.
+- `datacenter` (String) Specifies the node's datacenter.
+- `node_name` (String) The name of the node.
-The `service_identities` block supports:
-* `service_name` - (Required) The name of the service.
-* `datacenters` - (Optional) The datacenters the effective policy is valid within.
+
+### Nested Schema for `service_identities`
-The `node_identities` block supports:
+Required:
-* `node_name` - (Required) The name of the node.
-* `datacenter` - (Required) The datacenter of the node.
+- `service_name` (String) The name of the service.
-## Attributes Reference
+Optional:
-The following attributes are exported:
+- `datacenters` (Set of String) The datacenters the effective policy is valid within. When no datacenters are provided the effective policy is valid in all datacenters including those which do not yet exist but may in the future.
-* `id` - The ID of the role.
-* `name` - The name of the ACL role.
-* `description` - A free form human readable description of the role.
-* `policies` - The list of policies that should be applied to the role.
-* `service_identities` - The list of service identities that should be applied to the role.
-* `node_identities` - The list of node identities that should be applied to the role.
-* `namespace` - The namespace to create the role within.
+
+### Nested Schema for `templated_policies`
+
+Required:
+
+- `template_name` (String) The name of the templated policies.
+
+Optional:
+
+- `datacenters` (List of String) Specifies the datacenters the effective policy is valid within.
+- `template_variables` (Block List, Max: 1) The templated policy variables. (see [below for nested schema](#nestedblock--templated_policies--template_variables))
+
+
+### Nested Schema for `templated_policies.template_variables`
+
+Optional:
+
+- `name` (String) The name of node, workload identity or service.
## Import
-`consul_acl_role` can be imported:
+Import is supported using the following syntax:
-```
-$ terraform import consul_acl_role.read 816a195f-6cb1-2e8d-92af-3011ae706318
+```shell
+terraform import consul_acl_role.read 816a195f-6cb1-2e8d-92af-3011ae706318
```
diff --git a/docs/resources/acl_role_policy_attachment.md b/docs/resources/acl_role_policy_attachment.md
new file mode 100644
index 00000000..52611eac
--- /dev/null
+++ b/docs/resources/acl_role_policy_attachment.md
@@ -0,0 +1,53 @@
+---
+# generated by https://github.com/hashicorp/terraform-plugin-docs
+page_title: "consul_acl_role_policy_attachment Resource - terraform-provider-consul"
+subcategory: ""
+description: |-
+ The consul_acl_role_policy_attachment resource links a Consul ACL role and an ACL policy. The link is implemented through an update to the Consul ACL role.
+ ~> NOTE: This resource is only useful to attach policies to an ACL role that has been created outside the current Terraform configuration. If the ACL role you need to attach a policy to has been created in the current Terraform configuration and will only be used in it, you should use the policies attribute of consul_acl_role.
+---
+
+# consul_acl_role_policy_attachment (Resource)
+
+The `consul_acl_role_policy_attachment` resource links a Consul ACL role and an ACL policy. The link is implemented through an update to the Consul ACL role.
+
+~> **NOTE:** This resource is only useful to attach policies to an ACL role that has been created outside the current Terraform configuration. If the ACL role you need to attach a policy to has been created in the current Terraform configuration and will only be used in it, you should use the `policies` attribute of [`consul_acl_role`](/docs/providers/consul/r/acl_role.html).
+
+## Example Usage
+
+```terraform
+data "consul_acl_role" "my_role" {
+ name = "my_role"
+}
+
+resource "consul_acl_policy" "read_policy" {
+ name = "read-policy"
+ rules = "node \"\" { policy = \"read\" }"
+ datacenters = ["dc1"]
+}
+
+resource "consul_acl_role_policy_attachment" "my_role_read_policy" {
+ role_id = data.consul_acl_role.test.id
+ policy = consul_acl_policy.read_policy.name
+}
+```
+
+
+## Schema
+
+### Required
+
+- `policy` (String) The policy name.
+- `role_id` (String) The id of the role.
+
+### Read-Only
+
+- `id` (String) The ID of this resource.
+
+## Import
+
+Import is supported using the following syntax:
+
+```shell
+terraform import consul_acl_role_policy_attachment.my_role_read_policy 624d94ca-bc5c-f960-4e83-0a609cf588be:policy_name
+```
diff --git a/docs/resources/acl_token.md b/docs/resources/acl_token.md
index b65cb94f..7ccd984c 100644
--- a/docs/resources/acl_token.md
+++ b/docs/resources/acl_token.md
@@ -1,20 +1,23 @@
---
-layout: "consul"
-page_title: "Consul: consul_acl_token"
-sidebar_current: "docs-consul-resource-acl-token"
+# generated by https://github.com/hashicorp/terraform-plugin-docs
+page_title: "consul_acl_token Resource - terraform-provider-consul"
+subcategory: ""
description: |-
- Allows Terraform to create an ACL token
+ The consul_acl_token resource writes an ACL token into Consul.
+ ~> NOTE: The consul_acl_token resource does not save the secret ID of the generated token to the Terraform state to avoid leaking it when it is not needed. If you need to get the secret ID after creating the ACL token you can use the consul_acl_token_secret_id datasource.
---
-# consul_acl_token
+# consul_acl_token (Resource)
The `consul_acl_token` resource writes an ACL token into Consul.
+~> **NOTE:** The `consul_acl_token` resource does not save the secret ID of the generated token to the Terraform state to avoid leaking it when it is not needed. If you need to get the secret ID after creating the ACL token you can use the [`consul_acl_token_secret_id`](/docs/providers/consul/r/acl_token.html) datasource.
+
## Example Usage
-### Basic usage
+```terraform
+# Basic usage
-```hcl
resource "consul_acl_policy" "agent" {
name = "agent"
rules = <<-RULE
@@ -26,72 +29,88 @@ resource "consul_acl_policy" "agent" {
resource "consul_acl_token" "test" {
description = "my test token"
- policies = ["${consul_acl_policy.agent.name}"]
- local = true
+ policies = [consul_acl_policy.agent.name]
+ local = true
}
-```
-### Explicitly set the `accessor_id`
+# Explicitly set the `accessor_id`
-```hcl
-resource "random_uuid" "test" { }
+resource "random_uuid" "test" {}
resource "consul_acl_token" "test_predefined_id" {
- accessor_id = ${random_uuid.test_uuid.result}
+ accessor_id = random_uuid.test_uuid.result
description = "my test uuid token"
- policies = ["${consul_acl_policy.agent.name}"]
- local = true
+ policies = [consul_acl_policy.agent.name]
+ local = true
}
```
-## Argument Reference
+
+## Schema
+
+### Optional
+
+- `accessor_id` (String) The uuid of the token. If omitted, Consul will generate a random uuid.
+- `description` (String) The description of the token.
+- `expiration_time` (String) If set this represents the point after which a token should be considered revoked and is eligible for destruction.
+- `local` (Boolean) The flag to set the token local to the current datacenter.
+- `namespace` (String) The namespace to create the token within.
+- `node_identities` (Block List) The list of node identities that should be applied to the token. (see [below for nested schema](#nestedblock--node_identities))
+- `partition` (String) The partition the ACL token is associated with.
+- `policies` (Set of String) The list of policies attached to the token.
+- `roles` (Set of String) The list of roles attached to the token.
+- `service_identities` (Block List) The list of service identities that should be applied to the token. (see [below for nested schema](#nestedblock--service_identities))
+- `templated_policies` (Block List) The list of templated policies that should be applied to the token. (see [below for nested schema](#nestedblock--templated_policies))
+
+### Read-Only
+
+- `id` (String) The ID of this resource.
+
+
+### Nested Schema for `node_identities`
+
+Required:
-The following arguments are supported:
+- `datacenter` (String) The datacenter of the node.
+- `node_name` (String) The name of the node.
-* `accessor_id` - (Optional) The uuid of the token. If omitted, Consul will
- generate a random uuid.
-* `description` - (Optional) The description of the token.
-* `policies` - (Optional) The list of policies attached to the token.
-* `roles` - (Optional) The list of roles attached to the token.
-* `service_identities` - (Optional) The list of service identities that should be applied to the token.
-* `node_identities` - (Optional) The list of node identities that should be applied to the token.
-* `local` - (Optional) The flag to set the token local to the current datacenter.
-* `expiration_time` - (Optional) If set this represents the point after which a token should be considered revoked and is eligible for destruction.
-* `namespace` - (Optional, Enterprise Only) The namespace to create the token within.
-* `partition` - (Optional, Enterprise Only) The partition the ACL token is associated with.
-The `service_identities` block supports the following arguments:
+
+### Nested Schema for `service_identities`
-* `service_name` - (Required) The name of the service.
-* `datacenters` - (Required) The list of datacenters the policy is valid within.
+Required:
-The `node_identities` block supports the following arguments:
+- `service_name` (String) The name of the service.
-* `node_name` - (Optional) The name of the node.
-* `datacenter` - (Optional) The datacenter of the node.
+Optional:
-## Attributes Reference
+- `datacenters` (List of String) Specifies the datacenters the effective policy is valid within.
-The following attributes are exported:
-* `id` - The token accessor ID.
-* `accessor_id` - The token accessor ID.
-* `description` - The description of the token.
-* `policies` - The list of policies attached to the token.
-* `roles` - The list of roles attached to the token.
-* `service_identities` - The list of service identities that should be applied to the token.
-* `node_identities` - The list of node identities that should be applied to the token.
-* `local` - The flag to set the token local to the current datacenter.
-* `expiration_time` - If set this represents the point after which a token should be considered revoked and is eligible for destruction.
-* `namespace` - The namespace to create the token within.
+
+### Nested Schema for `templated_policies`
+Required:
+
+- `template_name` (String) The name of the templated policies.
+
+Optional:
+
+- `datacenters` (List of String) Specifies the datacenters the effective policy is valid within.
+- `template_variables` (Block List, Max: 1) The templated policy variables. (see [below for nested schema](#nestedblock--templated_policies--template_variables))
+
+
+### Nested Schema for `templated_policies.template_variables`
+
+Optional:
+
+- `name` (String) The name of node, workload identity or service.
## Import
-`consul_acl_token` can be imported. This is especially useful to manage the
-anonymous and the master token with Terraform:
+Import is supported using the following syntax:
-```
-$ terraform import consul_acl_token.anonymous 00000000-0000-0000-0000-000000000002
-$ terraform import consul_acl_token.master-token 624d94ca-bc5c-f960-4e83-0a609cf588be
+```shell
+terraform import consul_acl_token.anonymous 00000000-0000-0000-0000-000000000002
+terraform import consul_acl_token.master-token 624d94ca-bc5c-f960-4e83-0a609cf588be
```
diff --git a/docs/resources/config_entry_service_splitter.md b/docs/resources/config_entry_service_splitter.md
index 7ebe7314..1da77b2a 100644
--- a/docs/resources/config_entry_service_splitter.md
+++ b/docs/resources/config_entry_service_splitter.md
@@ -44,7 +44,7 @@ resource "consul_config_entry" "service_resolver" {
}
resource "consul_config_entry_service_splitter" "foo" {
- name = consul_config_entry.service_resolver.name
+ name = consul_config_entry.service_resolver.name
meta = {
key = "value"
diff --git a/examples/data-sources/consul_acl_role/data-source.tf b/examples/data-sources/consul_acl_role/data-source.tf
new file mode 100644
index 00000000..392b6ae8
--- /dev/null
+++ b/examples/data-sources/consul_acl_role/data-source.tf
@@ -0,0 +1,7 @@
+data "consul_acl_role" "test" {
+ name = "example-role"
+}
+
+output "consul_acl_role" {
+ value = data.consul_acl_role.test.id
+}
diff --git a/examples/data-sources/consul_acl_token/data-source.tf b/examples/data-sources/consul_acl_token/data-source.tf
new file mode 100644
index 00000000..3cd8fdd7
--- /dev/null
+++ b/examples/data-sources/consul_acl_token/data-source.tf
@@ -0,0 +1,7 @@
+data "consul_acl_token" "test" {
+ accessor_id = "00000000-0000-0000-0000-000000000002"
+}
+
+output "consul_acl_policies" {
+ value = data.consul_acl_token.test.policies
+}
diff --git a/examples/resources/consul_acl_binding_rule/resource.tf b/examples/resources/consul_acl_binding_rule/resource.tf
new file mode 100644
index 00000000..25cd3bcc
--- /dev/null
+++ b/examples/resources/consul_acl_binding_rule/resource.tf
@@ -0,0 +1,19 @@
+resource "consul_acl_auth_method" "minikube" {
+ name = "minikube"
+ type = "kubernetes"
+ description = "dev minikube cluster"
+
+ config = {
+ Host = "https://192.0.2.42:8443"
+ CACert = "-----BEGIN CERTIFICATE-----\n...-----END CERTIFICATE-----\n"
+ ServiceAccountJWT = "eyJhbGciOiJSUzI1NiIsImtpZCI6IiJ9..."
+ }
+}
+
+resource "consul_acl_binding_rule" "test" {
+ auth_method = consul_acl_auth_method.minikube.name
+ description = "foobar"
+ selector = "serviceaccount.namespace==default"
+ bind_type = "service"
+ bind_name = "minikube"
+}
diff --git a/examples/resources/consul_acl_role/import.sh b/examples/resources/consul_acl_role/import.sh
new file mode 100644
index 00000000..d99e86c6
--- /dev/null
+++ b/examples/resources/consul_acl_role/import.sh
@@ -0,0 +1 @@
+terraform import consul_acl_role.read 816a195f-6cb1-2e8d-92af-3011ae706318
diff --git a/examples/resources/consul_acl_role/resource.tf b/examples/resources/consul_acl_role/resource.tf
new file mode 100644
index 00000000..9a3c140a
--- /dev/null
+++ b/examples/resources/consul_acl_role/resource.tf
@@ -0,0 +1,18 @@
+resource "consul_acl_policy" "read-policy" {
+ name = "read-policy"
+ rules = "node \"\" { policy = \"read\" }"
+ datacenters = ["dc1"]
+}
+
+resource "consul_acl_role" "read" {
+ name = "foo"
+ description = "bar"
+
+ policies = [
+ consul_acl_policy.read-policy.id
+ ]
+
+ service_identities {
+ service_name = "foo"
+ }
+}
diff --git a/examples/resources/consul_acl_role_policy_attachment/import.sh b/examples/resources/consul_acl_role_policy_attachment/import.sh
new file mode 100644
index 00000000..2d8bb620
--- /dev/null
+++ b/examples/resources/consul_acl_role_policy_attachment/import.sh
@@ -0,0 +1 @@
+terraform import consul_acl_role_policy_attachment.my_role_read_policy 624d94ca-bc5c-f960-4e83-0a609cf588be:policy_name
diff --git a/examples/resources/consul_acl_role_policy_attachment/resource.tf b/examples/resources/consul_acl_role_policy_attachment/resource.tf
new file mode 100644
index 00000000..57922ebc
--- /dev/null
+++ b/examples/resources/consul_acl_role_policy_attachment/resource.tf
@@ -0,0 +1,14 @@
+data "consul_acl_role" "my_role" {
+ name = "my_role"
+}
+
+resource "consul_acl_policy" "read_policy" {
+ name = "read-policy"
+ rules = "node \"\" { policy = \"read\" }"
+ datacenters = ["dc1"]
+}
+
+resource "consul_acl_role_policy_attachment" "my_role_read_policy" {
+ role_id = data.consul_acl_role.test.id
+ policy = consul_acl_policy.read_policy.name
+}
diff --git a/examples/resources/consul_acl_token/import.sh b/examples/resources/consul_acl_token/import.sh
new file mode 100644
index 00000000..6801ef68
--- /dev/null
+++ b/examples/resources/consul_acl_token/import.sh
@@ -0,0 +1,2 @@
+terraform import consul_acl_token.anonymous 00000000-0000-0000-0000-000000000002
+terraform import consul_acl_token.master-token 624d94ca-bc5c-f960-4e83-0a609cf588be
diff --git a/examples/resources/consul_acl_token/resource.tf b/examples/resources/consul_acl_token/resource.tf
new file mode 100644
index 00000000..93615b1b
--- /dev/null
+++ b/examples/resources/consul_acl_token/resource.tf
@@ -0,0 +1,27 @@
+# Basic usage
+
+resource "consul_acl_policy" "agent" {
+ name = "agent"
+ rules = <<-RULE
+ node_prefix "" {
+ policy = "read"
+ }
+ RULE
+}
+
+resource "consul_acl_token" "test" {
+ description = "my test token"
+ policies = [consul_acl_policy.agent.name]
+ local = true
+}
+
+# Explicitly set the `accessor_id`
+
+resource "random_uuid" "test" {}
+
+resource "consul_acl_token" "test_predefined_id" {
+ accessor_id = random_uuid.test_uuid.result
+ description = "my test uuid token"
+ policies = [consul_acl_policy.agent.name]
+ local = true
+}
diff --git a/examples/resources/consul_config_entry_service_splitter/resource.tf b/examples/resources/consul_config_entry_service_splitter/resource.tf
index a8541fc2..ff41c299 100644
--- a/examples/resources/consul_config_entry_service_splitter/resource.tf
+++ b/examples/resources/consul_config_entry_service_splitter/resource.tf
@@ -29,7 +29,7 @@ resource "consul_config_entry" "service_resolver" {
}
resource "consul_config_entry_service_splitter" "foo" {
- name = consul_config_entry.service_resolver.name
+ name = consul_config_entry.service_resolver.name
meta = {
key = "value"
diff --git a/go.mod b/go.mod
index b48e012d..f8e91511 100644
--- a/go.mod
+++ b/go.mod
@@ -1,18 +1,19 @@
module github.com/hashicorp/terraform-provider-consul
require (
- github.com/hashicorp/consul/api v1.23.0
+ github.com/hashicorp/consul/api v1.26.1-rc1
github.com/hashicorp/errwrap v1.1.0
github.com/hashicorp/terraform-plugin-sdk v1.17.2
github.com/mitchellh/mapstructure v1.5.0
+ golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63
)
require (
cloud.google.com/go/compute v1.18.0 // indirect
cloud.google.com/go/compute/metadata v0.2.3 // indirect
cloud.google.com/go/iam v0.12.0 // indirect
+ github.com/armon/go-metrics v0.4.1 // indirect
github.com/googleapis/enterprise-certificate-proxy v0.2.3 // indirect
- golang.org/x/exp v0.0.0-20230321023759-10a507213a29 // indirect
)
require (
@@ -25,7 +26,6 @@ require (
github.com/apparentlymart/go-cidr v1.1.0 // indirect
github.com/apparentlymart/go-textseg/v12 v12.0.0 // indirect
github.com/apparentlymart/go-textseg/v13 v13.0.0 // indirect
- github.com/armon/go-metrics v0.4.1 // indirect
github.com/armon/go-radix v1.0.0 // indirect
github.com/aws/aws-sdk-go v1.44.122 // indirect
github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d // indirect
@@ -39,7 +39,7 @@ require (
github.com/google/go-cmp v0.5.9 // indirect
github.com/google/uuid v1.3.0 // indirect
github.com/googleapis/gax-go/v2 v2.7.1 // indirect
- github.com/hashicorp/consul/sdk v0.14.0
+ github.com/hashicorp/consul/sdk v0.14.3-rc1
github.com/hashicorp/go-checkpoint v0.5.0 // indirect
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
github.com/hashicorp/go-getter v1.7.0 // indirect
@@ -50,7 +50,7 @@ require (
github.com/hashicorp/go-rootcerts v1.0.2 // indirect
github.com/hashicorp/go-safetemp v1.0.0 // indirect
github.com/hashicorp/go-uuid v1.0.3 // indirect
- github.com/hashicorp/go-version v1.6.0 // indirect
+ github.com/hashicorp/go-version v1.6.0
github.com/hashicorp/golang-lru v0.5.4 // indirect
github.com/hashicorp/hcl v1.0.0 // indirect
github.com/hashicorp/hcl/v2 v2.8.2 // indirect
@@ -88,9 +88,9 @@ require (
github.com/zclconf/go-cty-yaml v1.0.2 // indirect
go.opencensus.io v0.24.0 // indirect
golang.org/x/crypto v0.11.0 // indirect
- golang.org/x/net v0.12.0 // indirect
+ golang.org/x/net v0.13.0 // indirect
golang.org/x/oauth2 v0.6.0 // indirect
- golang.org/x/sys v0.10.0 // indirect
+ golang.org/x/sys v0.11.0 // indirect
golang.org/x/text v0.11.0 // indirect
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect
google.golang.org/api v0.114.0 // indirect
diff --git a/go.sum b/go.sum
index 6becda55..16cc8cc0 100644
--- a/go.sum
+++ b/go.sum
@@ -409,10 +409,10 @@ github.com/googleapis/gax-go/v2 v2.7.1 h1:gF4c0zjUP2H/s/hEGyLA3I0fA2ZWjzYiONAD6c
github.com/googleapis/gax-go/v2 v2.7.1/go.mod h1:4orTrqY6hXxxaUL4LHIPl6lGo8vAE38/qKbhSAKP6QI=
github.com/googleapis/go-type-adapters v1.0.0/go.mod h1:zHW75FOG2aur7gAO2B+MLby+cLsWGBF62rFAi7WjWO4=
github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw=
-github.com/hashicorp/consul/api v1.23.0 h1:L6e4v1AfoumqAHq/Rrsmuulev+nd7vltM3k8H329tyI=
-github.com/hashicorp/consul/api v1.23.0/go.mod h1:SfvUIT74b0EplDuNgAJQ/FVqSO6KyK2ia80UI39/Ye8=
-github.com/hashicorp/consul/sdk v0.14.0 h1:Hly+BMNMssVzoWddbBnBFi3W+Fzytvm0haSkihhj3GU=
-github.com/hashicorp/consul/sdk v0.14.0/go.mod h1:gHYeuDa0+0qRAD6Wwr6yznMBvBwHKoxSBoW5l73+saE=
+github.com/hashicorp/consul/api v1.26.1-rc1 h1:eO+53vwWxEV2TMbTVrJbXp2TJjJNv+Nxij8j+xi3yOc=
+github.com/hashicorp/consul/api v1.26.1-rc1/go.mod h1:ZKnaWXL2r23i+SPmEj1H5YsRNUS/uUzB2uhmD2QY4IY=
+github.com/hashicorp/consul/sdk v0.14.3-rc1 h1:kE0dLXXTnvm67PNRE527XpSwqi5vwWoP+VkNHdBBR7o=
+github.com/hashicorp/consul/sdk v0.14.3-rc1/go.mod h1:vFt03juSzocLRFo59NkeQHHmQa6+g7oU0pfzdI1mUhg=
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I=
github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
@@ -720,8 +720,8 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0
golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
-golang.org/x/exp v0.0.0-20230321023759-10a507213a29 h1:ooxPy7fPvB4kwsA2h+iBNHkAbp/4JxTSwCmvdjEYmug=
-golang.org/x/exp v0.0.0-20230321023759-10a507213a29/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc=
+golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63 h1:m64FZMko/V45gv0bNmrNYoDEq8U5YUhetc9cBWKS1TQ=
+golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63/go.mod h1:0v4NqG35kSWCMzLaMeX+IQrlSnVE/bqGSyC2cz/9Le8=
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
@@ -803,8 +803,8 @@ golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug
golang.org/x/net v0.0.0-20220909164309-bea034e7d591/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk=
golang.org/x/net v0.0.0-20221014081412-f15817d10f9b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk=
golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco=
-golang.org/x/net v0.12.0 h1:cfawfvKITfUsFCeJIHJrbSxpeu/E81khclypR0GVT50=
-golang.org/x/net v0.12.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA=
+golang.org/x/net v0.13.0 h1:Nvo8UFsZ8X3BhAC9699Z1j7XQ3rsZnUUm7jfBEk1ueY=
+golang.org/x/net v0.13.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
@@ -924,8 +924,8 @@ golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.10.0 h1:SqMFp9UcQJZa+pmYuAKjd9xq1f0j5rLcDIk0mj4qAsA=
-golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.11.0 h1:eG7RXZHdqOJ1i+0lgLgCpSXAp6M3LYlAo6osgSi0xOM=
+golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
diff --git a/templates/data-sources/acl_role.md b/templates/data-sources/acl_role.md
deleted file mode 100644
index d2373ec0..00000000
--- a/templates/data-sources/acl_role.md
+++ /dev/null
@@ -1,44 +0,0 @@
----
-layout: "consul"
-page_title: "Consul: consul_acl_role"
-sidebar_current: "docs-consul-data-source-acl-role"
-description: |-
- Provides information about a Consul ACL Role.
----
-
-# consul_acl_role
-
-The `consul_acl_role` data source returns the information related to a
-[Consul ACL Role](https://www.consul.io/api/acl/roles.html).
-
-## Example Usage
-
-```hcl
-data "consul_acl_role" "test" {
- name = "example-role"
-}
-
-output "consul_acl_role" {
- value = data.consul_acl_role.test.id
-}
-```
-
-
-## Argument Reference
-
-The following arguments are supported:
-
-* `name` - (Required) The name of the ACL Role.
-* `namespace` - (Optional, Enterprise Only) The namespace to lookup the role.
-* `partition` - (Optional, Enterprise Only) The partition to lookup the role.
-
-## Attributes Reference
-
-The following attributes are exported:
-
-* `name` - The name of the ACL Role.
-* `namespace` - The namespace to lookup the role.
-* `description` - The description of the ACL Role.
-* `policies` - The list of policies associated with the ACL Role. Each entry has an `id` and a `name` attribute.
-* `service_identities` - The list of service identities associated with the ACL Role. Each entry has a `service_name` attribute and a list of `datacenters`.
-* `node_identities` - The list of node identities associated with the ACL Role. Each entry has a `node_name` and a `datacenter` attributes.
diff --git a/templates/data-sources/acl_token.md b/templates/data-sources/acl_token.md
deleted file mode 100644
index 8e62605b..00000000
--- a/templates/data-sources/acl_token.md
+++ /dev/null
@@ -1,48 +0,0 @@
----
-layout: "consul"
-page_title: "Consul: consul_acl_token"
-sidebar_current: "docs-consul-data-source-acl-token"
-description: |-
- Provides information about a Consul ACL Token.
----
-
-# consul_acl_token
-
-The `consul_acl_token` data source returns the information related to the
-`consul_acl_token` resource with the exception of its secret ID.
-
-If you want to get the secret ID associated with a token, use the
-[`consul_acl_token_secret_id` data source](/docs/providers/consul/d/acl_token_secret_id.html).
-
-## Example Usage
-
-```hcl
-data "consul_acl_token" "test" {
- accessor_id = "00000000-0000-0000-0000-000000000002"
-}
-
-output "consul_acl_policies" {
- value = "${data.consul_acl_token.test.policies}"
-}
-```
-
-
-## Argument Reference
-
-The following arguments are supported:
-
-* `accessor_id` - (Required) The accessor ID of the ACL token.
-* `namespace` - (Optional, Enterprise Only) The namespace to lookup the ACL token.
-* `partition` - (Optional, Enterprise Only) The partition to lookup the ACL token.
-
-## Attributes Reference
-
-The following attributes are exported:
-
-* `description` - The description of the ACL token.
-* `policies` - A list of policies associated with the ACL token. Each entry has an `id` and a `name` attribute.
-* `roles` - The list of roles attached to the token.
-* `service_identities` - The list of service identities attached to the token. Each entry has a `service_name` and a `datacenters` attribute.
-* `node_identities` - The list of node identities attached to the token. Each entry has a `node_name` and a `datacenter` attributes.
-* `local` - Whether the ACL token is local to the datacenter it was created within.
-* `expiration_time` - If set this represents the point after which a token should be considered revoked and is eligible for destruction.
diff --git a/templates/resources/acl_binding_rule.md b/templates/resources/acl_binding_rule.md
deleted file mode 100644
index 8bb8c0c8..00000000
--- a/templates/resources/acl_binding_rule.md
+++ /dev/null
@@ -1,64 +0,0 @@
----
-layout: "consul"
-page_title: "Consul: consul_acl_binding_rule"
-sidebar_current: "docs-consul-resource-acl-binding-rule"
-description: |-
- Allows Terraform to create an ACL binding rule
----
-
-# consul_acl_binding_rule
-
-Starting with Consul 1.5.0, the consul_acl_binding_rule resource can be used to
-managed Consul ACL binding rules.
-
-
-## Example Usage
-
-```hcl
-resource "consul_acl_auth_method" "minikube" {
- name = "minikube"
- type = "kubernetes"
- description = "dev minikube cluster"
-
- config = {
- Host = "https://192.0.2.42:8443"
- CACert = "-----BEGIN CERTIFICATE-----\n...-----END CERTIFICATE-----\n"
- ServiceAccountJWT = "eyJhbGciOiJSUzI1NiIsImtpZCI6IiJ9..."
- }
-}
-
-resource "consul_acl_binding_rule" "test" {
- auth_method = "${consul_acl_auth_method.minikube.name}"
- description = "foobar"
- selector = "serviceaccount.namespace==default"
- bind_type = "service"
- bind_name = "minikube"
-}
-```
-
-## Argument Reference
-
-The following arguments are supported:
-
-* `auth_method` - (Required) The name of the ACL auth method this rule apply.
-* `description` - (Optional) A free form human readable description of the binding rule.
-* `selector` - (Optional) The expression used to math this rule against valid identities returned from an auth method validation.
-* `bind_type` - (Required) Specifies the way the binding rule affects a token created at login.
-* `bind_name` - (Required) The name to bind to a token at login-time.
-* `namespace` - (Optional, Enterprise Only) The namespace to create the binding rule within.
-* `partition` - (Optional, Enterprise Only) The partition the ACL binding rule is associated with.
-
-
-## Attributes Reference
-
-The following attributes are exported:
-
-* `id` - The ID of the the binding rule.
-* `auth_method` - The name of the ACL auth method this rule apply.
-* `description` - A free form human readable description of the
-binding rule.
-* `selector` - The expression used to math this rule against valid
-identities returned from an auth method validation.
-* `bind_type` - Specifies the way the binding rule affects a token
-created at login.
-* `bind_name` - The name to bind to a token at login-time.
diff --git a/templates/resources/acl_role.md b/templates/resources/acl_role.md
deleted file mode 100644
index 11dd8ff6..00000000
--- a/templates/resources/acl_role.md
+++ /dev/null
@@ -1,78 +0,0 @@
----
-layout: "consul"
-page_title: "Consul: consul_acl_role"
-sidebar_current: "docs-consul-resource-acl-role"
-description: |-
- Allows Terraform to create an ACL role
----
-
-# consul_acl_role
-
-Starting with Consul 1.5.0, the consul_acl_role can be used to managed Consul ACL roles.
-
-
-## Example Usage
-
-```hcl
-resource "consul_acl_policy" "read-policy" {
- name = "read-policy"
- rules = "node \"\" { policy = \"read\" }"
- datacenters = [ "dc1" ]
-}
-
-resource "consul_acl_role" "read" {
- name = "foo"
- description = "bar"
-
- policies = [
- "${consul_acl_policy.read-policy.id}"
- ]
-
- service_identities {
- service_name = "foo"
- }
-}
-```
-
-## Argument Reference
-
-The following arguments are supported:
-
-* `name` - (Required) The name of the ACL role.
-* `description` - (Optional) A free form human readable description of the role.
-* `policies` - (Optional) The list of policies that should be applied to the role.
-* `service_identities` - (Optional) The list of service identities that should be applied to the role.
-* `node_identities` - (Optional) The list of node identities that should be applied to the role.
-* `namespace` - (Optional, Enterprise Only) The namespace to create the role within.
-* `partition` - (Optional, Enterprise Only) The partition the ACL role is associated with.
-
-The `service_identities` block supports:
-
-* `service_name` - (Required) The name of the service.
-* `datacenters` - (Optional) The datacenters the effective policy is valid within.
-
-The `node_identities` block supports:
-
-* `node_name` - (Required) The name of the node.
-* `datacenter` - (Required) The datacenter of the node.
-
-## Attributes Reference
-
-The following attributes are exported:
-
-* `id` - The ID of the role.
-* `name` - The name of the ACL role.
-* `description` - A free form human readable description of the role.
-* `policies` - The list of policies that should be applied to the role.
-* `service_identities` - The list of service identities that should be applied to the role.
-* `node_identities` - The list of node identities that should be applied to the role.
-* `namespace` - The namespace to create the role within.
-
-
-## Import
-
-`consul_acl_role` can be imported:
-
-```
-$ terraform import consul_acl_role.read 816a195f-6cb1-2e8d-92af-3011ae706318
-```
diff --git a/templates/resources/acl_token.md b/templates/resources/acl_token.md
deleted file mode 100644
index b65cb94f..00000000
--- a/templates/resources/acl_token.md
+++ /dev/null
@@ -1,97 +0,0 @@
----
-layout: "consul"
-page_title: "Consul: consul_acl_token"
-sidebar_current: "docs-consul-resource-acl-token"
-description: |-
- Allows Terraform to create an ACL token
----
-
-# consul_acl_token
-
-The `consul_acl_token` resource writes an ACL token into Consul.
-
-## Example Usage
-
-### Basic usage
-
-```hcl
-resource "consul_acl_policy" "agent" {
- name = "agent"
- rules = <<-RULE
- node_prefix "" {
- policy = "read"
- }
- RULE
-}
-
-resource "consul_acl_token" "test" {
- description = "my test token"
- policies = ["${consul_acl_policy.agent.name}"]
- local = true
-}
-```
-
-### Explicitly set the `accessor_id`
-
-```hcl
-resource "random_uuid" "test" { }
-
-resource "consul_acl_token" "test_predefined_id" {
- accessor_id = ${random_uuid.test_uuid.result}
- description = "my test uuid token"
- policies = ["${consul_acl_policy.agent.name}"]
- local = true
-}
-```
-
-## Argument Reference
-
-The following arguments are supported:
-
-* `accessor_id` - (Optional) The uuid of the token. If omitted, Consul will
- generate a random uuid.
-* `description` - (Optional) The description of the token.
-* `policies` - (Optional) The list of policies attached to the token.
-* `roles` - (Optional) The list of roles attached to the token.
-* `service_identities` - (Optional) The list of service identities that should be applied to the token.
-* `node_identities` - (Optional) The list of node identities that should be applied to the token.
-* `local` - (Optional) The flag to set the token local to the current datacenter.
-* `expiration_time` - (Optional) If set this represents the point after which a token should be considered revoked and is eligible for destruction.
-* `namespace` - (Optional, Enterprise Only) The namespace to create the token within.
-* `partition` - (Optional, Enterprise Only) The partition the ACL token is associated with.
-
-The `service_identities` block supports the following arguments:
-
-* `service_name` - (Required) The name of the service.
-* `datacenters` - (Required) The list of datacenters the policy is valid within.
-
-The `node_identities` block supports the following arguments:
-
-* `node_name` - (Optional) The name of the node.
-* `datacenter` - (Optional) The datacenter of the node.
-
-## Attributes Reference
-
-The following attributes are exported:
-
-* `id` - The token accessor ID.
-* `accessor_id` - The token accessor ID.
-* `description` - The description of the token.
-* `policies` - The list of policies attached to the token.
-* `roles` - The list of roles attached to the token.
-* `service_identities` - The list of service identities that should be applied to the token.
-* `node_identities` - The list of node identities that should be applied to the token.
-* `local` - The flag to set the token local to the current datacenter.
-* `expiration_time` - If set this represents the point after which a token should be considered revoked and is eligible for destruction.
-* `namespace` - The namespace to create the token within.
-
-
-## Import
-
-`consul_acl_token` can be imported. This is especially useful to manage the
-anonymous and the master token with Terraform:
-
-```
-$ terraform import consul_acl_token.anonymous 00000000-0000-0000-0000-000000000002
-$ terraform import consul_acl_token.master-token 624d94ca-bc5c-f960-4e83-0a609cf588be
-```