github.com/nathanielks/terraform@v0.6.1-0.20170509030759-13e1a62319dc/builtin/providers/aws/resource_aws_codebuild_project.go (about)

     1  package aws
     2  
     3  import (
     4  	"bytes"
     5  	"fmt"
     6  	"log"
     7  	"regexp"
     8  	"time"
     9  
    10  	"github.com/aws/aws-sdk-go/aws"
    11  	"github.com/aws/aws-sdk-go/service/codebuild"
    12  	"github.com/hashicorp/terraform/helper/hashcode"
    13  	"github.com/hashicorp/terraform/helper/resource"
    14  	"github.com/hashicorp/terraform/helper/schema"
    15  )
    16  
    17  func resourceAwsCodeBuildProject() *schema.Resource {
    18  	return &schema.Resource{
    19  		Create: resourceAwsCodeBuildProjectCreate,
    20  		Read:   resourceAwsCodeBuildProjectRead,
    21  		Update: resourceAwsCodeBuildProjectUpdate,
    22  		Delete: resourceAwsCodeBuildProjectDelete,
    23  
    24  		Schema: map[string]*schema.Schema{
    25  			"artifacts": &schema.Schema{
    26  				Type:     schema.TypeSet,
    27  				Required: true,
    28  				MaxItems: 1,
    29  				Elem: &schema.Resource{
    30  					Schema: map[string]*schema.Schema{
    31  						"name": {
    32  							Type:     schema.TypeString,
    33  							Optional: true,
    34  						},
    35  						"location": {
    36  							Type:     schema.TypeString,
    37  							Optional: true,
    38  						},
    39  						"namespace_type": {
    40  							Type:         schema.TypeString,
    41  							Optional:     true,
    42  							ValidateFunc: validateAwsCodeBuildArifactsNamespaceType,
    43  						},
    44  						"packaging": {
    45  							Type:     schema.TypeString,
    46  							Optional: true,
    47  						},
    48  						"path": {
    49  							Type:     schema.TypeString,
    50  							Optional: true,
    51  						},
    52  						"type": {
    53  							Type:         schema.TypeString,
    54  							Required:     true,
    55  							ValidateFunc: validateAwsCodeBuildArifactsType,
    56  						},
    57  					},
    58  				},
    59  				Set: resourceAwsCodeBuildProjectArtifactsHash,
    60  			},
    61  			"description": {
    62  				Type:         schema.TypeString,
    63  				Optional:     true,
    64  				Computed:     true,
    65  				ValidateFunc: validateAwsCodeBuildProjectDescription,
    66  			},
    67  			"encryption_key": {
    68  				Type:     schema.TypeString,
    69  				Optional: true,
    70  				Computed: true,
    71  			},
    72  			"environment": &schema.Schema{
    73  				Type:     schema.TypeSet,
    74  				Required: true,
    75  				MaxItems: 1,
    76  				Elem: &schema.Resource{
    77  					Schema: map[string]*schema.Schema{
    78  						"compute_type": {
    79  							Type:         schema.TypeString,
    80  							Required:     true,
    81  							ValidateFunc: validateAwsCodeBuildEnvironmentComputeType,
    82  						},
    83  						"environment_variable": &schema.Schema{
    84  							Type:     schema.TypeList,
    85  							Optional: true,
    86  							Computed: true,
    87  							Elem: &schema.Resource{
    88  								Schema: map[string]*schema.Schema{
    89  									"name": {
    90  										Type:     schema.TypeString,
    91  										Required: true,
    92  									},
    93  									"value": {
    94  										Type:     schema.TypeString,
    95  										Required: true,
    96  									},
    97  								},
    98  							},
    99  						},
   100  						"image": {
   101  							Type:     schema.TypeString,
   102  							Required: true,
   103  						},
   104  						"type": {
   105  							Type:         schema.TypeString,
   106  							Required:     true,
   107  							ValidateFunc: validateAwsCodeBuildEnvironmentType,
   108  						},
   109  					},
   110  				},
   111  				Set: resourceAwsCodeBuildProjectEnvironmentHash,
   112  			},
   113  			"name": {
   114  				Type:         schema.TypeString,
   115  				Required:     true,
   116  				ForceNew:     true,
   117  				ValidateFunc: validateAwsCodeBuildProjectName,
   118  			},
   119  			"service_role": {
   120  				Type:     schema.TypeString,
   121  				Optional: true,
   122  				Computed: true,
   123  			},
   124  			"source": &schema.Schema{
   125  				Type: schema.TypeSet,
   126  				Elem: &schema.Resource{
   127  					Schema: map[string]*schema.Schema{
   128  						"auth": &schema.Schema{
   129  							Type: schema.TypeSet,
   130  							Elem: &schema.Resource{
   131  								Schema: map[string]*schema.Schema{
   132  									"resource": {
   133  										Type:     schema.TypeString,
   134  										Optional: true,
   135  									},
   136  									"type": {
   137  										Type:         schema.TypeString,
   138  										Required:     true,
   139  										ValidateFunc: validateAwsCodeBuildSourceAuthType,
   140  									},
   141  								},
   142  							},
   143  							Optional: true,
   144  						},
   145  						"buildspec": {
   146  							Type:     schema.TypeString,
   147  							Optional: true,
   148  						},
   149  						"location": {
   150  							Type:     schema.TypeString,
   151  							Optional: true,
   152  						},
   153  						"type": {
   154  							Type:         schema.TypeString,
   155  							Required:     true,
   156  							ValidateFunc: validateAwsCodeBuildSourceType,
   157  						},
   158  					},
   159  				},
   160  				Required: true,
   161  				MaxItems: 1,
   162  			},
   163  			"timeout": {
   164  				Type:         schema.TypeInt,
   165  				Optional:     true,
   166  				ValidateFunc: validateAwsCodeBuildTimeout,
   167  				Removed:      "This field has been removed. Please use build_timeout instead",
   168  			},
   169  			"build_timeout": {
   170  				Type:         schema.TypeInt,
   171  				Optional:     true,
   172  				Default:      "60",
   173  				ValidateFunc: validateAwsCodeBuildTimeout,
   174  			},
   175  			"tags": tagsSchema(),
   176  		},
   177  	}
   178  }
   179  
   180  func resourceAwsCodeBuildProjectCreate(d *schema.ResourceData, meta interface{}) error {
   181  	conn := meta.(*AWSClient).codebuildconn
   182  
   183  	projectEnv := expandProjectEnvironment(d)
   184  	projectSource := expandProjectSource(d)
   185  	projectArtifacts := expandProjectArtifacts(d)
   186  
   187  	params := &codebuild.CreateProjectInput{
   188  		Environment: projectEnv,
   189  		Name:        aws.String(d.Get("name").(string)),
   190  		Source:      &projectSource,
   191  		Artifacts:   &projectArtifacts,
   192  	}
   193  
   194  	if v, ok := d.GetOk("description"); ok {
   195  		params.Description = aws.String(v.(string))
   196  	}
   197  
   198  	if v, ok := d.GetOk("encryption_key"); ok {
   199  		params.EncryptionKey = aws.String(v.(string))
   200  	}
   201  
   202  	if v, ok := d.GetOk("service_role"); ok {
   203  		params.ServiceRole = aws.String(v.(string))
   204  	}
   205  
   206  	if v, ok := d.GetOk("build_timeout"); ok {
   207  		params.TimeoutInMinutes = aws.Int64(int64(v.(int)))
   208  	}
   209  
   210  	if v, ok := d.GetOk("tags"); ok {
   211  		params.Tags = tagsFromMapCodeBuild(v.(map[string]interface{}))
   212  	}
   213  
   214  	var resp *codebuild.CreateProjectOutput
   215  	err := resource.Retry(2*time.Minute, func() *resource.RetryError {
   216  		var err error
   217  
   218  		resp, err = conn.CreateProject(params)
   219  
   220  		if err != nil {
   221  			return resource.RetryableError(err)
   222  		}
   223  
   224  		return resource.NonRetryableError(err)
   225  	})
   226  
   227  	if err != nil {
   228  		return fmt.Errorf("[ERROR] Error creating CodeBuild project: %s", err)
   229  	}
   230  
   231  	d.SetId(*resp.Project.Arn)
   232  
   233  	return resourceAwsCodeBuildProjectUpdate(d, meta)
   234  }
   235  
   236  func expandProjectArtifacts(d *schema.ResourceData) codebuild.ProjectArtifacts {
   237  	configs := d.Get("artifacts").(*schema.Set).List()
   238  	data := configs[0].(map[string]interface{})
   239  
   240  	projectArtifacts := codebuild.ProjectArtifacts{
   241  		Type: aws.String(data["type"].(string)),
   242  	}
   243  
   244  	if data["location"].(string) != "" {
   245  		projectArtifacts.Location = aws.String(data["location"].(string))
   246  	}
   247  
   248  	if data["name"].(string) != "" {
   249  		projectArtifacts.Name = aws.String(data["name"].(string))
   250  	}
   251  
   252  	if data["namespace_type"].(string) != "" {
   253  		projectArtifacts.NamespaceType = aws.String(data["namespace_type"].(string))
   254  	}
   255  
   256  	if data["packaging"].(string) != "" {
   257  		projectArtifacts.Packaging = aws.String(data["packaging"].(string))
   258  	}
   259  
   260  	if data["path"].(string) != "" {
   261  		projectArtifacts.Path = aws.String(data["path"].(string))
   262  	}
   263  
   264  	return projectArtifacts
   265  }
   266  
   267  func expandProjectEnvironment(d *schema.ResourceData) *codebuild.ProjectEnvironment {
   268  	configs := d.Get("environment").(*schema.Set).List()
   269  	projectEnv := &codebuild.ProjectEnvironment{}
   270  
   271  	envConfig := configs[0].(map[string]interface{})
   272  
   273  	if v := envConfig["compute_type"]; v != nil {
   274  		projectEnv.ComputeType = aws.String(v.(string))
   275  	}
   276  
   277  	if v := envConfig["image"]; v != nil {
   278  		projectEnv.Image = aws.String(v.(string))
   279  	}
   280  
   281  	if v := envConfig["type"]; v != nil {
   282  		projectEnv.Type = aws.String(v.(string))
   283  	}
   284  
   285  	if v := envConfig["environment_variable"]; v != nil {
   286  		envVariables := v.([]interface{})
   287  		if len(envVariables) > 0 {
   288  			projectEnvironmentVariables := make([]*codebuild.EnvironmentVariable, 0, len(envVariables))
   289  
   290  			for _, envVariablesConfig := range envVariables {
   291  				config := envVariablesConfig.(map[string]interface{})
   292  
   293  				projectEnvironmentVar := &codebuild.EnvironmentVariable{}
   294  
   295  				if v := config["name"].(string); v != "" {
   296  					projectEnvironmentVar.Name = &v
   297  				}
   298  
   299  				if v := config["value"].(string); v != "" {
   300  					projectEnvironmentVar.Value = &v
   301  				}
   302  
   303  				projectEnvironmentVariables = append(projectEnvironmentVariables, projectEnvironmentVar)
   304  			}
   305  
   306  			projectEnv.EnvironmentVariables = projectEnvironmentVariables
   307  		}
   308  	}
   309  
   310  	return projectEnv
   311  }
   312  
   313  func expandProjectSource(d *schema.ResourceData) codebuild.ProjectSource {
   314  	configs := d.Get("source").(*schema.Set).List()
   315  	projectSource := codebuild.ProjectSource{}
   316  
   317  	for _, configRaw := range configs {
   318  		data := configRaw.(map[string]interface{})
   319  
   320  		sourceType := data["type"].(string)
   321  		location := data["location"].(string)
   322  		buildspec := data["buildspec"].(string)
   323  
   324  		projectSource = codebuild.ProjectSource{
   325  			Type:      &sourceType,
   326  			Location:  &location,
   327  			Buildspec: &buildspec,
   328  		}
   329  
   330  		if v, ok := data["auth"]; ok {
   331  			if len(v.(*schema.Set).List()) > 0 {
   332  				auth := v.(*schema.Set).List()[0].(map[string]interface{})
   333  
   334  				projectSource.Auth = &codebuild.SourceAuth{
   335  					Type:     aws.String(auth["type"].(string)),
   336  					Resource: aws.String(auth["resource"].(string)),
   337  				}
   338  			}
   339  		}
   340  	}
   341  
   342  	return projectSource
   343  }
   344  
   345  func resourceAwsCodeBuildProjectRead(d *schema.ResourceData, meta interface{}) error {
   346  	conn := meta.(*AWSClient).codebuildconn
   347  
   348  	resp, err := conn.BatchGetProjects(&codebuild.BatchGetProjectsInput{
   349  		Names: []*string{
   350  			aws.String(d.Id()),
   351  		},
   352  	})
   353  
   354  	if err != nil {
   355  		return fmt.Errorf("[ERROR] Error retreiving Projects: %q", err)
   356  	}
   357  
   358  	// if nothing was found, then return no state
   359  	if len(resp.Projects) == 0 {
   360  		log.Printf("[INFO]: No projects were found, removing from state")
   361  		d.SetId("")
   362  		return nil
   363  	}
   364  
   365  	project := resp.Projects[0]
   366  
   367  	if err := d.Set("artifacts", flattenAwsCodebuildProjectArtifacts(project.Artifacts)); err != nil {
   368  		return err
   369  	}
   370  
   371  	if err := d.Set("environment", schema.NewSet(resourceAwsCodeBuildProjectEnvironmentHash, flattenAwsCodebuildProjectEnvironment(project.Environment))); err != nil {
   372  		return err
   373  	}
   374  
   375  	if err := d.Set("source", flattenAwsCodebuildProjectSource(project.Source)); err != nil {
   376  		return err
   377  	}
   378  
   379  	d.Set("description", project.Description)
   380  	d.Set("encryption_key", project.EncryptionKey)
   381  	d.Set("name", project.Name)
   382  	d.Set("service_role", project.ServiceRole)
   383  	d.Set("build_timeout", project.TimeoutInMinutes)
   384  
   385  	if err := d.Set("tags", tagsToMapCodeBuild(project.Tags)); err != nil {
   386  		return err
   387  	}
   388  
   389  	return nil
   390  }
   391  
   392  func resourceAwsCodeBuildProjectUpdate(d *schema.ResourceData, meta interface{}) error {
   393  	conn := meta.(*AWSClient).codebuildconn
   394  
   395  	params := &codebuild.UpdateProjectInput{
   396  		Name: aws.String(d.Get("name").(string)),
   397  	}
   398  
   399  	if d.HasChange("environment") {
   400  		projectEnv := expandProjectEnvironment(d)
   401  		params.Environment = projectEnv
   402  	}
   403  
   404  	if d.HasChange("source") {
   405  		projectSource := expandProjectSource(d)
   406  		params.Source = &projectSource
   407  	}
   408  
   409  	if d.HasChange("artifacts") {
   410  		projectArtifacts := expandProjectArtifacts(d)
   411  		params.Artifacts = &projectArtifacts
   412  	}
   413  
   414  	if d.HasChange("description") {
   415  		params.Description = aws.String(d.Get("description").(string))
   416  	}
   417  
   418  	if d.HasChange("encryption_key") {
   419  		params.EncryptionKey = aws.String(d.Get("encryption_key").(string))
   420  	}
   421  
   422  	if d.HasChange("service_role") {
   423  		params.ServiceRole = aws.String(d.Get("service_role").(string))
   424  	}
   425  
   426  	if d.HasChange("build_timeout") {
   427  		params.TimeoutInMinutes = aws.Int64(int64(d.Get("build_timeout").(int)))
   428  	}
   429  
   430  	// The documentation clearly says "The replacement set of tags for this build project."
   431  	// But its a slice of pointers so if not set for every update, they get removed.
   432  	params.Tags = tagsFromMapCodeBuild(d.Get("tags").(map[string]interface{}))
   433  
   434  	_, err := conn.UpdateProject(params)
   435  
   436  	if err != nil {
   437  		return fmt.Errorf(
   438  			"[ERROR] Error updating CodeBuild project (%s): %s",
   439  			d.Id(), err)
   440  	}
   441  
   442  	return resourceAwsCodeBuildProjectRead(d, meta)
   443  }
   444  
   445  func resourceAwsCodeBuildProjectDelete(d *schema.ResourceData, meta interface{}) error {
   446  	conn := meta.(*AWSClient).codebuildconn
   447  
   448  	_, err := conn.DeleteProject(&codebuild.DeleteProjectInput{
   449  		Name: aws.String(d.Id()),
   450  	})
   451  
   452  	if err != nil {
   453  		return err
   454  	}
   455  
   456  	d.SetId("")
   457  
   458  	return nil
   459  }
   460  
   461  func flattenAwsCodebuildProjectArtifacts(artifacts *codebuild.ProjectArtifacts) *schema.Set {
   462  
   463  	artifactSet := schema.Set{
   464  		F: resourceAwsCodeBuildProjectArtifactsHash,
   465  	}
   466  
   467  	values := map[string]interface{}{}
   468  
   469  	values["type"] = *artifacts.Type
   470  
   471  	if artifacts.Location != nil {
   472  		values["location"] = *artifacts.Location
   473  	}
   474  
   475  	if artifacts.Name != nil {
   476  		values["name"] = *artifacts.Name
   477  	}
   478  
   479  	if artifacts.NamespaceType != nil {
   480  		values["namespace_type"] = *artifacts.NamespaceType
   481  	}
   482  
   483  	if artifacts.Packaging != nil {
   484  		values["packaging"] = *artifacts.Packaging
   485  	}
   486  
   487  	if artifacts.Path != nil {
   488  		values["path"] = *artifacts.Path
   489  	}
   490  
   491  	artifactSet.Add(values)
   492  
   493  	return &artifactSet
   494  }
   495  
   496  func flattenAwsCodebuildProjectEnvironment(environment *codebuild.ProjectEnvironment) []interface{} {
   497  	envConfig := map[string]interface{}{}
   498  
   499  	envConfig["type"] = *environment.Type
   500  	envConfig["compute_type"] = *environment.ComputeType
   501  	envConfig["image"] = *environment.Image
   502  
   503  	if environment.EnvironmentVariables != nil {
   504  		envConfig["environment_variable"] = environmentVariablesToMap(environment.EnvironmentVariables)
   505  	}
   506  
   507  	return []interface{}{envConfig}
   508  
   509  }
   510  
   511  func flattenAwsCodebuildProjectSource(source *codebuild.ProjectSource) *schema.Set {
   512  
   513  	sourceSet := schema.Set{
   514  		F: resourceAwsCodeBuildProjectSourceHash,
   515  	}
   516  
   517  	authSet := schema.Set{
   518  		F: resourceAwsCodeBuildProjectSourceAuthHash,
   519  	}
   520  
   521  	sourceConfig := map[string]interface{}{}
   522  
   523  	sourceConfig["type"] = *source.Type
   524  
   525  	if source.Auth != nil {
   526  		authSet.Add(sourceAuthToMap(source.Auth))
   527  		sourceConfig["auth"] = &authSet
   528  	}
   529  
   530  	if source.Buildspec != nil {
   531  		sourceConfig["buildspec"] = *source.Buildspec
   532  	}
   533  
   534  	if source.Location != nil {
   535  		sourceConfig["location"] = *source.Location
   536  	}
   537  
   538  	sourceSet.Add(sourceConfig)
   539  
   540  	return &sourceSet
   541  
   542  }
   543  
   544  func resourceAwsCodeBuildProjectArtifactsHash(v interface{}) int {
   545  	var buf bytes.Buffer
   546  	m := v.(map[string]interface{})
   547  
   548  	artifactType := m["type"].(string)
   549  
   550  	buf.WriteString(fmt.Sprintf("%s-", artifactType))
   551  
   552  	return hashcode.String(buf.String())
   553  }
   554  
   555  func resourceAwsCodeBuildProjectEnvironmentHash(v interface{}) int {
   556  	var buf bytes.Buffer
   557  	m := v.(map[string]interface{})
   558  
   559  	environmentType := m["type"].(string)
   560  	computeType := m["compute_type"].(string)
   561  	image := m["image"].(string)
   562  	environmentVariables := m["environment_variable"].([]interface{})
   563  	buf.WriteString(fmt.Sprintf("%s-", environmentType))
   564  	buf.WriteString(fmt.Sprintf("%s-", computeType))
   565  	buf.WriteString(fmt.Sprintf("%s-", image))
   566  	for _, e := range environmentVariables {
   567  		if e != nil { // Old statefiles might have nil values in them
   568  			ev := e.(map[string]interface{})
   569  			buf.WriteString(fmt.Sprintf("%s:%s-", ev["name"].(string), ev["value"].(string)))
   570  		}
   571  	}
   572  
   573  	return hashcode.String(buf.String())
   574  }
   575  
   576  func resourceAwsCodeBuildProjectSourceHash(v interface{}) int {
   577  	var buf bytes.Buffer
   578  	m := v.(map[string]interface{})
   579  
   580  	sourceType := m["type"].(string)
   581  	buildspec := m["buildspec"].(string)
   582  	location := m["location"].(string)
   583  
   584  	buf.WriteString(fmt.Sprintf("%s-", sourceType))
   585  	buf.WriteString(fmt.Sprintf("%s-", buildspec))
   586  	buf.WriteString(fmt.Sprintf("%s-", location))
   587  
   588  	return hashcode.String(buf.String())
   589  }
   590  
   591  func resourceAwsCodeBuildProjectSourceAuthHash(v interface{}) int {
   592  	var buf bytes.Buffer
   593  	m := v.(map[string]interface{})
   594  
   595  	buf.WriteString(fmt.Sprintf("%s-", m["type"].(string)))
   596  
   597  	if m["resource"] != nil {
   598  		buf.WriteString(fmt.Sprintf("%s-", m["resource"].(string)))
   599  	}
   600  
   601  	return hashcode.String(buf.String())
   602  }
   603  
   604  func environmentVariablesToMap(environmentVariables []*codebuild.EnvironmentVariable) []interface{} {
   605  
   606  	envVariables := []interface{}{}
   607  	if len(environmentVariables) > 0 {
   608  		for _, env := range environmentVariables {
   609  			item := map[string]interface{}{}
   610  			item["name"] = *env.Name
   611  			item["value"] = *env.Value
   612  			envVariables = append(envVariables, item)
   613  		}
   614  	}
   615  
   616  	return envVariables
   617  }
   618  
   619  func sourceAuthToMap(sourceAuth *codebuild.SourceAuth) map[string]interface{} {
   620  
   621  	auth := map[string]interface{}{}
   622  	auth["type"] = *sourceAuth.Type
   623  
   624  	if sourceAuth.Resource != nil {
   625  		auth["resource"] = *sourceAuth.Resource
   626  	}
   627  
   628  	return auth
   629  }
   630  
   631  func validateAwsCodeBuildArifactsType(v interface{}, k string) (ws []string, errors []error) {
   632  	value := v.(string)
   633  	types := map[string]bool{
   634  		"CODEPIPELINE": true,
   635  		"NO_ARTIFACTS": true,
   636  		"S3":           true,
   637  	}
   638  
   639  	if !types[value] {
   640  		errors = append(errors, fmt.Errorf("CodeBuild: Arifacts Type can only be CODEPIPELINE / NO_ARTIFACTS / S3"))
   641  	}
   642  	return
   643  }
   644  
   645  func validateAwsCodeBuildArifactsNamespaceType(v interface{}, k string) (ws []string, errors []error) {
   646  	value := v.(string)
   647  	types := map[string]bool{
   648  		"NONE":     true,
   649  		"BUILD_ID": true,
   650  	}
   651  
   652  	if !types[value] {
   653  		errors = append(errors, fmt.Errorf("CodeBuild: Arifacts Namespace Type can only be NONE / BUILD_ID"))
   654  	}
   655  	return
   656  }
   657  
   658  func validateAwsCodeBuildProjectName(v interface{}, k string) (ws []string, errors []error) {
   659  	value := v.(string)
   660  	if !regexp.MustCompile(`^[A-Za-z0-9]`).MatchString(value) {
   661  		errors = append(errors, fmt.Errorf(
   662  			"first character of %q must be a letter or number", value))
   663  	}
   664  
   665  	if !regexp.MustCompile(`^[A-Za-z0-9\-_]+$`).MatchString(value) {
   666  		errors = append(errors, fmt.Errorf(
   667  			"only alphanumeric characters, hyphens and underscores allowed in %q", value))
   668  	}
   669  
   670  	if len(value) > 255 {
   671  		errors = append(errors, fmt.Errorf(
   672  			"%q cannot be greater than 255 characters", value))
   673  	}
   674  
   675  	return
   676  }
   677  
   678  func validateAwsCodeBuildProjectDescription(v interface{}, k string) (ws []string, errors []error) {
   679  	value := v.(string)
   680  	if len(value) > 255 {
   681  		errors = append(errors, fmt.Errorf("%q cannot be greater than 255 characters", value))
   682  	}
   683  	return
   684  }
   685  
   686  func validateAwsCodeBuildEnvironmentComputeType(v interface{}, k string) (ws []string, errors []error) {
   687  	value := v.(string)
   688  	types := map[string]bool{
   689  		"BUILD_GENERAL1_SMALL":  true,
   690  		"BUILD_GENERAL1_MEDIUM": true,
   691  		"BUILD_GENERAL1_LARGE":  true,
   692  	}
   693  
   694  	if !types[value] {
   695  		errors = append(errors, fmt.Errorf("CodeBuild: Environment Compute Type can only be BUILD_GENERAL1_SMALL / BUILD_GENERAL1_MEDIUM / BUILD_GENERAL1_LARGE"))
   696  	}
   697  	return
   698  }
   699  
   700  func validateAwsCodeBuildEnvironmentType(v interface{}, k string) (ws []string, errors []error) {
   701  	value := v.(string)
   702  	types := map[string]bool{
   703  		"LINUX_CONTAINER": true,
   704  	}
   705  
   706  	if !types[value] {
   707  		errors = append(errors, fmt.Errorf("CodeBuild: Environment Type can only be LINUX_CONTAINER"))
   708  	}
   709  	return
   710  }
   711  
   712  func validateAwsCodeBuildSourceType(v interface{}, k string) (ws []string, errors []error) {
   713  	value := v.(string)
   714  	types := map[string]bool{
   715  		"CODECOMMIT":   true,
   716  		"CODEPIPELINE": true,
   717  		"GITHUB":       true,
   718  		"S3":           true,
   719  	}
   720  
   721  	if !types[value] {
   722  		errors = append(errors, fmt.Errorf("CodeBuild: Source Type can only be CODECOMMIT / CODEPIPELINE / GITHUB / S3"))
   723  	}
   724  	return
   725  }
   726  
   727  func validateAwsCodeBuildSourceAuthType(v interface{}, k string) (ws []string, errors []error) {
   728  	value := v.(string)
   729  	types := map[string]bool{
   730  		"OAUTH": true,
   731  	}
   732  
   733  	if !types[value] {
   734  		errors = append(errors, fmt.Errorf("CodeBuild: Source Auth Type can only be OAUTH"))
   735  	}
   736  	return
   737  }
   738  
   739  func validateAwsCodeBuildTimeout(v interface{}, k string) (ws []string, errors []error) {
   740  	value := v.(int)
   741  
   742  	if value < 5 || value > 480 {
   743  		errors = append(errors, fmt.Errorf("%q must be greater than 5 minutes and less than 480 minutes (8 hours)", value))
   744  	}
   745  	return
   746  }