code: func UploadTemplate(serviceName string,
  	cfTemplate *gocf.Template,
  	s3Bucket string,
  	s3KeyName string,
  	awsSession *session.Session,
  	logger *logrus.Logger) (string, error) {
  
  	logger.WithFields(logrus.Fields{
  		"Key":    s3KeyName,
  		"Bucket": s3Bucket,
  	}).Info("Uploading CloudFormation template")
  
  	s3Uploader := s3manager.NewUploader(awsSession)
  
  	// Serialize the template and upload it
  	cfTemplateJSON, err := json.Marshal(cfTemplate)
  	if err != nil {
  		return "", errors.Wrap(err, "Failed to Marshal CloudFormation template")
  	}
  
  	// Upload the actual CloudFormation template to S3 to maximize the template
  	// size limit
  	// Ref: http://docs.aws.amazon.com/AWSCloudFormation/latest/APIReference/API_CreateStack.html
  	contentBody := string(cfTemplateJSON)
  	uploadInput := &s3manager.UploadInput{
  		Bucket:      &s3Bucket,
  		Key:         &s3KeyName,
  		ContentType: aws.String("application/json"),
  		Body:        strings.NewReader(contentBody),
  	}
  	templateUploadResult, templateUploadResultErr := s3Uploader.Upload(uploadInput)
  	if nil != templateUploadResultErr {
  		return "", templateUploadResultErr
  	}
  
  	// Be transparent
  	logger.WithFields(logrus.Fields{
  		"URL": templateUploadResult.Location,
  	}).Info("Template uploaded")
  	return templateUploadResult.Location, nil
  }
docs: // UploadTemplate marshals the given cfTemplate and uploads it to the
  // supplied bucket using the given KeyName