github.com/vtorhonen/terraform@v0.9.0-beta2.0.20170307220345-5d894e4ffda7/builtin/providers/aws/resource_aws_opsworks_application.go (about)

     1  package aws
     2  
     3  import (
     4  	"fmt"
     5  	"log"
     6  	"strings"
     7  	"time"
     8  
     9  	"github.com/aws/aws-sdk-go/aws"
    10  	"github.com/aws/aws-sdk-go/aws/awserr"
    11  	"github.com/aws/aws-sdk-go/service/opsworks"
    12  	"github.com/hashicorp/terraform/helper/resource"
    13  	"github.com/hashicorp/terraform/helper/schema"
    14  )
    15  
    16  func resourceAwsOpsworksApplication() *schema.Resource {
    17  	return &schema.Resource{
    18  
    19  		Create: resourceAwsOpsworksApplicationCreate,
    20  		Read:   resourceAwsOpsworksApplicationRead,
    21  		Update: resourceAwsOpsworksApplicationUpdate,
    22  		Delete: resourceAwsOpsworksApplicationDelete,
    23  		Schema: map[string]*schema.Schema{
    24  			"id": &schema.Schema{
    25  				Type:     schema.TypeString,
    26  				Computed: true,
    27  			},
    28  			"name": &schema.Schema{
    29  				Type:     schema.TypeString,
    30  				Required: true,
    31  			},
    32  			"short_name": &schema.Schema{
    33  				Type:     schema.TypeString,
    34  				Computed: true,
    35  				Optional: true,
    36  			},
    37  			// aws-flow-ruby | java | rails | php | nodejs | static | other
    38  			"type": &schema.Schema{
    39  				Type:     schema.TypeString,
    40  				Required: true,
    41  				ValidateFunc: func(v interface{}, k string) (ws []string, errors []error) {
    42  					value := v.(string)
    43  
    44  					expected := [7]string{"aws-flow-ruby", "java", "rails", "php", "nodejs", "static", "other"}
    45  
    46  					found := false
    47  					for _, b := range expected {
    48  						if b == value {
    49  							found = true
    50  						}
    51  					}
    52  					if !found {
    53  						errors = append(errors, fmt.Errorf(
    54  							"%q has to be one of [aws-flow-ruby, java, rails, php, nodejs, static, other]", k))
    55  					}
    56  					return
    57  				},
    58  			},
    59  			"stack_id": &schema.Schema{
    60  				Type:     schema.TypeString,
    61  				Required: true,
    62  			},
    63  			// TODO: the following 4 vals are really part of the Attributes array. We should validate that only ones relevant to the chosen type are set, perhaps. (what is the default type? how do they map?)
    64  			"document_root": &schema.Schema{
    65  				Type:     schema.TypeString,
    66  				Optional: true,
    67  				//Default:  "public",
    68  			},
    69  			"rails_env": &schema.Schema{
    70  				Type:     schema.TypeString,
    71  				Optional: true,
    72  				//Default:  "production",
    73  			},
    74  			"auto_bundle_on_deploy": &schema.Schema{
    75  				Type:     schema.TypeString,
    76  				Optional: true,
    77  				//Default:  true,
    78  			},
    79  			"aws_flow_ruby_settings": &schema.Schema{
    80  				Type:     schema.TypeString,
    81  				Optional: true,
    82  			},
    83  			"app_source": &schema.Schema{
    84  				Type:     schema.TypeList,
    85  				Optional: true,
    86  				Computed: true,
    87  				Elem: &schema.Resource{
    88  					Schema: map[string]*schema.Schema{
    89  						"type": &schema.Schema{
    90  							Type:     schema.TypeString,
    91  							Required: true,
    92  						},
    93  
    94  						"url": &schema.Schema{
    95  							Type:     schema.TypeString,
    96  							Optional: true,
    97  						},
    98  
    99  						"username": &schema.Schema{
   100  							Type:     schema.TypeString,
   101  							Optional: true,
   102  						},
   103  
   104  						"password": &schema.Schema{
   105  							Type:     schema.TypeString,
   106  							Optional: true,
   107  						},
   108  
   109  						"revision": &schema.Schema{
   110  							Type:     schema.TypeString,
   111  							Optional: true,
   112  						},
   113  
   114  						"ssh_key": &schema.Schema{
   115  							Type:     schema.TypeString,
   116  							Optional: true,
   117  						},
   118  					},
   119  				},
   120  			},
   121  			// AutoSelectOpsworksMysqlInstance, OpsworksMysqlInstance, or RdsDbInstance.
   122  			// anything beside auto select will lead into failure in case the instance doesn't exist
   123  			// XXX: validation?
   124  			"data_source_type": &schema.Schema{
   125  				Type:     schema.TypeString,
   126  				Optional: true,
   127  			},
   128  			"data_source_database_name": &schema.Schema{
   129  				Type:     schema.TypeString,
   130  				Optional: true,
   131  			},
   132  			"data_source_arn": &schema.Schema{
   133  				Type:     schema.TypeString,
   134  				Optional: true,
   135  			},
   136  			"description": &schema.Schema{
   137  				Type:     schema.TypeString,
   138  				Optional: true,
   139  			},
   140  			"domains": &schema.Schema{
   141  				Type:     schema.TypeList,
   142  				Optional: true,
   143  				Elem:     &schema.Schema{Type: schema.TypeString},
   144  			},
   145  			"environment": &schema.Schema{
   146  				Type:     schema.TypeSet,
   147  				Optional: true,
   148  				Elem: &schema.Resource{
   149  					Schema: map[string]*schema.Schema{
   150  						"key": &schema.Schema{
   151  							Type:     schema.TypeString,
   152  							Required: true,
   153  						},
   154  						"value": &schema.Schema{
   155  							Type:     schema.TypeString,
   156  							Required: true,
   157  						},
   158  						"secure": &schema.Schema{
   159  							Type:     schema.TypeBool,
   160  							Optional: true,
   161  							Default:  true,
   162  						},
   163  					},
   164  				},
   165  			},
   166  			"enable_ssl": &schema.Schema{
   167  				Type:     schema.TypeBool,
   168  				Optional: true,
   169  				Default:  false,
   170  			},
   171  			"ssl_configuration": &schema.Schema{
   172  				Type:     schema.TypeList,
   173  				Optional: true,
   174  				//Computed: true,
   175  				Elem: &schema.Resource{
   176  					Schema: map[string]*schema.Schema{
   177  						"certificate": &schema.Schema{
   178  							Type:     schema.TypeString,
   179  							Required: true,
   180  							StateFunc: func(v interface{}) string {
   181  								switch v.(type) {
   182  								case string:
   183  									return strings.TrimSpace(v.(string))
   184  								default:
   185  									return ""
   186  								}
   187  							},
   188  						},
   189  						"private_key": &schema.Schema{
   190  							Type:     schema.TypeString,
   191  							Required: true,
   192  							StateFunc: func(v interface{}) string {
   193  								switch v.(type) {
   194  								case string:
   195  									return strings.TrimSpace(v.(string))
   196  								default:
   197  									return ""
   198  								}
   199  							},
   200  						},
   201  						"chain": &schema.Schema{
   202  							Type:     schema.TypeString,
   203  							Optional: true,
   204  							StateFunc: func(v interface{}) string {
   205  								switch v.(type) {
   206  								case string:
   207  									return strings.TrimSpace(v.(string))
   208  								default:
   209  									return ""
   210  								}
   211  							},
   212  						},
   213  					},
   214  				},
   215  			},
   216  		},
   217  	}
   218  }
   219  
   220  func resourceAwsOpsworksApplicationValidate(d *schema.ResourceData) error {
   221  	appSourceCount := d.Get("app_source.#").(int)
   222  	if appSourceCount > 1 {
   223  		return fmt.Errorf("Only one app_source is permitted.")
   224  	}
   225  
   226  	sslCount := d.Get("ssl_configuration.#").(int)
   227  	if sslCount > 1 {
   228  		return fmt.Errorf("Only one ssl_configuration is permitted.")
   229  	}
   230  
   231  	if d.Get("type") == opsworks.AppTypeNodejs || d.Get("type") == opsworks.AppTypeJava {
   232  		// allowed attributes: none
   233  		if d.Get("document_root").(string) != "" || d.Get("rails_env").(string) != "" || d.Get("auto_bundle_on_deploy").(string) != "" || d.Get("aws_flow_ruby_settings").(string) != "" {
   234  			return fmt.Errorf("No additional attributes are allowed for app type '%s'.", d.Get("type").(string))
   235  		}
   236  	} else if d.Get("type") == opsworks.AppTypeRails {
   237  		// allowed attributes: document_root, rails_env, auto_bundle_on_deploy
   238  		if d.Get("aws_flow_ruby_settings").(string) != "" {
   239  			return fmt.Errorf("Only 'document_root, rails_env, auto_bundle_on_deploy' are allowed for app type '%s'.", opsworks.AppTypeRails)
   240  		}
   241  		// rails_env is required
   242  		if _, ok := d.GetOk("rails_env"); !ok {
   243  			return fmt.Errorf("Set rails_env must be set if type is set to rails.")
   244  		}
   245  	} else if d.Get("type") == opsworks.AppTypePhp || d.Get("type") == opsworks.AppTypeStatic || d.Get("type") == opsworks.AppTypeOther {
   246  		log.Printf("[DEBUG] the app type is : %s", d.Get("type").(string))
   247  		log.Printf("[DEBUG] the attributes are: document_root '%s', rails_env '%s', auto_bundle_on_deploy '%s', aws_flow_ruby_settings '%s'", d.Get("document_root").(string), d.Get("rails_env").(string), d.Get("auto_bundle_on_deploy").(string), d.Get("aws_flow_ruby_settings").(string))
   248  		// allowed attributes: document_root
   249  		if d.Get("rails_env").(string) != "" || d.Get("auto_bundle_on_deploy").(string) != "" || d.Get("aws_flow_ruby_settings").(string) != "" {
   250  			return fmt.Errorf("Only 'document_root' is allowed for app type '%s'.", d.Get("type").(string))
   251  		}
   252  	} else if d.Get("type") == opsworks.AppTypeAwsFlowRuby {
   253  		// allowed attributes: aws_flow_ruby_settings
   254  		if d.Get("document_root").(string) != "" || d.Get("rails_env").(string) != "" || d.Get("auto_bundle_on_deploy").(string) != "" {
   255  			return fmt.Errorf("Only 'aws_flow_ruby_settings' is allowed for app type '%s'.", d.Get("type").(string))
   256  		}
   257  	}
   258  
   259  	return nil
   260  }
   261  
   262  func resourceAwsOpsworksApplicationRead(d *schema.ResourceData, meta interface{}) error {
   263  	client := meta.(*AWSClient).opsworksconn
   264  
   265  	req := &opsworks.DescribeAppsInput{
   266  		AppIds: []*string{
   267  			aws.String(d.Id()),
   268  		},
   269  	}
   270  
   271  	log.Printf("[DEBUG] Reading OpsWorks app: %s", d.Id())
   272  
   273  	resp, err := client.DescribeApps(req)
   274  	if err != nil {
   275  		if awserr, ok := err.(awserr.Error); ok {
   276  			if awserr.Code() == "ResourceNotFoundException" {
   277  				log.Printf("[INFO] App not found: %s", d.Id())
   278  				d.SetId("")
   279  				return nil
   280  			}
   281  		}
   282  		return err
   283  	}
   284  
   285  	app := resp.Apps[0]
   286  
   287  	d.Set("name", app.Name)
   288  	d.Set("stack_id", app.StackId)
   289  	d.Set("type", app.Type)
   290  	d.Set("description", app.Description)
   291  	d.Set("domains", flattenStringList(app.Domains))
   292  	d.Set("enable_ssl", app.EnableSsl)
   293  	resourceAwsOpsworksSetApplicationSsl(d, app.SslConfiguration)
   294  	resourceAwsOpsworksSetApplicationSource(d, app.AppSource)
   295  	resourceAwsOpsworksSetApplicationDataSources(d, app.DataSources)
   296  	resourceAwsOpsworksSetApplicationEnvironmentVariable(d, app.Environment)
   297  	resourceAwsOpsworksSetApplicationAttributes(d, app.Attributes)
   298  	return nil
   299  }
   300  
   301  func resourceAwsOpsworksApplicationCreate(d *schema.ResourceData, meta interface{}) error {
   302  	client := meta.(*AWSClient).opsworksconn
   303  
   304  	err := resourceAwsOpsworksApplicationValidate(d)
   305  	if err != nil {
   306  		return err
   307  	}
   308  
   309  	req := &opsworks.CreateAppInput{
   310  		Name:             aws.String(d.Get("name").(string)),
   311  		Shortname:        aws.String(d.Get("short_name").(string)),
   312  		StackId:          aws.String(d.Get("stack_id").(string)),
   313  		Type:             aws.String(d.Get("type").(string)),
   314  		Description:      aws.String(d.Get("description").(string)),
   315  		Domains:          expandStringList(d.Get("domains").([]interface{})),
   316  		EnableSsl:        aws.Bool(d.Get("enable_ssl").(bool)),
   317  		SslConfiguration: resourceAwsOpsworksApplicationSsl(d),
   318  		AppSource:        resourceAwsOpsworksApplicationSource(d),
   319  		DataSources:      resourceAwsOpsworksApplicationDataSources(d),
   320  		Environment:      resourceAwsOpsworksApplicationEnvironmentVariable(d),
   321  		Attributes:       resourceAwsOpsworksApplicationAttributes(d),
   322  	}
   323  
   324  	var resp *opsworks.CreateAppOutput
   325  	err = resource.Retry(2*time.Minute, func() *resource.RetryError {
   326  		var cerr error
   327  		resp, cerr = client.CreateApp(req)
   328  		if cerr != nil {
   329  			log.Printf("[INFO] client error")
   330  			if opserr, ok := cerr.(awserr.Error); ok {
   331  				// XXX: handle errors
   332  				log.Printf("[ERROR] OpsWorks error: %s message: %s", opserr.Code(), opserr.Message())
   333  				return resource.RetryableError(cerr)
   334  			}
   335  			return resource.NonRetryableError(cerr)
   336  		}
   337  		return nil
   338  	})
   339  
   340  	if err != nil {
   341  		return err
   342  	}
   343  
   344  	appID := *resp.AppId
   345  	d.SetId(appID)
   346  	d.Set("id", appID)
   347  
   348  	return resourceAwsOpsworksApplicationRead(d, meta)
   349  }
   350  
   351  func resourceAwsOpsworksApplicationUpdate(d *schema.ResourceData, meta interface{}) error {
   352  	client := meta.(*AWSClient).opsworksconn
   353  
   354  	err := resourceAwsOpsworksApplicationValidate(d)
   355  	if err != nil {
   356  		return err
   357  	}
   358  
   359  	req := &opsworks.UpdateAppInput{
   360  		AppId:            aws.String(d.Id()),
   361  		Name:             aws.String(d.Get("name").(string)),
   362  		Type:             aws.String(d.Get("type").(string)),
   363  		Description:      aws.String(d.Get("description").(string)),
   364  		Domains:          expandStringList(d.Get("domains").([]interface{})),
   365  		EnableSsl:        aws.Bool(d.Get("enable_ssl").(bool)),
   366  		SslConfiguration: resourceAwsOpsworksApplicationSsl(d),
   367  		AppSource:        resourceAwsOpsworksApplicationSource(d),
   368  		DataSources:      resourceAwsOpsworksApplicationDataSources(d),
   369  		Environment:      resourceAwsOpsworksApplicationEnvironmentVariable(d),
   370  		Attributes:       resourceAwsOpsworksApplicationAttributes(d),
   371  	}
   372  
   373  	log.Printf("[DEBUG] Updating OpsWorks layer: %s", d.Id())
   374  
   375  	err = resource.Retry(2*time.Minute, func() *resource.RetryError {
   376  		_, cerr := client.UpdateApp(req)
   377  		if cerr != nil {
   378  			log.Printf("[INFO] client error")
   379  			if opserr, ok := cerr.(awserr.Error); ok {
   380  				// XXX: handle errors
   381  				log.Printf("[ERROR] OpsWorks error: %s message: %s", opserr.Code(), opserr.Message())
   382  				return resource.NonRetryableError(cerr)
   383  			}
   384  			return resource.RetryableError(cerr)
   385  		}
   386  		return nil
   387  	})
   388  
   389  	if err != nil {
   390  		return err
   391  	}
   392  	return resourceAwsOpsworksApplicationRead(d, meta)
   393  }
   394  
   395  func resourceAwsOpsworksApplicationDelete(d *schema.ResourceData, meta interface{}) error {
   396  	client := meta.(*AWSClient).opsworksconn
   397  
   398  	req := &opsworks.DeleteAppInput{
   399  		AppId: aws.String(d.Id()),
   400  	}
   401  
   402  	log.Printf("[DEBUG] Deleting OpsWorks application: %s", d.Id())
   403  
   404  	_, err := client.DeleteApp(req)
   405  	return err
   406  }
   407  
   408  func resourceAwsOpsworksSetApplicationEnvironmentVariable(d *schema.ResourceData, v []*opsworks.EnvironmentVariable) {
   409  	log.Printf("[DEBUG] envs: %s %d", v, len(v))
   410  	if len(v) == 0 {
   411  		d.Set("environment", nil)
   412  		return
   413  	}
   414  	newValue := make([]*map[string]interface{}, len(v))
   415  
   416  	for i := 0; i < len(v); i++ {
   417  		config := v[i]
   418  		data := make(map[string]interface{})
   419  		newValue[i] = &data
   420  
   421  		if config.Key != nil {
   422  			data["key"] = *config.Key
   423  		}
   424  		if config.Value != nil {
   425  			data["value"] = *config.Value
   426  		}
   427  		if config.Secure != nil {
   428  
   429  			if bool(*config.Secure) {
   430  				data["secure"] = &opsworksTrueString
   431  			} else {
   432  				data["secure"] = &opsworksFalseString
   433  			}
   434  		}
   435  		log.Printf("[DEBUG] v: %s", data)
   436  	}
   437  
   438  	d.Set("environment", newValue)
   439  }
   440  
   441  func resourceAwsOpsworksApplicationEnvironmentVariable(d *schema.ResourceData) []*opsworks.EnvironmentVariable {
   442  	environmentVariables := d.Get("environment").(*schema.Set).List()
   443  	result := make([]*opsworks.EnvironmentVariable, len(environmentVariables))
   444  
   445  	for i := 0; i < len(environmentVariables); i++ {
   446  		env := environmentVariables[i].(map[string]interface{})
   447  
   448  		result[i] = &opsworks.EnvironmentVariable{
   449  			Key:    aws.String(env["key"].(string)),
   450  			Value:  aws.String(env["value"].(string)),
   451  			Secure: aws.Bool(env["secure"].(bool)),
   452  		}
   453  	}
   454  	return result
   455  }
   456  
   457  func resourceAwsOpsworksApplicationSource(d *schema.ResourceData) *opsworks.Source {
   458  	count := d.Get("app_source.#").(int)
   459  	if count == 0 {
   460  		return nil
   461  	}
   462  
   463  	return &opsworks.Source{
   464  		Type:     aws.String(d.Get("app_source.0.type").(string)),
   465  		Url:      aws.String(d.Get("app_source.0.url").(string)),
   466  		Username: aws.String(d.Get("app_source.0.username").(string)),
   467  		Password: aws.String(d.Get("app_source.0.password").(string)),
   468  		Revision: aws.String(d.Get("app_source.0.revision").(string)),
   469  		SshKey:   aws.String(d.Get("app_source.0.ssh_key").(string)),
   470  	}
   471  }
   472  
   473  func resourceAwsOpsworksSetApplicationSource(d *schema.ResourceData, v *opsworks.Source) {
   474  	nv := make([]interface{}, 0, 1)
   475  	if v != nil {
   476  		m := make(map[string]interface{})
   477  		if v.Type != nil {
   478  			m["type"] = *v.Type
   479  		}
   480  		if v.Url != nil {
   481  			m["url"] = *v.Url
   482  		}
   483  		if v.Username != nil {
   484  			m["username"] = *v.Username
   485  		}
   486  		if v.Password != nil {
   487  			m["password"] = *v.Password
   488  		}
   489  		if v.Revision != nil {
   490  			m["revision"] = *v.Revision
   491  		}
   492  		nv = append(nv, m)
   493  	}
   494  
   495  	err := d.Set("app_source", nv)
   496  	if err != nil {
   497  		// should never happen
   498  		panic(err)
   499  	}
   500  }
   501  
   502  func resourceAwsOpsworksApplicationDataSources(d *schema.ResourceData) []*opsworks.DataSource {
   503  	arn := d.Get("data_source_arn").(string)
   504  	databaseName := d.Get("data_source_database_name").(string)
   505  	databaseType := d.Get("data_source_type").(string)
   506  
   507  	result := make([]*opsworks.DataSource, 1)
   508  
   509  	if len(arn) > 0 || len(databaseName) > 0 || len(databaseType) > 0 {
   510  		result[0] = &opsworks.DataSource{
   511  			Arn:          aws.String(arn),
   512  			DatabaseName: aws.String(databaseName),
   513  			Type:         aws.String(databaseType),
   514  		}
   515  	}
   516  	return result
   517  }
   518  
   519  func resourceAwsOpsworksSetApplicationDataSources(d *schema.ResourceData, v []*opsworks.DataSource) {
   520  	d.Set("data_source_arn", nil)
   521  	d.Set("data_source_database_name", nil)
   522  	d.Set("data_source_type", nil)
   523  
   524  	if len(v) == 0 {
   525  		return
   526  	}
   527  
   528  	d.Set("data_source_arn", v[0].Arn)
   529  	d.Set("data_source_database_name", v[0].DatabaseName)
   530  	d.Set("data_source_type", v[0].Type)
   531  }
   532  
   533  func resourceAwsOpsworksApplicationSsl(d *schema.ResourceData) *opsworks.SslConfiguration {
   534  	count := d.Get("ssl_configuration.#").(int)
   535  	if count == 0 {
   536  		return nil
   537  	}
   538  
   539  	return &opsworks.SslConfiguration{
   540  		PrivateKey:  aws.String(d.Get("ssl_configuration.0.private_key").(string)),
   541  		Certificate: aws.String(d.Get("ssl_configuration.0.certificate").(string)),
   542  		Chain:       aws.String(d.Get("ssl_configuration.0.chain").(string)),
   543  	}
   544  }
   545  
   546  func resourceAwsOpsworksSetApplicationSsl(d *schema.ResourceData, v *opsworks.SslConfiguration) {
   547  	nv := make([]interface{}, 0, 1)
   548  	set := false
   549  	if v != nil {
   550  		m := make(map[string]interface{})
   551  		if v.PrivateKey != nil {
   552  			m["private_key"] = *v.PrivateKey
   553  			set = true
   554  		}
   555  		if v.Certificate != nil {
   556  			m["certificate"] = *v.Certificate
   557  			set = true
   558  		}
   559  		if v.Chain != nil {
   560  			m["chain"] = *v.Chain
   561  			set = true
   562  		}
   563  		if set {
   564  			nv = append(nv, m)
   565  		}
   566  	}
   567  
   568  	err := d.Set("ssl_configuration", nv)
   569  	if err != nil {
   570  		// should never happen
   571  		panic(err)
   572  	}
   573  }
   574  
   575  func resourceAwsOpsworksApplicationAttributes(d *schema.ResourceData) map[string]*string {
   576  	attributes := make(map[string]*string)
   577  
   578  	if val := d.Get("document_root").(string); len(val) > 0 {
   579  		attributes[opsworks.AppAttributesKeysDocumentRoot] = aws.String(val)
   580  	}
   581  	if val := d.Get("aws_flow_ruby_settings").(string); len(val) > 0 {
   582  		attributes[opsworks.AppAttributesKeysAwsFlowRubySettings] = aws.String(val)
   583  	}
   584  	if val := d.Get("rails_env").(string); len(val) > 0 {
   585  		attributes[opsworks.AppAttributesKeysRailsEnv] = aws.String(val)
   586  	}
   587  	if val := d.Get("auto_bundle_on_deploy").(string); len(val) > 0 {
   588  		if val == "1" {
   589  			val = "true"
   590  		} else if val == "0" {
   591  			val = "false"
   592  		}
   593  		attributes[opsworks.AppAttributesKeysAutoBundleOnDeploy] = aws.String(val)
   594  	}
   595  
   596  	return attributes
   597  }
   598  
   599  func resourceAwsOpsworksSetApplicationAttributes(d *schema.ResourceData, v map[string]*string) {
   600  	d.Set("document_root", nil)
   601  	d.Set("rails_env", nil)
   602  	d.Set("aws_flow_ruby_settings", nil)
   603  	d.Set("auto_bundle_on_deploy", nil)
   604  
   605  	if d.Get("type") == opsworks.AppTypeNodejs || d.Get("type") == opsworks.AppTypeJava {
   606  		return
   607  	} else if d.Get("type") == opsworks.AppTypeRails {
   608  		if val, ok := v[opsworks.AppAttributesKeysDocumentRoot]; ok {
   609  			d.Set("document_root", val)
   610  		}
   611  		if val, ok := v[opsworks.AppAttributesKeysRailsEnv]; ok {
   612  			d.Set("rails_env", val)
   613  		}
   614  		if val, ok := v[opsworks.AppAttributesKeysAutoBundleOnDeploy]; ok {
   615  			d.Set("auto_bundle_on_deploy", val)
   616  		}
   617  		return
   618  	} else if d.Get("type") == opsworks.AppTypePhp || d.Get("type") == opsworks.AppTypeStatic || d.Get("type") == opsworks.AppTypeOther {
   619  		if val, ok := v[opsworks.AppAttributesKeysDocumentRoot]; ok {
   620  			d.Set("document_root", val)
   621  		}
   622  		return
   623  	} else if d.Get("type") == opsworks.AppTypeAwsFlowRuby {
   624  		if val, ok := v[opsworks.AppAttributesKeysAwsFlowRubySettings]; ok {
   625  			d.Set("aws_flow_ruby_settings", val)
   626  		}
   627  		return
   628  	}
   629  
   630  	return
   631  }