From ae5502b74490cca1d0d493e3ffe81f22f7732257 Mon Sep 17 00:00:00 2001 From: Radek Simko Date: Mon, 4 May 2015 22:48:09 +0100 Subject: [PATCH] provider/aws: Add new resource - aws_ecs_cluster --- builtin/providers/aws/config.go | 5 ++ builtin/providers/aws/provider.go | 1 + .../providers/aws/resource_aws_ecs_cluster.go | 80 +++++++++++++++++++ .../aws/resource_aws_ecs_cluster_test.go | 68 ++++++++++++++++ 4 files changed, 154 insertions(+) create mode 100644 builtin/providers/aws/resource_aws_ecs_cluster.go create mode 100644 builtin/providers/aws/resource_aws_ecs_cluster_test.go diff --git a/builtin/providers/aws/config.go b/builtin/providers/aws/config.go index 7908daf16..6a46b5fc9 100644 --- a/builtin/providers/aws/config.go +++ b/builtin/providers/aws/config.go @@ -11,6 +11,7 @@ import ( "github.com/aws/aws-sdk-go/aws/credentials" "github.com/aws/aws-sdk-go/service/autoscaling" "github.com/aws/aws-sdk-go/service/ec2" + "github.com/aws/aws-sdk-go/service/ecs" "github.com/aws/aws-sdk-go/service/elasticache" "github.com/aws/aws-sdk-go/service/elb" "github.com/aws/aws-sdk-go/service/iam" @@ -35,6 +36,7 @@ type Config struct { type AWSClient struct { ec2conn *ec2.EC2 + ecsconn *ecs.ECS elbconn *elb.ELB autoscalingconn *autoscaling.AutoScaling s3conn *s3.S3 @@ -116,6 +118,9 @@ func (c *Config) Client() (interface{}, error) { log.Println("[INFO] Initializing EC2 Connection") client.ec2conn = ec2.New(awsConfig) + log.Println("[INFO] Initializing ECS Connection") + client.ecsconn = ecs.New(awsConfig) + // aws-sdk-go uses v4 for signing requests, which requires all global // endpoints to use 'us-east-1'. // See http://docs.aws.amazon.com/general/latest/gr/sigv4_changes.html diff --git a/builtin/providers/aws/provider.go b/builtin/providers/aws/provider.go index 9e0f928a4..2aa094d6d 100644 --- a/builtin/providers/aws/provider.go +++ b/builtin/providers/aws/provider.go @@ -91,6 +91,7 @@ func Provider() terraform.ResourceProvider { "aws_db_security_group": resourceAwsDbSecurityGroup(), "aws_db_subnet_group": resourceAwsDbSubnetGroup(), "aws_ebs_volume": resourceAwsEbsVolume(), + "aws_ecs_cluster": resourceAwsEcsCluster(), "aws_eip": resourceAwsEip(), "aws_elasticache_cluster": resourceAwsElasticacheCluster(), "aws_elasticache_security_group": resourceAwsElasticacheSecurityGroup(), diff --git a/builtin/providers/aws/resource_aws_ecs_cluster.go b/builtin/providers/aws/resource_aws_ecs_cluster.go new file mode 100644 index 000000000..30871f3dc --- /dev/null +++ b/builtin/providers/aws/resource_aws_ecs_cluster.go @@ -0,0 +1,80 @@ +package aws + +import ( + "log" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/service/ecs" + "github.com/hashicorp/terraform/helper/schema" +) + +func resourceAwsEcsCluster() *schema.Resource { + return &schema.Resource{ + Create: resourceAwsEcsClusterCreate, + Read: resourceAwsEcsClusterRead, + Delete: resourceAwsEcsClusterDelete, + + Schema: map[string]*schema.Schema{ + "name": &schema.Schema{ + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + }, + } +} + +func resourceAwsEcsClusterCreate(d *schema.ResourceData, meta interface{}) error { + conn := meta.(*AWSClient).ecsconn + + clusterName := d.Get("name").(string) + log.Printf("[DEBUG] Creating ECS cluster %s", clusterName) + + out, err := conn.CreateCluster(&ecs.CreateClusterInput{ + ClusterName: aws.String(clusterName), + }) + if err != nil { + return err + } + log.Printf("[DEBUG] ECS cluster %s created", *out.Cluster.ClusterARN) + + d.SetId(*out.Cluster.ClusterARN) + d.Set("name", *out.Cluster.ClusterName) + return nil +} + +func resourceAwsEcsClusterRead(d *schema.ResourceData, meta interface{}) error { + conn := meta.(*AWSClient).ecsconn + + clusterName := d.Get("name").(string) + log.Printf("[DEBUG] Reading ECS cluster %s", clusterName) + out, err := conn.DescribeClusters(&ecs.DescribeClustersInput{ + Clusters: []*string{aws.String(clusterName)}, + }) + if err != nil { + return err + } + log.Printf("[DEBUG] Received ECS clusters: %#v", out.Clusters) + + d.SetId(*out.Clusters[0].ClusterARN) + d.Set("name", *out.Clusters[0].ClusterName) + + return nil +} + +func resourceAwsEcsClusterDelete(d *schema.ResourceData, meta interface{}) error { + conn := meta.(*AWSClient).ecsconn + + log.Printf("[DEBUG] Deleting ECS cluster %s", d.Id()) + + // TODO: Handle ClientException: The Cluster cannot be deleted while Container Instances are active. + // TODO: Handle ClientException: The Cluster cannot be deleted while Services are active. + + out, err := conn.DeleteCluster(&ecs.DeleteClusterInput{ + Cluster: aws.String(d.Id()), + }) + + log.Printf("[DEBUG] ECS cluster %s deleted: %#v", d.Id(), out) + + return err +} diff --git a/builtin/providers/aws/resource_aws_ecs_cluster_test.go b/builtin/providers/aws/resource_aws_ecs_cluster_test.go new file mode 100644 index 000000000..0f5ab242a --- /dev/null +++ b/builtin/providers/aws/resource_aws_ecs_cluster_test.go @@ -0,0 +1,68 @@ +package aws + +import ( + "fmt" + "testing" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/service/ecs" + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/terraform" +) + +func TestAccAWSEcsCluster(t *testing.T) { + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckAWSEcsClusterDestroy, + Steps: []resource.TestStep{ + resource.TestStep{ + Config: testAccAWSEcsCluster, + Check: resource.ComposeTestCheckFunc( + testAccCheckAWSEcsClusterExists("aws_ecs_cluster.foo"), + ), + }, + }, + }) +} + +func testAccCheckAWSEcsClusterDestroy(s *terraform.State) error { + conn := testAccProvider.Meta().(*AWSClient).ecsconn + + for _, rs := range s.RootModule().Resources { + if rs.Type != "aws_ecs_cluster" { + continue + } + + out, err := conn.DescribeClusters(&ecs.DescribeClustersInput{ + Clusters: []*string{aws.String(rs.Primary.ID)}, + }) + + if err == nil { + if len(out.Clusters) != 0 { + return fmt.Errorf("ECS cluster still exists:\n%#v", out.Clusters) + } + } + + return err + } + + return nil +} + +func testAccCheckAWSEcsClusterExists(name string) resource.TestCheckFunc { + return func(s *terraform.State) error { + _, ok := s.RootModule().Resources[name] + if !ok { + return fmt.Errorf("Not found: %s", name) + } + + return nil + } +} + +var testAccAWSEcsCluster = ` +resource "aws_ecs_cluster" "foo" { + name = "red-grapes" +} +`