diff --git a/aws/provider.go b/aws/provider.go index d6ea3587f19..267cabf98c5 100644 --- a/aws/provider.go +++ b/aws/provider.go @@ -592,6 +592,7 @@ func Provider() terraform.ResourceProvider { "aws_elastic_beanstalk_environment": resourceAwsElasticBeanstalkEnvironment(), "aws_elasticsearch_domain": resourceAwsElasticSearchDomain(), "aws_elasticsearch_domain_policy": resourceAwsElasticSearchDomainPolicy(), + "aws_elasticsearch_package": resourceAwsElasticsearchPackage(), "aws_elastictranscoder_pipeline": resourceAwsElasticTranscoderPipeline(), "aws_elastictranscoder_preset": resourceAwsElasticTranscoderPreset(), "aws_elb": resourceAwsElb(), diff --git a/aws/resource_aws_elasticsearch_package.go b/aws/resource_aws_elasticsearch_package.go new file mode 100644 index 00000000000..1f891925ffc --- /dev/null +++ b/aws/resource_aws_elasticsearch_package.go @@ -0,0 +1,148 @@ +package aws + +import ( + "fmt" + "log" + + "github.com/aws/aws-sdk-go/aws" + elasticsearch "github.com/aws/aws-sdk-go/service/elasticsearchservice" + "github.com/hashicorp/terraform-plugin-sdk/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/helper/validation" +) + +func resourceAwsElasticsearchPackage() *schema.Resource { + return &schema.Resource{ + Create: resourceAwsElasticsearchPackageCreate, + Read: resourceAwsElasticsearchPackageRead, + Delete: resourceAwsElasticsearchPackageDelete, + + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validation.StringLenBetween(3, 28), + }, + "type": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validation.StringInSlice([]string{ + elasticsearch.PackageTypeTxtDictionary, + }, false), + }, + "description": { + Type: schema.TypeString, + Optional: true, + ForceNew: true, + }, + "source": { + Type: schema.TypeList, + MaxItems: 1, + Required: true, + ForceNew: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "s3_bucket_name": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringIsNotEmpty, + }, + "s3_key": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringIsNotEmpty, + }, + }, + }, + }, + }, + } +} + +func resourceAwsElasticsearchPackageCreate(d *schema.ResourceData, meta interface{}) error { + conn := meta.(*AWSClient).esconn + + name := d.Get("name").(string) + source := d.Get("source").([]interface{})[0].(map[string]interface{}) + + input := &elasticsearch.CreatePackageInput{ + PackageName: aws.String(name), + PackageType: aws.String(d.Get("type").(string)), + PackageDescription: aws.String(d.Get("description").(string)), + PackageSource: &elasticsearch.PackageSource{ + S3BucketName: aws.String(source["s3_bucket_name"].(string)), + S3Key: aws.String(source["s3_key"].(string)), + }, + } + + out, err := conn.CreatePackage(input) + if err != nil { + return fmt.Errorf("Error creating Elasticsearch Package %s: %s", name, err) + } + + d.SetId(aws.StringValue(out.PackageDetails.PackageID)) + + return resourceAwsElasticsearchPackageRead(d, meta) +} + +func resourceAwsElasticsearchPackageRead(d *schema.ResourceData, meta interface{}) error { + conn := meta.(*AWSClient).esconn + + details, err := getElasticsearchPackage(conn, d.Id()) + if err != nil { + if isAWSErr(err, "ResourceNotFoundException", "") { + log.Printf("[WARN] ElasticSearch Package (%s) not found, removing from state", d.Id()) + d.SetId("") + return nil + } + + return fmt.Errorf("Error reading ElasticSearch Package: %s", err) + } + + if details == nil { + log.Printf("[WARN] ElasticSearch Package (%s) not found, removing from state", d.Id()) + d.SetId("") + return nil + } + + d.SetId(aws.StringValue(details.PackageID)) + d.Set("name", details.PackageName) + d.Set("description", details.PackageDescription) + d.Set("type", details.PackageType) + + return nil +} + +func resourceAwsElasticsearchPackageDelete(d *schema.ResourceData, meta interface{}) error { + conn := meta.(*AWSClient).esconn + + input := &elasticsearch.DeletePackageInput{PackageID: aws.String(d.Id())} + _, err := conn.DeletePackage(input) + if err != nil { + return fmt.Errorf("Error deleting Elasticsearch Package: %v", err) + } + + return nil +} + +func getElasticsearchPackage(conn *elasticsearch.ElasticsearchService, packageID string) (*elasticsearch.PackageDetails, error) { + input := &elasticsearch.DescribePackagesInput{ + Filters: []*elasticsearch.DescribePackagesFilter{ + { + Name: aws.String("PackageID"), + Value: []*string{aws.String(packageID)}, + }, + }, + } + output, err := conn.DescribePackages(input) + if err != nil { + return nil, err + } + + if output == nil || len(output.PackageDetailsList) == 0 { + return nil, nil + } + + return output.PackageDetailsList[0], nil +} diff --git a/aws/resource_aws_elasticsearch_package_test.go b/aws/resource_aws_elasticsearch_package_test.go new file mode 100644 index 00000000000..8bc992a7379 --- /dev/null +++ b/aws/resource_aws_elasticsearch_package_test.go @@ -0,0 +1,138 @@ +package aws + +import ( + "fmt" + "testing" + + elasticsearch "github.com/aws/aws-sdk-go/service/elasticsearchservice" + "github.com/hashicorp/terraform-plugin-sdk/helper/acctest" + "github.com/hashicorp/terraform-plugin-sdk/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/terraform" +) + +func TestAccAWSElasticsearchPackage_basic(t *testing.T) { + rString := acctest.RandString(7) + prefix := "tf-acctest-espackage" + name := fmt.Sprintf("%s-%s", prefix, rString) + resourceName := "aws_elasticsearch_package.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckAWSElasticsearchPackageDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAWSElasticsearchPackageConfig_basic(name), + Check: resource.ComposeTestCheckFunc( + testAccCheckAWSElasticsearchPackageExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "name", name), + resource.TestCheckResourceAttr(resourceName, "type", elasticsearch.PackageTypeTxtDictionary), + resource.TestCheckResourceAttr(resourceName, "description", "terraform acctest"), + resource.TestCheckResourceAttr(resourceName, "source.0.s3_bucket_name", name+"-bucket"), + resource.TestCheckResourceAttr(resourceName, "source.0.s3_key", "synonyms.txt"), + ), + }, + }, + }) +} + +func TestAccAWSElasticsearchPackage_disappears(t *testing.T) { + rString := acctest.RandString(7) + prefix := "tf-acctest-espackage" + name := fmt.Sprintf("%s-%s", prefix, rString) + resourceName := "aws_elasticsearch_package.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckAWSElasticsearchPackageDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAWSElasticsearchPackageConfig_basic(name), + Check: resource.ComposeTestCheckFunc( + testAccCheckAWSElasticsearchPackageExists(resourceName), + testAccCheckResourceDisappears(testAccProvider, resourceAwsElasticsearchPackage(), resourceName), + ), + ExpectNonEmptyPlan: true, + }, + }, + }) +} + +func testAccCheckAWSElasticsearchPackageExists(resourceName string) resource.TestCheckFunc { + return func(s *terraform.State) error { + rs, ok := s.RootModule().Resources[resourceName] + if !ok { + return fmt.Errorf("Not found: %s", resourceName) + } + + if rs.Primary.ID == "" { + return fmt.Errorf("No Elasticsearch Package ID is set") + } + + conn := testAccProvider.Meta().(*AWSClient).esconn + + details, err := getElasticsearchPackage(conn, rs.Primary.ID) + if err != nil { + return err + } + + if details == nil { + return fmt.Errorf("Elasticsearch Package (%s) not found", rs.Primary.ID) + } + + return nil + } +} + +func testAccCheckAWSElasticsearchPackageDestroy(s *terraform.State) error { + conn := testAccProvider.Meta().(*AWSClient).esconn + + for _, rs := range s.RootModule().Resources { + if rs.Type != "aws_elasticsearch_package" { + continue + } + + details, err := getElasticsearchPackage(conn, rs.Primary.ID) + + if isAWSErr(err, "ResourceNotFoundException", "") { + continue + } + + if err != nil { + return err + } + + if details == nil { + continue + } + + return fmt.Errorf("Elasticsearch Package (%s) still exists", rs.Primary.ID) + } + + return nil +} + +func testAccAWSElasticsearchPackageConfig_basic(name string) string { + return fmt.Sprintf(` + resource "aws_s3_bucket" "test" { + bucket = "%[1]s-bucket" + } + + resource "aws_s3_bucket_object" "test" { + bucket = "${aws_s3_bucket.test.bucket}" + key = "synonyms.txt" + content = "foo, bar" + } + + resource "aws_elasticsearch_package" "test" { + name = "%[1]s" + type = "TXT-DICTIONARY" + description = "terraform acctest" + source { + s3_bucket_name = "${aws_s3_bucket.test.bucket}" + s3_key = "${aws_s3_bucket_object.test.key}" + } + } + `, name) +} diff --git a/website/aws.erb b/website/aws.erb index 8f070b7bc4d..032391a92b3 100644 --- a/website/aws.erb +++ b/website/aws.erb @@ -1664,6 +1664,9 @@
  • aws_elasticsearch_domain_policy
  • +
  • + aws_elasticsearch_package +
  • diff --git a/website/docs/r/elasticsearch_package.html.markdown b/website/docs/r/elasticsearch_package.html.markdown new file mode 100644 index 00000000000..20d1459b5d8 --- /dev/null +++ b/website/docs/r/elasticsearch_package.html.markdown @@ -0,0 +1,57 @@ +--- +subcategory: 'ElasticSearch' +layout: 'aws' +page_title: 'AWS: aws_elasticsearch_package' +description: |- + Terraform resource for managing an AWS Elasticsearch Package. +--- + +# Resource: aws_elasticsearch_package + +Manages an AWS Elasticsearch Package. + +## Example Usage + +### Basic Usage + +```hcl +resource "aws_s3_bucket" "example" { + bucket = "foo-bucket" +} + +resource "aws_s3_bucket_object" "example" { + bucket = "${aws_s3_bucket.example.bucket}" + key = "synonyms.txt" + content = "foo, bar" +} + +resource "aws_elasticsearch_package" "example" { + name = "synonyms" + type = "TXT-DICTIONARY" + + source { + s3_bucket_name = "${aws_s3_bucket.example.bucket}" + s3_key = "${aws_s3_bucket_object.example.key}" + } +} +``` + +## Argument Reference + +The following arguments are supported: + +* `name` - (Required) Unique name for the package. +* `type` - (Required) Type of the package. Currently supports only `TXT-DICTIONARY`. +* `description` - (Optional) Description of the package. +* `source` - (Required) S3 bucket and key for the package. See below. + +**source** supports the following attributes: + +* `s3_bucket_name` - (Required) Name of the bucket containing the package. +* `s3_key` - (Required) Key (file name) of the package. + +## Attributes Reference + +In addition to all arguments above, the following attributes are exported: + +* `id` - The ID of the package.