github.com/subuk/terraform@v0.6.14-0.20160317140351-de1567c2e732/builtin/providers/aws/resource_aws_cloudtrail.go (about)

     1  package aws
     2  
     3  import (
     4  	"fmt"
     5  	"log"
     6  
     7  	"github.com/aws/aws-sdk-go/aws"
     8  	"github.com/aws/aws-sdk-go/service/cloudtrail"
     9  	"github.com/hashicorp/terraform/helper/schema"
    10  )
    11  
    12  func resourceAwsCloudTrail() *schema.Resource {
    13  	return &schema.Resource{
    14  		Create: resourceAwsCloudTrailCreate,
    15  		Read:   resourceAwsCloudTrailRead,
    16  		Update: resourceAwsCloudTrailUpdate,
    17  		Delete: resourceAwsCloudTrailDelete,
    18  
    19  		Schema: map[string]*schema.Schema{
    20  			"name": &schema.Schema{
    21  				Type:     schema.TypeString,
    22  				Required: true,
    23  				ForceNew: true,
    24  			},
    25  			"enable_logging": &schema.Schema{
    26  				Type:     schema.TypeBool,
    27  				Optional: true,
    28  				Default:  true,
    29  			},
    30  			"s3_bucket_name": &schema.Schema{
    31  				Type:     schema.TypeString,
    32  				Required: true,
    33  			},
    34  			"s3_key_prefix": &schema.Schema{
    35  				Type:     schema.TypeString,
    36  				Optional: true,
    37  			},
    38  			"cloud_watch_logs_role_arn": &schema.Schema{
    39  				Type:     schema.TypeString,
    40  				Optional: true,
    41  			},
    42  			"cloud_watch_logs_group_arn": &schema.Schema{
    43  				Type:     schema.TypeString,
    44  				Optional: true,
    45  			},
    46  			"include_global_service_events": &schema.Schema{
    47  				Type:     schema.TypeBool,
    48  				Optional: true,
    49  				Default:  true,
    50  			},
    51  			"is_multi_region_trail": &schema.Schema{
    52  				Type:     schema.TypeBool,
    53  				Optional: true,
    54  				Default:  false,
    55  			},
    56  			"sns_topic_name": &schema.Schema{
    57  				Type:     schema.TypeString,
    58  				Optional: true,
    59  			},
    60  			"enable_log_file_validation": &schema.Schema{
    61  				Type:     schema.TypeBool,
    62  				Optional: true,
    63  				Default:  false,
    64  			},
    65  			"kms_key_id": &schema.Schema{
    66  				Type:     schema.TypeString,
    67  				Optional: true,
    68  			},
    69  			"home_region": &schema.Schema{
    70  				Type:     schema.TypeString,
    71  				Computed: true,
    72  			},
    73  			"arn": &schema.Schema{
    74  				Type:     schema.TypeString,
    75  				Computed: true,
    76  			},
    77  			"tags": tagsSchema(),
    78  		},
    79  	}
    80  }
    81  
    82  func resourceAwsCloudTrailCreate(d *schema.ResourceData, meta interface{}) error {
    83  	conn := meta.(*AWSClient).cloudtrailconn
    84  
    85  	input := cloudtrail.CreateTrailInput{
    86  		Name:         aws.String(d.Get("name").(string)),
    87  		S3BucketName: aws.String(d.Get("s3_bucket_name").(string)),
    88  	}
    89  
    90  	if v, ok := d.GetOk("cloud_watch_logs_group_arn"); ok {
    91  		input.CloudWatchLogsLogGroupArn = aws.String(v.(string))
    92  	}
    93  	if v, ok := d.GetOk("cloud_watch_logs_role_arn"); ok {
    94  		input.CloudWatchLogsRoleArn = aws.String(v.(string))
    95  	}
    96  	if v, ok := d.GetOk("include_global_service_events"); ok {
    97  		input.IncludeGlobalServiceEvents = aws.Bool(v.(bool))
    98  	}
    99  	if v, ok := d.GetOk("is_multi_region_trail"); ok {
   100  		input.IsMultiRegionTrail = aws.Bool(v.(bool))
   101  	}
   102  	if v, ok := d.GetOk("enable_log_file_validation"); ok {
   103  		input.EnableLogFileValidation = aws.Bool(v.(bool))
   104  	}
   105  	if v, ok := d.GetOk("kms_key_id"); ok {
   106  		input.KmsKeyId = aws.String(v.(string))
   107  	}
   108  	if v, ok := d.GetOk("s3_key_prefix"); ok {
   109  		input.S3KeyPrefix = aws.String(v.(string))
   110  	}
   111  	if v, ok := d.GetOk("sns_topic_name"); ok {
   112  		input.SnsTopicName = aws.String(v.(string))
   113  	}
   114  
   115  	t, err := conn.CreateTrail(&input)
   116  	if err != nil {
   117  		return err
   118  	}
   119  
   120  	log.Printf("[DEBUG] CloudTrail created: %s", t)
   121  
   122  	d.Set("arn", *t.TrailARN)
   123  	d.SetId(*t.Name)
   124  
   125  	// AWS CloudTrail sets newly-created trails to false.
   126  	if v, ok := d.GetOk("enable_logging"); ok && v.(bool) {
   127  		err := cloudTrailSetLogging(conn, v.(bool), d.Id())
   128  		if err != nil {
   129  			return err
   130  		}
   131  	}
   132  
   133  	return resourceAwsCloudTrailUpdate(d, meta)
   134  }
   135  
   136  func resourceAwsCloudTrailRead(d *schema.ResourceData, meta interface{}) error {
   137  	conn := meta.(*AWSClient).cloudtrailconn
   138  
   139  	name := d.Get("name").(string)
   140  	input := cloudtrail.DescribeTrailsInput{
   141  		TrailNameList: []*string{
   142  			aws.String(name),
   143  		},
   144  	}
   145  	resp, err := conn.DescribeTrails(&input)
   146  	if err != nil {
   147  		return err
   148  	}
   149  	if len(resp.TrailList) == 0 {
   150  		return fmt.Errorf("No CloudTrail found, using name %q", name)
   151  	}
   152  
   153  	trail := resp.TrailList[0]
   154  	log.Printf("[DEBUG] CloudTrail received: %s", trail)
   155  
   156  	d.Set("name", trail.Name)
   157  	d.Set("s3_bucket_name", trail.S3BucketName)
   158  	d.Set("s3_key_prefix", trail.S3KeyPrefix)
   159  	d.Set("cloud_watch_logs_role_arn", trail.CloudWatchLogsRoleArn)
   160  	d.Set("cloud_watch_logs_group_arn", trail.CloudWatchLogsLogGroupArn)
   161  	d.Set("include_global_service_events", trail.IncludeGlobalServiceEvents)
   162  	d.Set("is_multi_region_trail", trail.IsMultiRegionTrail)
   163  	d.Set("sns_topic_name", trail.SnsTopicName)
   164  	d.Set("enable_log_file_validation", trail.LogFileValidationEnabled)
   165  
   166  	// TODO: Make it possible to use KMS Key names, not just ARNs
   167  	// In order to test it properly this PR needs to be merged 1st:
   168  	// https://github.com/hashicorp/terraform/pull/3928
   169  	d.Set("kms_key_id", trail.KmsKeyId)
   170  
   171  	d.Set("arn", trail.TrailARN)
   172  	d.Set("home_region", trail.HomeRegion)
   173  
   174  	// Get tags
   175  	req := &cloudtrail.ListTagsInput{
   176  		ResourceIdList: []*string{trail.TrailARN},
   177  	}
   178  
   179  	tagsOut, err := conn.ListTags(req)
   180  	if err != nil {
   181  		return err
   182  	}
   183  	log.Printf("[DEBUG] Received CloudTrail tags: %s", tagsOut)
   184  
   185  	var tags []*cloudtrail.Tag
   186  	if tagsOut.ResourceTagList != nil && len(tagsOut.ResourceTagList) > 0 {
   187  		tags = tagsOut.ResourceTagList[0].TagsList
   188  	}
   189  
   190  	if err := d.Set("tags", tagsToMapCloudtrail(tags)); err != nil {
   191  		return err
   192  	}
   193  
   194  	logstatus, err := cloudTrailGetLoggingStatus(conn, trail.Name)
   195  	if err != nil {
   196  		return err
   197  	}
   198  	d.Set("enable_logging", logstatus)
   199  
   200  	return nil
   201  }
   202  
   203  func resourceAwsCloudTrailUpdate(d *schema.ResourceData, meta interface{}) error {
   204  	conn := meta.(*AWSClient).cloudtrailconn
   205  
   206  	input := cloudtrail.UpdateTrailInput{
   207  		Name: aws.String(d.Get("name").(string)),
   208  	}
   209  
   210  	if d.HasChange("s3_bucket_name") {
   211  		input.S3BucketName = aws.String(d.Get("s3_bucket_name").(string))
   212  	}
   213  	if d.HasChange("s3_key_prefix") {
   214  		input.S3KeyPrefix = aws.String(d.Get("s3_key_prefix").(string))
   215  	}
   216  	if d.HasChange("cloud_watch_logs_role_arn") {
   217  		input.CloudWatchLogsRoleArn = aws.String(d.Get("cloud_watch_logs_role_arn").(string))
   218  	}
   219  	if d.HasChange("cloud_watch_logs_group_arn") {
   220  		input.CloudWatchLogsLogGroupArn = aws.String(d.Get("cloud_watch_logs_group_arn").(string))
   221  	}
   222  	if d.HasChange("include_global_service_events") {
   223  		input.IncludeGlobalServiceEvents = aws.Bool(d.Get("include_global_service_events").(bool))
   224  	}
   225  	if d.HasChange("is_multi_region_trail") {
   226  		input.IsMultiRegionTrail = aws.Bool(d.Get("is_multi_region_trail").(bool))
   227  	}
   228  	if d.HasChange("enable_log_file_validation") {
   229  		input.EnableLogFileValidation = aws.Bool(d.Get("enable_log_file_validation").(bool))
   230  	}
   231  	if d.HasChange("kms_key_id") {
   232  		input.KmsKeyId = aws.String(d.Get("kms_key_id").(string))
   233  	}
   234  	if d.HasChange("sns_topic_name") {
   235  		input.SnsTopicName = aws.String(d.Get("sns_topic_name").(string))
   236  	}
   237  
   238  	log.Printf("[DEBUG] Updating CloudTrail: %s", input)
   239  	t, err := conn.UpdateTrail(&input)
   240  	if err != nil {
   241  		return err
   242  	}
   243  
   244  	if d.HasChange("tags") {
   245  		err := setTagsCloudtrail(conn, d)
   246  		if err != nil {
   247  			return err
   248  		}
   249  	}
   250  
   251  	if d.HasChange("enable_logging") {
   252  		log.Printf("[DEBUG] Updating logging on CloudTrail: %s", input)
   253  		err := cloudTrailSetLogging(conn, d.Get("enable_logging").(bool), *input.Name)
   254  		if err != nil {
   255  			return err
   256  		}
   257  	}
   258  
   259  	log.Printf("[DEBUG] CloudTrail updated: %s", t)
   260  
   261  	return resourceAwsCloudTrailRead(d, meta)
   262  }
   263  
   264  func resourceAwsCloudTrailDelete(d *schema.ResourceData, meta interface{}) error {
   265  	conn := meta.(*AWSClient).cloudtrailconn
   266  	name := d.Get("name").(string)
   267  
   268  	log.Printf("[DEBUG] Deleting CloudTrail: %q", name)
   269  	_, err := conn.DeleteTrail(&cloudtrail.DeleteTrailInput{
   270  		Name: aws.String(name),
   271  	})
   272  
   273  	return err
   274  }
   275  
   276  func cloudTrailGetLoggingStatus(conn *cloudtrail.CloudTrail, id *string) (bool, error) {
   277  	GetTrailStatusOpts := &cloudtrail.GetTrailStatusInput{
   278  		Name: id,
   279  	}
   280  	resp, err := conn.GetTrailStatus(GetTrailStatusOpts)
   281  	if err != nil {
   282  		return false, fmt.Errorf("Error retrieving logging status of CloudTrail (%s): %s", *id, err)
   283  	}
   284  
   285  	return *resp.IsLogging, err
   286  }
   287  
   288  func cloudTrailSetLogging(conn *cloudtrail.CloudTrail, enabled bool, id string) error {
   289  	if enabled {
   290  		log.Printf(
   291  			"[DEBUG] Starting logging on CloudTrail (%s)",
   292  			id)
   293  		StartLoggingOpts := &cloudtrail.StartLoggingInput{
   294  			Name: aws.String(id),
   295  		}
   296  		if _, err := conn.StartLogging(StartLoggingOpts); err != nil {
   297  			return fmt.Errorf(
   298  				"Error starting logging on CloudTrail (%s): %s",
   299  				id, err)
   300  		}
   301  	} else {
   302  		log.Printf(
   303  			"[DEBUG] Stopping logging on CloudTrail (%s)",
   304  			id)
   305  		StopLoggingOpts := &cloudtrail.StopLoggingInput{
   306  			Name: aws.String(id),
   307  		}
   308  		if _, err := conn.StopLogging(StopLoggingOpts); err != nil {
   309  			return fmt.Errorf(
   310  				"Error stopping logging on CloudTrail (%s): %s",
   311  				id, err)
   312  		}
   313  	}
   314  
   315  	return nil
   316  }