provider/aws: Add EBS Volume support for EMR Instance Groups
Adds EBS Volume support and tests for EMR Instnace Groups ``` $ make testacc TEST=./builtin/providers/aws TESTARGS='-run=TestAccAWSEMRInstanceGroup_ebsBasic' ==> Checking that code complies with gofmt requirements... go generate $(go list ./... | grep -v /terraform/vendor/) 2017/01/25 10:14:58 Generated command/internal_plugin_list.go TF_ACC=1 go test ./builtin/providers/aws -v -run=TestAccAWSEMRInstanceGroup_ebsBasic -timeout 120m === RUN TestAccAWSEMRInstanceGroup_ebsBasic --- PASS: TestAccAWSEMRInstanceGroup_ebsBasic (675.14s) PASS ok github.com/hashicorp/terraform/builtin/providers/aws 675.171s ```
This commit is contained in:
parent
27e29420e5
commit
a60f35e694
|
@ -22,38 +22,100 @@ func resourceAwsEMRInstanceGroup() *schema.Resource {
|
|||
Update: resourceAwsEMRInstanceGroupUpdate,
|
||||
Delete: resourceAwsEMRInstanceGroupDelete,
|
||||
Schema: map[string]*schema.Schema{
|
||||
"cluster_id": &schema.Schema{
|
||||
"cluster_id": {
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
ForceNew: true,
|
||||
},
|
||||
"instance_type": &schema.Schema{
|
||||
"instance_type": {
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
ForceNew: true,
|
||||
},
|
||||
"instance_count": &schema.Schema{
|
||||
"instance_count": {
|
||||
Type: schema.TypeInt,
|
||||
Optional: true,
|
||||
Default: 0,
|
||||
},
|
||||
"running_instance_count": &schema.Schema{
|
||||
"running_instance_count": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
"status": &schema.Schema{
|
||||
"status": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"name": &schema.Schema{
|
||||
"name": {
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
ForceNew: true,
|
||||
},
|
||||
"ebs_optimized": {
|
||||
Type: schema.TypeBool,
|
||||
Optional: true,
|
||||
ForceNew: true,
|
||||
},
|
||||
"ebs_config": {
|
||||
Type: schema.TypeSet,
|
||||
Optional: true,
|
||||
ForceNew: true,
|
||||
Elem: &schema.Resource{
|
||||
Schema: map[string]*schema.Schema{
|
||||
"iops": {
|
||||
Type: schema.TypeInt,
|
||||
Optional: true,
|
||||
},
|
||||
"size": {
|
||||
Type: schema.TypeInt,
|
||||
Required: true,
|
||||
},
|
||||
"type": {
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
ValidateFunc: validateAwsEmrEbsVolumeType,
|
||||
},
|
||||
"volumes_per_instance": {
|
||||
Type: schema.TypeInt,
|
||||
Optional: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// Populates an emr.EbsConfiguration struct
|
||||
func readEmrEBSConfig(d *schema.ResourceData) *emr.EbsConfiguration {
|
||||
result := &emr.EbsConfiguration{}
|
||||
if v, ok := d.GetOk("ebs_optimized"); ok {
|
||||
result.EbsOptimized = aws.Bool(v.(bool))
|
||||
}
|
||||
|
||||
ebsConfigs := make([]*emr.EbsBlockDeviceConfig, 0)
|
||||
if rawConfig, ok := d.GetOk("ebs_config"); ok {
|
||||
configList := rawConfig.(*schema.Set).List()
|
||||
for _, config := range configList {
|
||||
conf := config.(map[string]interface{})
|
||||
ebs := &emr.EbsBlockDeviceConfig{}
|
||||
volumeSpec := &emr.VolumeSpecification{
|
||||
SizeInGB: aws.Int64(int64(conf["size"].(int))),
|
||||
VolumeType: aws.String(conf["type"].(string)),
|
||||
}
|
||||
if v, ok := conf["iops"].(int); ok && v != 0 {
|
||||
volumeSpec.Iops = aws.Int64(int64(v))
|
||||
}
|
||||
if v, ok := conf["volumes_per_instance"].(int); ok && v != 0 {
|
||||
ebs.VolumesPerInstance = aws.Int64(int64(v))
|
||||
}
|
||||
ebs.VolumeSpecification = volumeSpec
|
||||
ebsConfigs = append(ebsConfigs, ebs)
|
||||
}
|
||||
}
|
||||
result.EbsBlockDeviceConfigs = ebsConfigs
|
||||
return result
|
||||
}
|
||||
|
||||
func resourceAwsEMRInstanceGroupCreate(d *schema.ResourceData, meta interface{}) error {
|
||||
conn := meta.(*AWSClient).emrconn
|
||||
|
||||
|
@ -62,13 +124,16 @@ func resourceAwsEMRInstanceGroupCreate(d *schema.ResourceData, meta interface{})
|
|||
instanceCount := d.Get("instance_count").(int)
|
||||
groupName := d.Get("name").(string)
|
||||
|
||||
ebsConfig := readEmrEBSConfig(d)
|
||||
|
||||
params := &emr.AddInstanceGroupsInput{
|
||||
InstanceGroups: []*emr.InstanceGroupConfig{
|
||||
{
|
||||
InstanceRole: aws.String("TASK"),
|
||||
InstanceCount: aws.Int64(int64(instanceCount)),
|
||||
InstanceType: aws.String(instanceType),
|
||||
Name: aws.String(groupName),
|
||||
InstanceRole: aws.String("TASK"),
|
||||
InstanceCount: aws.Int64(int64(instanceCount)),
|
||||
InstanceType: aws.String(instanceType),
|
||||
Name: aws.String(groupName),
|
||||
EbsConfiguration: ebsConfig,
|
||||
},
|
||||
},
|
||||
JobFlowId: aws.String(clusterId),
|
||||
|
|
|
@ -21,7 +21,7 @@ func TestAccAWSEMRInstanceGroup_basic(t *testing.T) {
|
|||
Providers: testAccProviders,
|
||||
CheckDestroy: testAccCheckAWSEmrInstanceGroupDestroy,
|
||||
Steps: []resource.TestStep{
|
||||
resource.TestStep{
|
||||
{
|
||||
Config: testAccAWSEmrInstanceGroupConfig(rInt),
|
||||
Check: testAccCheckAWSEmrInstanceGroupExists("aws_emr_instance_group.task", &ig),
|
||||
},
|
||||
|
@ -29,6 +29,28 @@ func TestAccAWSEMRInstanceGroup_basic(t *testing.T) {
|
|||
})
|
||||
}
|
||||
|
||||
func TestAccAWSEMRInstanceGroup_ebsBasic(t *testing.T) {
|
||||
var ig emr.InstanceGroup
|
||||
rInt := acctest.RandInt()
|
||||
resource.Test(t, resource.TestCase{
|
||||
PreCheck: func() { testAccPreCheck(t) },
|
||||
Providers: testAccProviders,
|
||||
CheckDestroy: testAccCheckAWSEmrInstanceGroupDestroy,
|
||||
Steps: []resource.TestStep{
|
||||
{
|
||||
Config: testAccAWSEmrInstanceGroupConfig_ebsBasic(rInt),
|
||||
Check: resource.ComposeTestCheckFunc(
|
||||
testAccCheckAWSEmrInstanceGroupExists("aws_emr_instance_group.task", &ig),
|
||||
resource.TestCheckResourceAttr(
|
||||
"aws_emr_instance_group.task", "ebs_config.#", "1"),
|
||||
resource.TestCheckResourceAttr(
|
||||
"aws_emr_instance_group.task", "ebs_optimized", "true"),
|
||||
),
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func testAccCheckAWSEmrInstanceGroupDestroy(s *terraform.State) error {
|
||||
conn := testAccProvider.Meta().(*AWSClient).emrconn
|
||||
|
||||
|
@ -85,8 +107,7 @@ func testAccCheckAWSEmrInstanceGroupExists(n string, v *emr.InstanceGroup) resou
|
|||
}
|
||||
}
|
||||
|
||||
func testAccAWSEmrInstanceGroupConfig(r int) string {
|
||||
return fmt.Sprintf(`
|
||||
const testAccAWSEmrInstanceGroupBase = `
|
||||
provider "aws" {
|
||||
region = "us-west-2"
|
||||
}
|
||||
|
@ -126,12 +147,6 @@ resource "aws_emr_cluster" "tf-test-cluster" {
|
|||
depends_on = ["aws_internet_gateway.gw"]
|
||||
}
|
||||
|
||||
resource "aws_emr_instance_group" "task" {
|
||||
cluster_id = "${aws_emr_cluster.tf-test-cluster.id}"
|
||||
instance_count = 1
|
||||
instance_type = "m3.xlarge"
|
||||
}
|
||||
|
||||
resource "aws_security_group" "allow_all" {
|
||||
name = "allow_all"
|
||||
description = "Allow all inbound traffic"
|
||||
|
@ -352,5 +367,30 @@ resource "aws_iam_policy" "iam_emr_profile_policy" {
|
|||
}]
|
||||
}
|
||||
EOT
|
||||
}`, r, r, r, r, r, r)
|
||||
}
|
||||
`
|
||||
|
||||
func testAccAWSEmrInstanceGroupConfig(r int) string {
|
||||
return fmt.Sprintf(testAccAWSEmrInstanceGroupBase+`
|
||||
resource "aws_emr_instance_group" "task" {
|
||||
cluster_id = "${aws_emr_cluster.tf-test-cluster.id}"
|
||||
instance_count = 1
|
||||
instance_type = "m3.xlarge"
|
||||
}
|
||||
`, r, r, r, r, r, r)
|
||||
}
|
||||
|
||||
func testAccAWSEmrInstanceGroupConfig_ebsBasic(r int) string {
|
||||
return fmt.Sprintf(testAccAWSEmrInstanceGroupBase+`
|
||||
resource "aws_emr_instance_group" "task" {
|
||||
cluster_id = "${aws_emr_cluster.tf-test-cluster.id}"
|
||||
instance_count = 1
|
||||
instance_type = "m3.xlarge"
|
||||
ebs_optimized = true
|
||||
ebs_config {
|
||||
"size" = 10,
|
||||
"type" = "gp2",
|
||||
}
|
||||
}
|
||||
`, r, r, r, r, r, r)
|
||||
}
|
||||
|
|
|
@ -727,3 +727,19 @@ func validateAwsEcsPlacementStrategy(stratType, stratField string) error {
|
|||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func validateAwsEmrEbsVolumeType(v interface{}, k string) (ws []string, errors []error) {
|
||||
validTypes := map[string]struct{}{
|
||||
"gp2": {},
|
||||
"io1": {},
|
||||
"standard": {},
|
||||
}
|
||||
|
||||
value := v.(string)
|
||||
|
||||
if _, ok := validTypes[value]; !ok {
|
||||
errors = append(errors, fmt.Errorf(
|
||||
"%q must be one of ['gp2', 'io1', 'standard']", k))
|
||||
}
|
||||
return
|
||||
}
|
||||
|
|
|
@ -1172,3 +1172,48 @@ func TestValidateEcsPlacementStrategy(t *testing.T) {
|
|||
|
||||
}
|
||||
}
|
||||
|
||||
func TestValidateEmrEbsVolumeType(t *testing.T) {
|
||||
cases := []struct {
|
||||
VolType string
|
||||
ErrCount int
|
||||
}{
|
||||
{
|
||||
VolType: "gp2",
|
||||
ErrCount: 0,
|
||||
},
|
||||
{
|
||||
VolType: "io1",
|
||||
ErrCount: 0,
|
||||
},
|
||||
{
|
||||
VolType: "standard",
|
||||
ErrCount: 0,
|
||||
},
|
||||
{
|
||||
VolType: "stand",
|
||||
ErrCount: 1,
|
||||
},
|
||||
{
|
||||
VolType: "io",
|
||||
ErrCount: 1,
|
||||
},
|
||||
{
|
||||
VolType: "gp1",
|
||||
ErrCount: 1,
|
||||
},
|
||||
{
|
||||
VolType: "fast-disk",
|
||||
ErrCount: 1,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range cases {
|
||||
_, errors := validateAwsEmrEbsVolumeType(tc.VolType, "volume")
|
||||
|
||||
if len(errors) != tc.ErrCount {
|
||||
t.Fatalf("Expected %d errors, got %d: %s", tc.ErrCount, len(errors), errors)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue