@ -8,6 +8,7 @@ import (
"strings"
"time"
"github.com/hashicorp/go-multierror"
"github.com/hashicorp/terraform/helper/hashcode"
"github.com/hashicorp/terraform/helper/resource"
"github.com/hashicorp/terraform/helper/schema"
@ -255,7 +256,7 @@ func resourceAwsElasticBeanstalkEnvironmentCreate(d *schema.ResourceData, meta i
createOpts . VersionLabel = aws . String ( version )
}
// Get the current time to filter describeBeanstalkEvent s messages
// Get the current time to filter getBeanstalkEnvironmentError s messages
t := time . Now ( )
log . Printf ( "[DEBUG] Elastic Beanstalk Environment create opts: %s" , createOpts )
resp , err := conn . CreateEnvironment ( & createOpts )
@ -280,7 +281,7 @@ func resourceAwsElasticBeanstalkEnvironmentCreate(d *schema.ResourceData, meta i
stateConf := & resource . StateChangeConf {
Pending : [ ] string { "Launching" , "Updating" } ,
Target : [ ] string { "Ready" } ,
Refresh : environmentStateRefreshFunc ( conn , d . Id ( ) ),
Refresh : environmentStateRefreshFunc ( conn , d . Id ( ) , t ),
Timeout : waitForReadyTimeOut ,
Delay : 10 * time . Second ,
PollInterval : pollInterval ,
@ -294,10 +295,13 @@ func resourceAwsElasticBeanstalkEnvironmentCreate(d *schema.ResourceData, meta i
d . Id ( ) , err )
}
e rr = describeBeanstalkEvent s( conn , d . Id ( ) , t )
e nvErrors, err := getBeanstalkEnvironmentError s( conn , d . Id ( ) , t )
if err != nil {
return err
}
if envErrors != nil {
return envErrors
}
return resourceAwsElasticBeanstalkEnvironmentRead ( d , meta )
}
@ -403,7 +407,7 @@ func resourceAwsElasticBeanstalkEnvironmentUpdate(d *schema.ResourceData, meta i
}
if hasChange {
// Get the current time to filter describeBeanstalkEvent s messages
// Get the current time to filter getBeanstalkEnvironmentError s messages
t := time . Now ( )
log . Printf ( "[DEBUG] Elastic Beanstalk Environment update opts: %s" , updateOpts )
_ , err := conn . UpdateEnvironment ( & updateOpts )
@ -424,7 +428,7 @@ func resourceAwsElasticBeanstalkEnvironmentUpdate(d *schema.ResourceData, meta i
stateConf := & resource . StateChangeConf {
Pending : [ ] string { "Launching" , "Updating" } ,
Target : [ ] string { "Ready" } ,
Refresh : environmentStateRefreshFunc ( conn , d . Id ( ) ),
Refresh : environmentStateRefreshFunc ( conn , d . Id ( ) , t ),
Timeout : waitForReadyTimeOut ,
Delay : 10 * time . Second ,
PollInterval : pollInterval ,
@ -438,10 +442,13 @@ func resourceAwsElasticBeanstalkEnvironmentUpdate(d *schema.ResourceData, meta i
d . Id ( ) , err )
}
e rr = describeBeanstalkEvent s( conn , d . Id ( ) , t )
e nvErrors, err := getBeanstalkEnvironmentError s( conn , d . Id ( ) , t )
if err != nil {
return err
}
if envErrors != nil {
return envErrors
}
}
return resourceAwsElasticBeanstalkEnvironmentRead ( d , meta )
@ -663,7 +670,7 @@ func resourceAwsElasticBeanstalkEnvironmentDelete(d *schema.ResourceData, meta i
TerminateResources : aws . Bool ( true ) ,
}
// Get the current time to filter describeBeanstalkEvent s messages
// Get the current time to filter getBeanstalkEnvironmentError s messages
t := time . Now ( )
log . Printf ( "[DEBUG] Elastic Beanstalk Environment terminate opts: %s" , opts )
_ , err := conn . TerminateEnvironment ( & opts )
@ -685,7 +692,7 @@ func resourceAwsElasticBeanstalkEnvironmentDelete(d *schema.ResourceData, meta i
stateConf := & resource . StateChangeConf {
Pending : [ ] string { "Terminating" } ,
Target : [ ] string { "Terminated" } ,
Refresh : environmentStateRefreshFunc ( conn , d . Id ( ) ),
Refresh : environmentStateRefreshFunc ( conn , d . Id ( ) , t ),
Timeout : waitForReadyTimeOut ,
Delay : 10 * time . Second ,
PollInterval : pollInterval ,
@ -699,17 +706,20 @@ func resourceAwsElasticBeanstalkEnvironmentDelete(d *schema.ResourceData, meta i
d . Id ( ) , err )
}
e rr = describeBeanstalkEvent s( conn , d . Id ( ) , t )
e nvErrors, err := getBeanstalkEnvironmentError s( conn , d . Id ( ) , t )
if err != nil {
return err
}
if envErrors != nil {
return envErrors
}
return nil
}
// environmentStateRefreshFunc returns a resource.StateRefreshFunc that is used to watch
// the creation of the Beanstalk Environment
func environmentStateRefreshFunc ( conn * elasticbeanstalk . ElasticBeanstalk , environmentId string ) resource . StateRefreshFunc {
func environmentStateRefreshFunc ( conn * elasticbeanstalk . ElasticBeanstalk , environmentId string , t time . Time ) resource . StateRefreshFunc {
return func ( ) ( interface { } , string , error ) {
resp , err := conn . DescribeEnvironments ( & elasticbeanstalk . DescribeEnvironmentsInput {
EnvironmentIds : [ ] * string { aws . String ( environmentId ) } ,
@ -736,6 +746,14 @@ func environmentStateRefreshFunc(conn *elasticbeanstalk.ElasticBeanstalk, enviro
return - 1 , "failed" , fmt . Errorf ( "[Err] Error finding Elastic Beanstalk Environment, environment not found" )
}
envErrors , err := getBeanstalkEnvironmentErrors ( conn , environmentId , t )
if err != nil {
return - 1 , "failed" , err
}
if envErrors != nil {
return - 1 , "failed" , envErrors
}
return env , * env . Status , nil
}
}
@ -848,25 +866,48 @@ func dropGeneratedSecurityGroup(settingValue string, meta interface{}) string {
return strings . Join ( legitGroups , "," )
}
func describeBeanstalkEvents ( conn * elasticbeanstalk . ElasticBeanstalk , environmentId string , t time . Time ) error {
beanstalkErrors , err := conn . DescribeEvents ( & elasticbeanstalk . DescribeEventsInput {
type beanstalkEnvironmentError struct {
eventDate * time . Time
environmentID string
message * string
}
func ( e beanstalkEnvironmentError ) Error ( ) string {
return e . eventDate . String ( ) + " (" + e . environmentID + ") : " + * e . message
}
type beanstalkEnvironmentErrors [ ] * beanstalkEnvironmentError
func ( e beanstalkEnvironmentErrors ) Len ( ) int { return len ( e ) }
func ( e beanstalkEnvironmentErrors ) Swap ( i , j int ) { e [ i ] , e [ j ] = e [ j ] , e [ i ] }
func ( e beanstalkEnvironmentErrors ) Less ( i , j int ) bool { return e [ i ] . eventDate . Before ( * e [ j ] . eventDate ) }
func getBeanstalkEnvironmentErrors ( conn * elasticbeanstalk . ElasticBeanstalk , environmentId string , t time . Time ) ( * multierror . Error , error ) {
environmentErrors , err := conn . DescribeEvents ( & elasticbeanstalk . DescribeEventsInput {
EnvironmentId : aws . String ( environmentId ) ,
Severity : aws . String ( "ERROR" ) ,
StartTime : aws . Time ( t ) ,
} )
if err != nil {
log . Printf ( "[Err] Unable to get Elastic Beanstalk Evironment events: %s" , err )
return nil , fmt . Error f( "[Err] Unable to get Elastic Beanstalk Evironment events: %s" , err )
}
events := ""
for _ , event := range beanstalkErrors . Events {
events = events + "\n" + event . EventDate . String ( ) + ": " + * event . Message
var events beanstalkEnvironmentErrors
for _ , event := range environmentErrors . Events {
e := & beanstalkEnvironmentError {
eventDate : event . EventDate ,
environmentID : environmentId ,
message : event . Message ,
}
events = append ( events , e )
}
sort . Sort ( beanstalkEnvironmentErrors ( events ) )
if events != "" {
return fmt . Errorf ( "%s" , events )
var result * multierror . Error
for _ , event := range events {
result = multierror . Append ( result , event )
}
return nil
return result , nil
}