-
Notifications
You must be signed in to change notification settings - Fork 387
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #122 from hryamzik/integrations
datadog_integration_aws
- Loading branch information
Showing
4 changed files
with
298 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,211 @@ | ||
package datadog | ||
|
||
import ( | ||
"fmt" | ||
"os" | ||
"strings" | ||
|
||
"github.com/hashicorp/terraform/helper/schema" | ||
"github.com/zorkian/go-datadog-api" | ||
) | ||
|
||
func accountAndRoleFromID(id string) (string, string) { | ||
result := strings.SplitN(id, ":", 2) | ||
return result[0], result[1] | ||
} | ||
|
||
func resourceDatadogIntegrationAws() *schema.Resource { | ||
return &schema.Resource{ | ||
Create: resourceDatadogIntegrationAwsCreate, | ||
Read: resourceDatadogIntegrationAwsRead, | ||
Update: resourceDatadogIntegrationAwsUpdate, | ||
Delete: resourceDatadogIntegrationAwsDelete, | ||
Exists: resourceDatadogIntegrationAwsExists, | ||
Importer: &schema.ResourceImporter{ | ||
State: resourceDatadogIntegrationAwsImport, | ||
}, | ||
|
||
Schema: map[string]*schema.Schema{ | ||
"account_id": { | ||
Type: schema.TypeString, | ||
Required: true, | ||
}, | ||
"role_name": { | ||
Type: schema.TypeString, | ||
Required: true, | ||
ForceNew: true, // waits for update API call support | ||
}, | ||
"filter_tags": { | ||
Type: schema.TypeList, | ||
Optional: true, | ||
Elem: &schema.Schema{Type: schema.TypeString}, | ||
ForceNew: true, // waits for update API call support | ||
}, | ||
"host_tags": { | ||
Type: schema.TypeList, | ||
Optional: true, | ||
Elem: &schema.Schema{Type: schema.TypeString}, | ||
ForceNew: true, // waits for update API call support | ||
}, | ||
"account_specific_namespace_rules": { | ||
Type: schema.TypeMap, | ||
Optional: true, | ||
Elem: schema.TypeBool, | ||
ForceNew: true, // waits for update API call support | ||
}, | ||
"external_id": { | ||
Type: schema.TypeString, | ||
Computed: true, | ||
}, | ||
}, | ||
} | ||
} | ||
|
||
func resourceDatadogIntegrationAwsExists(d *schema.ResourceData, meta interface{}) (b bool, e error) { | ||
// Exists - This is called to verify a resource still exists. It is called prior to Read, | ||
// and lowers the burden of Read to be able to assume the resource exists. | ||
client := meta.(*datadog.Client) | ||
|
||
integrations, err := client.GetIntegrationAWS() | ||
if err != nil { | ||
return false, err | ||
} | ||
accountID, roleName := accountAndRoleFromID(d.Id()) | ||
for _, integration := range *integrations { | ||
if integration.GetAccountID() == accountID && integration.GetRoleName() == roleName { | ||
return true, nil | ||
} | ||
} | ||
return false, nil | ||
} | ||
|
||
func resourceDatadogIntegrationAwsPrepareCreateRequest(d *schema.ResourceData, accountID string, roleName string) datadog.IntegrationAWSAccount { | ||
|
||
iaws := datadog.IntegrationAWSAccount{ | ||
AccountID: datadog.String(accountID), | ||
RoleName: datadog.String(roleName), | ||
} | ||
|
||
filterTags := []string{} | ||
|
||
if attr, ok := d.GetOk("filter_tags"); ok { | ||
for _, s := range attr.([]interface{}) { | ||
filterTags = append(filterTags, s.(string)) | ||
} | ||
} | ||
|
||
hostTags := []string{} | ||
|
||
if attr, ok := d.GetOk("host_tags"); ok { | ||
for _, s := range attr.([]interface{}) { | ||
hostTags = append(hostTags, s.(string)) | ||
} | ||
} | ||
|
||
accountSpecificNamespaceRules := make(map[string]bool) | ||
|
||
if attr, ok := d.GetOk("account_specific_namespace_rules"); ok { | ||
// TODO: this is not very defensive, test if we can fail on non bool input | ||
for k, v := range attr.(map[string]interface{}) { | ||
accountSpecificNamespaceRules[k] = v.(bool) | ||
} | ||
} | ||
iaws.FilterTags = filterTags | ||
iaws.HostTags = hostTags | ||
iaws.AccountSpecificNamespaceRules = accountSpecificNamespaceRules | ||
return iaws | ||
} | ||
|
||
func resourceDatadogIntegrationAwsCreate(d *schema.ResourceData, meta interface{}) error { | ||
client := meta.(*datadog.Client) | ||
|
||
accountID := d.Get("account_id").(string) | ||
roleName := d.Get("role_name").(string) | ||
|
||
iaws := resourceDatadogIntegrationAwsPrepareCreateRequest(d, accountID, roleName) | ||
response, err := client.CreateIntegrationAWS(&iaws) | ||
|
||
if err != nil { | ||
return fmt.Errorf("error creating a Amazon Web Services integration: %s", err.Error()) | ||
} | ||
|
||
d.SetId(fmt.Sprintf("%s:%s", accountID, roleName)) | ||
d.Set("external_id", response.ExternalID) | ||
|
||
return resourceDatadogIntegrationAwsRead(d, meta) | ||
} | ||
|
||
func resourceDatadogIntegrationAwsRead(d *schema.ResourceData, meta interface{}) error { | ||
client := meta.(*datadog.Client) | ||
|
||
accountID, roleName := accountAndRoleFromID(d.Id()) | ||
|
||
integrations, err := client.GetIntegrationAWS() | ||
if err != nil { | ||
return err | ||
} | ||
for _, integration := range *integrations { | ||
if integration.GetAccountID() == accountID && integration.GetRoleName() == roleName { | ||
d.Set("account_id", integration.GetAccountID()) | ||
d.Set("role_name", integration.GetRoleName()) | ||
d.Set("filter_tags", integration.FilterTags) | ||
d.Set("host_tags", integration.HostTags) | ||
d.Set("account_specific_namespace_rules", integration.AccountSpecificNamespaceRules) | ||
return nil | ||
} | ||
} | ||
return fmt.Errorf("error getting a Amazon Web Services integration: account_id=%s, role_name=%s", accountID, roleName) | ||
} | ||
|
||
func resourceDatadogIntegrationAwsUpdate(d *schema.ResourceData, meta interface{}) error { | ||
// Unfortunately the PUT operation for updating the AWS configuration is not available at the moment. | ||
// However this feature is one we have in our backlog. I don't know if it's scheduled for delivery short-term, | ||
// however I will follow-up after reviewing with product management. | ||
// © | ||
|
||
// UpdateIntegrationAWS function: | ||
// func (client *Client) UpdateIntegrationAWS(awsAccount *IntegrationAWSAccount) (*IntegrationAWSAccountCreateResponse, error) { | ||
// var out IntegrationAWSAccountCreateResponse | ||
// if err := client.doJsonRequest("PUT", "/v1/integration/aws", awsAccount, &out); err != nil { | ||
// return nil, err | ||
// } | ||
// return &out, nil | ||
// } | ||
|
||
client := meta.(*datadog.Client) | ||
|
||
accountID, roleName := accountAndRoleFromID(d.Id()) | ||
|
||
iaws := resourceDatadogIntegrationAwsPrepareCreateRequest(d, accountID, roleName) | ||
|
||
_, err := client.CreateIntegrationAWS(&iaws) | ||
if err != nil { | ||
return fmt.Errorf("error updating a Amazon Web Services integration: %s", err.Error()) | ||
} | ||
|
||
return resourceDatadogIntegrationAwsRead(d, meta) | ||
} | ||
|
||
func resourceDatadogIntegrationAwsDelete(d *schema.ResourceData, meta interface{}) error { | ||
client := meta.(*datadog.Client) | ||
accountID, roleName := accountAndRoleFromID(d.Id()) | ||
|
||
if err := client.DeleteIntegrationAWS( | ||
&datadog.IntegrationAWSAccountDeleteRequest{ | ||
AccountID: datadog.String(accountID), | ||
RoleName: datadog.String(roleName), | ||
}, | ||
); err != nil { | ||
return fmt.Errorf("error deleting a Amazon Web Services integration: %s", err.Error()) | ||
} | ||
|
||
return nil | ||
} | ||
|
||
func resourceDatadogIntegrationAwsImport(d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) { | ||
if err := resourceDatadogIntegrationAwsRead(d, meta); err != nil { | ||
return nil, err | ||
} | ||
d.Set("external_id", os.Getenv("EXTERNAL_ID")) | ||
return []*schema.ResourceData{d}, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
package datadog | ||
|
||
import ( | ||
"testing" | ||
) | ||
|
||
func TestAccountAndRoleFromID(t *testing.T) { | ||
cases := map[string]struct { | ||
id string | ||
accountID string | ||
roleName string | ||
}{ | ||
"basic": {"1234:qwe", "1234", "qwe"}, | ||
"underscores": {"1234:qwe_rty_asd", "1234", "qwe_rty_asd"}, | ||
} | ||
for name, tc := range cases { | ||
accountID, roleName := accountAndRoleFromID(tc.id) | ||
if accountID != tc.accountID { | ||
t.Errorf("%s: account ID '%s' didn't match `%s`", name, accountID, tc.accountID) | ||
} | ||
if roleName != tc.roleName { | ||
t.Errorf("%s: role name '%s' didn't match `%s`", name, roleName, tc.roleName) | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
--- | ||
layout: "datadog" | ||
page_title: "Datadog: datadog_integration_aws" | ||
sidebar_current: "docs-datadog-resource-integration_aws" | ||
description: |- | ||
Provides a Datadog - Amazon Web Services integration resource. This can be used to create and manage the integrations. | ||
--- | ||
|
||
# datadog_integration_aws | ||
|
||
Provides a Datadog - Amazon Web Services integration resource. This can be used to create and manage Datadog - Amazon Web Services integration. | ||
|
||
Update operations are currently not supported with datadog API so any change forces a new resource. | ||
|
||
## Example Usage | ||
|
||
```hcl | ||
# Create a new Datadog - Amazon Web Services integration | ||
resource "datadog_integration_aws" "sandbox" { | ||
account_id = "1234567890" | ||
role_name = "DatadogAWSIntegrationRole" | ||
filter_tags = ["key:value"] | ||
host_tags = ["key:value", "key2:value2"] | ||
account_specific_namespace_rules = { | ||
"auto_scaling" = false | ||
"opsworks" = false | ||
} | ||
} | ||
``` | ||
|
||
## Argument Reference | ||
|
||
The following arguments are supported: | ||
|
||
* `account_id` - (Required) Your AWS Account ID without dashes. | ||
* `role_name` - (Required) Your Datadog role delegation name. | ||
* `filter_tags` - (Optional) Array of EC2 tags (in the form `key:value`) defines a filter that Datadog use when collecting metrics from EC2. Wildcards, such as `?` (for single characters) and `*` (for multiple characters) can also be used. | ||
|
||
Only hosts that match one of the defined tags will be imported into Datadog. The rest will be ignored. Host matching a given tag can also be excluded by adding `!` before the tag. | ||
|
||
e.x. `env:production,instance-type:c1.*,!region:us-east-1` | ||
|
||
* `host_tags` - (Optinal) Array of tags (in the form key:value) to add to all hosts and metrics reporting through this integration. | ||
* `account_specific_namespace_rules` - (Optinal) Enables or disables metric collection for specific AWS namespaces for this AWS account only. A list of namespaces can be found at the [available namespace rules API endpoint](https://api.datadoghq.com/api/v1/integration/aws/available_namespace_rules). | ||
|
||
### See also | ||
* [Datadog API Reference > Integrations > AWS](https://docs.datadoghq.com/api/?lang=bash#aws) | ||
|
||
## Attributes Reference | ||
|
||
The following attributes are exported: | ||
|
||
* `external_id` - AWS External ID | ||
|
||
## Import | ||
|
||
Amazon Web Services integrations can be imported using their `account ID` and `role name` separated with a colon (`:`), while the `external_id` should be passed by setting an environment variable called `EXTERNAL_ID` | ||
|
||
``` | ||
$ EXTERNAL_ID=${external_id} terraform import datadog_integration_aws.test ${account_id}:${role_name} | ||
``` |