github.com/danp/terraform@v0.9.5-0.20170426144147-39d740081351/builtin/providers/aws/resource_aws_appautoscaling_target_test.go (about) 1 package aws 2 3 import ( 4 "fmt" 5 "testing" 6 7 "github.com/aws/aws-sdk-go/aws" 8 "github.com/aws/aws-sdk-go/aws/awserr" 9 "github.com/aws/aws-sdk-go/service/applicationautoscaling" 10 "github.com/hashicorp/terraform/helper/acctest" 11 "github.com/hashicorp/terraform/helper/resource" 12 "github.com/hashicorp/terraform/terraform" 13 ) 14 15 func TestAccAWSAppautoScalingTarget_basic(t *testing.T) { 16 var target applicationautoscaling.ScalableTarget 17 18 randClusterName := fmt.Sprintf("cluster-%s", acctest.RandString(10)) 19 20 resource.Test(t, resource.TestCase{ 21 PreCheck: func() { testAccPreCheck(t) }, 22 IDRefreshName: "aws_appautoscaling_target.bar", 23 Providers: testAccProviders, 24 CheckDestroy: testAccCheckAWSAppautoscalingTargetDestroy, 25 Steps: []resource.TestStep{ 26 { 27 Config: testAccAWSAppautoscalingTargetConfig(randClusterName), 28 Check: resource.ComposeTestCheckFunc( 29 testAccCheckAWSAppautoscalingTargetExists("aws_appautoscaling_target.bar", &target), 30 resource.TestCheckResourceAttr("aws_appautoscaling_target.bar", "service_namespace", "ecs"), 31 resource.TestCheckResourceAttr("aws_appautoscaling_target.bar", "scalable_dimension", "ecs:service:DesiredCount"), 32 resource.TestCheckResourceAttr("aws_appautoscaling_target.bar", "min_capacity", "1"), 33 resource.TestCheckResourceAttr("aws_appautoscaling_target.bar", "max_capacity", "3"), 34 ), 35 }, 36 37 { 38 Config: testAccAWSAppautoscalingTargetConfigUpdate(randClusterName), 39 Check: resource.ComposeTestCheckFunc( 40 testAccCheckAWSAppautoscalingTargetExists("aws_appautoscaling_target.bar", &target), 41 resource.TestCheckResourceAttr("aws_appautoscaling_target.bar", "min_capacity", "2"), 42 resource.TestCheckResourceAttr("aws_appautoscaling_target.bar", "max_capacity", "8"), 43 ), 44 }, 45 }, 46 }) 47 } 48 49 func TestAccAWSAppautoScalingTarget_spotFleetRequest(t *testing.T) { 50 var target applicationautoscaling.ScalableTarget 51 52 resource.Test(t, resource.TestCase{ 53 PreCheck: func() { testAccPreCheck(t) }, 54 IDRefreshName: "aws_appautoscaling_target.test", 55 Providers: testAccProviders, 56 CheckDestroy: testAccCheckAWSAppautoscalingTargetDestroy, 57 Steps: []resource.TestStep{ 58 { 59 Config: testAccAWSAppautoscalingTargetSpotFleetRequestConfig, 60 Check: resource.ComposeTestCheckFunc( 61 testAccCheckAWSAppautoscalingTargetExists("aws_appautoscaling_target.test", &target), 62 resource.TestCheckResourceAttr("aws_appautoscaling_target.test", "service_namespace", "ec2"), 63 resource.TestCheckResourceAttr("aws_appautoscaling_target.test", "scalable_dimension", "ec2:spot-fleet-request:TargetCapacity"), 64 ), 65 }, 66 }, 67 }) 68 } 69 70 func TestAccAWSAppautoScalingTarget_emrCluster(t *testing.T) { 71 var target applicationautoscaling.ScalableTarget 72 rInt := acctest.RandInt() 73 74 resource.Test(t, resource.TestCase{ 75 PreCheck: func() { testAccPreCheck(t) }, 76 Providers: testAccProviders, 77 CheckDestroy: testAccCheckAWSAppautoscalingTargetDestroy, 78 Steps: []resource.TestStep{ 79 { 80 Config: testAccAWSAppautoscalingTargetEmrClusterConfig(rInt), 81 Check: resource.ComposeTestCheckFunc( 82 testAccCheckAWSAppautoscalingTargetExists("aws_appautoscaling_target.bar", &target), 83 resource.TestCheckResourceAttr("aws_appautoscaling_target.bar", "service_namespace", "elasticmapreduce"), 84 resource.TestCheckResourceAttr("aws_appautoscaling_target.bar", "scalable_dimension", "elasticmapreduce:instancegroup:InstanceCount"), 85 ), 86 }, 87 }, 88 }) 89 } 90 91 func testAccCheckAWSAppautoscalingTargetDestroy(s *terraform.State) error { 92 conn := testAccProvider.Meta().(*AWSClient).appautoscalingconn 93 94 for _, rs := range s.RootModule().Resources { 95 if rs.Type != "aws_appautoscaling_target" { 96 continue 97 } 98 99 // Try to find the target 100 describeTargets, err := conn.DescribeScalableTargets( 101 &applicationautoscaling.DescribeScalableTargetsInput{ 102 ResourceIds: []*string{aws.String(rs.Primary.ID)}, 103 ServiceNamespace: aws.String(rs.Primary.Attributes["service_namespace"]), 104 }, 105 ) 106 107 if err == nil { 108 if len(describeTargets.ScalableTargets) != 0 && 109 *describeTargets.ScalableTargets[0].ResourceId == rs.Primary.ID { 110 return fmt.Errorf("Application AutoScaling Target still exists") 111 } 112 } 113 114 // Verify error 115 e, ok := err.(awserr.Error) 116 if !ok { 117 return err 118 } 119 if e.Code() != "" { 120 return e 121 } 122 } 123 124 return nil 125 } 126 127 func testAccCheckAWSAppautoscalingTargetExists(n string, target *applicationautoscaling.ScalableTarget) resource.TestCheckFunc { 128 return func(s *terraform.State) error { 129 rs, ok := s.RootModule().Resources[n] 130 if !ok { 131 return fmt.Errorf("Not found: %s", n) 132 } 133 134 if rs.Primary.ID == "" { 135 return fmt.Errorf("No Application AutoScaling Target ID is set") 136 } 137 138 conn := testAccProvider.Meta().(*AWSClient).appautoscalingconn 139 140 describeTargets, err := conn.DescribeScalableTargets( 141 &applicationautoscaling.DescribeScalableTargetsInput{ 142 ResourceIds: []*string{aws.String(rs.Primary.ID)}, 143 ServiceNamespace: aws.String(rs.Primary.Attributes["service_namespace"]), 144 }, 145 ) 146 147 if err != nil { 148 return err 149 } 150 151 if len(describeTargets.ScalableTargets) != 1 || *describeTargets.ScalableTargets[0].ResourceId != rs.Primary.ID { 152 return fmt.Errorf("Application AutoScaling ResourceId not found") 153 } 154 155 target = describeTargets.ScalableTargets[0] 156 157 return nil 158 } 159 } 160 161 func testAccAWSAppautoscalingTargetConfig( 162 randClusterName string) string { 163 return fmt.Sprintf(` 164 resource "aws_iam_role" "autoscale_role" { 165 name = "autoscalerole%s" 166 path = "/" 167 168 assume_role_policy = <<EOF 169 { 170 "Version": "2012-10-17", 171 "Statement": [ 172 { 173 "Effect": "Allow", 174 "Principal": { 175 "Service": "application-autoscaling.amazonaws.com" 176 }, 177 "Action": "sts:AssumeRole" 178 } 179 ] 180 } 181 EOF 182 } 183 184 resource "aws_iam_role_policy" "autoscale_role_policy" { 185 name = "autoscalepolicy%s" 186 role = "${aws_iam_role.autoscale_role.id}" 187 188 policy = <<EOF 189 { 190 "Version": "2012-10-17", 191 "Statement": [ 192 { 193 "Effect": "Allow", 194 "Action": [ 195 "ecs:DescribeServices", 196 "ecs:UpdateService" 197 ], 198 "Resource": [ 199 "*" 200 ] 201 }, 202 { 203 "Effect": "Allow", 204 "Action": [ 205 "cloudwatch:DescribeAlarms" 206 ], 207 "Resource": [ 208 "*" 209 ] 210 } 211 ] 212 } 213 EOF 214 } 215 216 resource "aws_ecs_cluster" "foo" { 217 name = "%s" 218 } 219 220 resource "aws_ecs_task_definition" "task" { 221 family = "foobar" 222 container_definitions = <<EOF 223 [ 224 { 225 "name": "busybox", 226 "image": "busybox:latest", 227 "cpu": 10, 228 "memory": 128, 229 "essential": true 230 } 231 ] 232 EOF 233 } 234 235 resource "aws_ecs_service" "service" { 236 name = "foobar" 237 cluster = "${aws_ecs_cluster.foo.id}" 238 task_definition = "${aws_ecs_task_definition.task.arn}" 239 desired_count = 1 240 241 deployment_maximum_percent = 200 242 deployment_minimum_healthy_percent = 50 243 } 244 245 resource "aws_appautoscaling_target" "bar" { 246 service_namespace = "ecs" 247 resource_id = "service/${aws_ecs_cluster.foo.name}/${aws_ecs_service.service.name}" 248 scalable_dimension = "ecs:service:DesiredCount" 249 role_arn = "${aws_iam_role.autoscale_role.arn}" 250 min_capacity = 1 251 max_capacity = 3 252 } 253 `, randClusterName, randClusterName, randClusterName) 254 } 255 256 func testAccAWSAppautoscalingTargetConfigUpdate( 257 randClusterName string) string { 258 return fmt.Sprintf(` 259 resource "aws_iam_role" "autoscale_role" { 260 name = "autoscalerole%s" 261 path = "/" 262 263 assume_role_policy = <<EOF 264 { 265 "Version": "2012-10-17", 266 "Statement": [ 267 { 268 "Effect": "Allow", 269 "Principal": { 270 "Service": "application-autoscaling.amazonaws.com" 271 }, 272 "Action": "sts:AssumeRole" 273 } 274 ] 275 } 276 EOF 277 } 278 279 resource "aws_iam_role_policy" "autoscale_role_policy" { 280 name = "autoscalepolicy%s" 281 role = "${aws_iam_role.autoscale_role.id}" 282 283 policy = <<EOF 284 { 285 "Version": "2012-10-17", 286 "Statement": [ 287 { 288 "Effect": "Allow", 289 "Action": [ 290 "ecs:DescribeServices", 291 "ecs:UpdateService" 292 ], 293 "Resource": [ 294 "*" 295 ] 296 }, 297 { 298 "Effect": "Allow", 299 "Action": [ 300 "cloudwatch:DescribeAlarms" 301 ], 302 "Resource": [ 303 "*" 304 ] 305 } 306 ] 307 } 308 EOF 309 } 310 311 resource "aws_ecs_cluster" "foo" { 312 name = "%s" 313 } 314 315 resource "aws_ecs_task_definition" "task" { 316 family = "foobar" 317 container_definitions = <<EOF 318 [ 319 { 320 "name": "busybox", 321 "image": "busybox:latest", 322 "cpu": 10, 323 "memory": 128, 324 "essential": true 325 } 326 ] 327 EOF 328 } 329 330 resource "aws_ecs_service" "service" { 331 name = "foobar" 332 cluster = "${aws_ecs_cluster.foo.id}" 333 task_definition = "${aws_ecs_task_definition.task.arn}" 334 desired_count = 2 335 336 deployment_maximum_percent = 200 337 deployment_minimum_healthy_percent = 50 338 } 339 340 resource "aws_appautoscaling_target" "bar" { 341 service_namespace = "ecs" 342 resource_id = "service/${aws_ecs_cluster.foo.name}/${aws_ecs_service.service.name}" 343 scalable_dimension = "ecs:service:DesiredCount" 344 role_arn = "${aws_iam_role.autoscale_role.arn}" 345 min_capacity = 2 346 max_capacity = 8 347 } 348 `, randClusterName, randClusterName, randClusterName) 349 } 350 351 func testAccAWSAppautoscalingTargetEmrClusterConfig(rInt int) string { 352 return fmt.Sprintf(` 353 resource "aws_emr_cluster" "tf-test-cluster" { 354 name = "emr-test-%d" 355 release_label = "emr-4.6.0" 356 applications = ["Spark"] 357 358 ec2_attributes { 359 subnet_id = "${aws_subnet.main.id}" 360 emr_managed_master_security_group = "${aws_security_group.allow_all.id}" 361 emr_managed_slave_security_group = "${aws_security_group.allow_all.id}" 362 instance_profile = "${aws_iam_instance_profile.emr_profile.arn}" 363 } 364 365 master_instance_type = "m3.xlarge" 366 core_instance_type = "m3.xlarge" 367 core_instance_count = 2 368 369 tags { 370 role = "rolename" 371 dns_zone = "env_zone" 372 env = "env" 373 name = "name-env" 374 } 375 376 keep_job_flow_alive_when_no_steps = true 377 378 bootstrap_action { 379 path = "s3://elasticmapreduce/bootstrap-actions/run-if" 380 name = "runif" 381 args = ["instance.isMaster=true", "echo running on master node"] 382 } 383 384 configurations = "test-fixtures/emr_configurations.json" 385 386 depends_on = ["aws_main_route_table_association.a"] 387 388 service_role = "${aws_iam_role.iam_emr_default_role.arn}" 389 autoscaling_role = "${aws_iam_role.emr-autoscaling-role.arn}" 390 } 391 392 resource "aws_emr_instance_group" "task" { 393 cluster_id = "${aws_emr_cluster.tf-test-cluster.id}" 394 instance_count = 1 395 instance_type = "m3.xlarge" 396 } 397 398 resource "aws_security_group" "allow_all" { 399 name = "allow_all_%d" 400 description = "Allow all inbound traffic" 401 vpc_id = "${aws_vpc.main.id}" 402 403 ingress { 404 from_port = 0 405 to_port = 0 406 protocol = "-1" 407 cidr_blocks = ["0.0.0.0/0"] 408 } 409 410 egress { 411 from_port = 0 412 to_port = 0 413 protocol = "-1" 414 cidr_blocks = ["0.0.0.0/0"] 415 } 416 417 depends_on = ["aws_subnet.main"] 418 419 lifecycle { 420 ignore_changes = ["ingress", "egress"] 421 } 422 423 tags { 424 name = "emr_test" 425 } 426 } 427 428 resource "aws_vpc" "main" { 429 cidr_block = "168.31.0.0/16" 430 enable_dns_hostnames = true 431 432 tags { 433 name = "emr_test_%d" 434 } 435 } 436 437 resource "aws_subnet" "main" { 438 vpc_id = "${aws_vpc.main.id}" 439 cidr_block = "168.31.0.0/20" 440 441 tags { 442 name = "emr_test_%d" 443 } 444 } 445 446 resource "aws_internet_gateway" "gw" { 447 vpc_id = "${aws_vpc.main.id}" 448 } 449 450 resource "aws_route_table" "r" { 451 vpc_id = "${aws_vpc.main.id}" 452 453 route { 454 cidr_block = "0.0.0.0/0" 455 gateway_id = "${aws_internet_gateway.gw.id}" 456 } 457 } 458 459 resource "aws_main_route_table_association" "a" { 460 vpc_id = "${aws_vpc.main.id}" 461 route_table_id = "${aws_route_table.r.id}" 462 } 463 464 resource "aws_iam_role" "iam_emr_default_role" { 465 name = "iam_emr_default_role_%d" 466 467 assume_role_policy = <<EOT 468 { 469 "Version": "2008-10-17", 470 "Statement": [ 471 { 472 "Sid": "", 473 "Effect": "Allow", 474 "Principal": { 475 "Service": "elasticmapreduce.amazonaws.com" 476 }, 477 "Action": "sts:AssumeRole" 478 } 479 ] 480 } 481 EOT 482 } 483 484 resource "aws_iam_role_policy_attachment" "service-attach" { 485 role = "${aws_iam_role.iam_emr_default_role.id}" 486 policy_arn = "${aws_iam_policy.iam_emr_default_policy.arn}" 487 } 488 489 resource "aws_iam_policy" "iam_emr_default_policy" { 490 name = "iam_emr_default_policy_%d" 491 492 policy = <<EOT 493 { 494 "Version": "2012-10-17", 495 "Statement": [{ 496 "Effect": "Allow", 497 "Resource": "*", 498 "Action": [ 499 "ec2:AuthorizeSecurityGroupEgress", 500 "ec2:AuthorizeSecurityGroupIngress", 501 "ec2:CancelSpotInstanceRequests", 502 "ec2:CreateNetworkInterface", 503 "ec2:CreateSecurityGroup", 504 "ec2:CreateTags", 505 "ec2:DeleteNetworkInterface", 506 "ec2:DeleteSecurityGroup", 507 "ec2:DeleteTags", 508 "ec2:DescribeAvailabilityZones", 509 "ec2:DescribeAccountAttributes", 510 "ec2:DescribeDhcpOptions", 511 "ec2:DescribeInstanceStatus", 512 "ec2:DescribeInstances", 513 "ec2:DescribeKeyPairs", 514 "ec2:DescribeNetworkAcls", 515 "ec2:DescribeNetworkInterfaces", 516 "ec2:DescribePrefixLists", 517 "ec2:DescribeRouteTables", 518 "ec2:DescribeSecurityGroups", 519 "ec2:DescribeSpotInstanceRequests", 520 "ec2:DescribeSpotPriceHistory", 521 "ec2:DescribeSubnets", 522 "ec2:DescribeVpcAttribute", 523 "ec2:DescribeVpcEndpoints", 524 "ec2:DescribeVpcEndpointServices", 525 "ec2:DescribeVpcs", 526 "ec2:DetachNetworkInterface", 527 "ec2:ModifyImageAttribute", 528 "ec2:ModifyInstanceAttribute", 529 "ec2:RequestSpotInstances", 530 "ec2:RevokeSecurityGroupEgress", 531 "ec2:RunInstances", 532 "ec2:TerminateInstances", 533 "ec2:DeleteVolume", 534 "ec2:DescribeVolumeStatus", 535 "ec2:DescribeVolumes", 536 "ec2:DetachVolume", 537 "iam:GetRole", 538 "iam:GetRolePolicy", 539 "iam:ListInstanceProfiles", 540 "iam:ListRolePolicies", 541 "iam:PassRole", 542 "s3:CreateBucket", 543 "s3:Get*", 544 "s3:List*", 545 "sdb:BatchPutAttributes", 546 "sdb:Select", 547 "sqs:CreateQueue", 548 "sqs:Delete*", 549 "sqs:GetQueue*", 550 "sqs:PurgeQueue", 551 "sqs:ReceiveMessage" 552 ] 553 }] 554 } 555 EOT 556 } 557 558 # IAM Role for EC2 Instance Profile 559 resource "aws_iam_role" "iam_emr_profile_role" { 560 name = "iam_emr_profile_role_%d" 561 562 assume_role_policy = <<EOT 563 { 564 "Version": "2008-10-17", 565 "Statement": [ 566 { 567 "Sid": "", 568 "Effect": "Allow", 569 "Principal": { 570 "Service": "ec2.amazonaws.com" 571 }, 572 "Action": "sts:AssumeRole" 573 } 574 ] 575 } 576 EOT 577 } 578 579 resource "aws_iam_instance_profile" "emr_profile" { 580 name = "emr_profile_%d" 581 roles = ["${aws_iam_role.iam_emr_profile_role.name}"] 582 } 583 584 resource "aws_iam_role_policy_attachment" "profile-attach" { 585 role = "${aws_iam_role.iam_emr_profile_role.id}" 586 policy_arn = "${aws_iam_policy.iam_emr_profile_policy.arn}" 587 } 588 589 resource "aws_iam_policy" "iam_emr_profile_policy" { 590 name = "iam_emr_profile_policy_%d" 591 592 policy = <<EOT 593 { 594 "Version": "2012-10-17", 595 "Statement": [{ 596 "Effect": "Allow", 597 "Resource": "*", 598 "Action": [ 599 "cloudwatch:*", 600 "dynamodb:*", 601 "ec2:Describe*", 602 "elasticmapreduce:Describe*", 603 "elasticmapreduce:ListBootstrapActions", 604 "elasticmapreduce:ListClusters", 605 "elasticmapreduce:ListInstanceGroups", 606 "elasticmapreduce:ListInstances", 607 "elasticmapreduce:ListSteps", 608 "kinesis:CreateStream", 609 "kinesis:DeleteStream", 610 "kinesis:DescribeStream", 611 "kinesis:GetRecords", 612 "kinesis:GetShardIterator", 613 "kinesis:MergeShards", 614 "kinesis:PutRecord", 615 "kinesis:SplitShard", 616 "rds:Describe*", 617 "s3:*", 618 "sdb:*", 619 "sns:*", 620 "sqs:*" 621 ] 622 }] 623 } 624 EOT 625 } 626 627 # IAM Role for autoscaling 628 resource "aws_iam_role" "emr-autoscaling-role" { 629 name = "EMR_AutoScaling_DefaultRole_%d" 630 assume_role_policy = "${data.aws_iam_policy_document.emr-autoscaling-role-policy.json}" 631 } 632 633 data "aws_iam_policy_document" "emr-autoscaling-role-policy" { 634 statement { 635 effect = "Allow" 636 actions = ["sts:AssumeRole"] 637 638 principals = { 639 type = "Service" 640 identifiers = ["elasticmapreduce.amazonaws.com","application-autoscaling.amazonaws.com"] 641 } 642 } 643 } 644 645 resource "aws_iam_role_policy_attachment" "emr-autoscaling-role" { 646 role = "${aws_iam_role.emr-autoscaling-role.name}" 647 policy_arn = "arn:aws:iam::aws:policy/service-role/AmazonElasticMapReduceforAutoScalingRole" 648 } 649 650 resource "aws_appautoscaling_target" "bar" { 651 service_namespace = "elasticmapreduce" 652 resource_id = "instancegroup/${aws_emr_cluster.tf-test-cluster.id}/${aws_emr_instance_group.task.id}" 653 scalable_dimension = "elasticmapreduce:instancegroup:InstanceCount" 654 role_arn = "${aws_iam_role.emr-autoscaling-role.arn}" 655 min_capacity = 1 656 max_capacity = 8 657 } 658 659 `, rInt, rInt, rInt, rInt, rInt, rInt, rInt, rInt, rInt, rInt) 660 } 661 662 var testAccAWSAppautoscalingTargetSpotFleetRequestConfig = fmt.Sprintf(` 663 resource "aws_iam_role" "fleet_role" { 664 assume_role_policy = <<EOF 665 { 666 "Version": "2012-10-17", 667 "Statement": [ 668 { 669 "Effect": "Allow", 670 "Principal": { 671 "Service": [ 672 "spotfleet.amazonaws.com", 673 "ec2.amazonaws.com" 674 ] 675 }, 676 "Action": "sts:AssumeRole" 677 } 678 ] 679 } 680 EOF 681 } 682 683 resource "aws_iam_role_policy_attachment" "fleet_role_policy" { 684 role = "${aws_iam_role.fleet_role.name}" 685 policy_arn = "arn:aws:iam::aws:policy/service-role/AmazonEC2SpotFleetRole" 686 } 687 688 resource "aws_spot_fleet_request" "test" { 689 iam_fleet_role = "${aws_iam_role.fleet_role.arn}" 690 spot_price = "0.005" 691 target_capacity = 2 692 valid_until = "2019-11-04T20:44:20Z" 693 terminate_instances_with_expiration = true 694 695 launch_specification { 696 instance_type = "m3.medium" 697 ami = "ami-d06a90b0" 698 } 699 } 700 701 resource "aws_iam_role" "autoscale_role" { 702 assume_role_policy = <<EOF 703 { 704 "Version": "2012-10-17", 705 "Statement": [ 706 { 707 "Effect": "Allow", 708 "Principal": { 709 "Service": "application-autoscaling.amazonaws.com" 710 }, 711 "Action": "sts:AssumeRole" 712 } 713 ] 714 } 715 EOF 716 } 717 718 resource "aws_iam_role_policy_attachment" "autoscale_role_policy_a" { 719 role = "${aws_iam_role.autoscale_role.name}" 720 policy_arn = "arn:aws:iam::aws:policy/service-role/AmazonEC2SpotFleetRole" 721 } 722 723 resource "aws_iam_role_policy_attachment" "autoscale_role_policy_b" { 724 role = "${aws_iam_role.autoscale_role.name}" 725 policy_arn = "arn:aws:iam::aws:policy/service-role/AmazonEC2SpotFleetAutoscaleRole" 726 } 727 728 resource "aws_appautoscaling_target" "test" { 729 service_namespace = "ec2" 730 resource_id = "spot-fleet-request/${aws_spot_fleet_request.test.id}" 731 scalable_dimension = "ec2:spot-fleet-request:TargetCapacity" 732 role_arn = "${aws_iam_role.autoscale_role.arn}" 733 min_capacity = 1 734 max_capacity = 3 735 } 736 `)