Skip to content

Commit

Permalink
Add website_domain for S3 buckets.
Browse files Browse the repository at this point in the history
  • Loading branch information
johnrengelman committed Jul 22, 2015
1 parent 9cb3150 commit cbe9be4
Show file tree
Hide file tree
Showing 4 changed files with 75 additions and 14 deletions.
42 changes: 42 additions & 0 deletions builtin/providers/aws/resource_aws_route53_record_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,22 @@ func TestAccAWSRoute53Record_alias(t *testing.T) {
})
}

func TestAccAWSRoute53Record_s3_alias(t *testing.T) {
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckRoute53RecordDestroy,
Steps: []resource.TestStep{
resource.TestStep{
Config: testAccRoute53S3AliasRecord,
Check: resource.ComposeTestCheckFunc(
testAccCheckRoute53RecordExists("aws_route53_record.alias"),
),
},
},
})
}

func TestAccAWSRoute53Record_weighted_alias(t *testing.T) {
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Expand Down Expand Up @@ -449,6 +465,32 @@ resource "aws_route53_record" "alias" {
}
`

const testAccRoute53S3AliasRecord = `
resource "aws_route53_zone" "main" {
name = "notexample.com"
}
resource "aws_s3_bucket" "website" {
bucket = "website.notexample.com"
acl = "public-read"
website {
index_document = "index.html"
}
}
resource "aws_route53_record" "alias" {
zone_id = "${aws_route53_zone.main.zone_id}"
name = "www"
type = "A"
alias {
zone_id = "${aws_s3_bucket.website.hosted_zone_id}"
name = "${aws_s3_bucket.website.website_domain}"
evaluate_target_health = true
}
}
`

const testAccRoute53WeightedElbAliasRecord = `
resource "aws_route53_zone" "main" {
name = "notexample.com"
Expand Down
40 changes: 29 additions & 11 deletions builtin/providers/aws/resource_aws_s3_bucket.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,12 +77,16 @@ func resourceAwsS3Bucket() *schema.Resource {
Optional: true,
Computed: true,
},

"website_endpoint": &schema.Schema{
Type: schema.TypeString,
Optional: true,
Computed: true,
},
"website_domain": &schema.Schema{
Type: schema.TypeString,
Optional: true,
Computed: true,
},

"tags": tagsSchema(),

Expand Down Expand Up @@ -237,12 +241,17 @@ func resourceAwsS3BucketRead(d *schema.ResourceData, meta interface{}) error {
}

// Add website_endpoint as an attribute
endpoint, err := websiteEndpoint(s3conn, d)
websiteEndpoint, err := websiteEndpoint(s3conn, d)
if err != nil {
return err
}
if err := d.Set("website_endpoint", endpoint); err != nil {
return err
if websiteEndpoint != nil {
if err := d.Set("website_endpoint", websiteEndpoint.Endpoint); err != nil {
return err
}
if err := d.Set("website_domain", websiteEndpoint.Domain); err != nil {
return err
}
}

tagSet, err := getTagSetS3(s3conn, d.Id())
Expand Down Expand Up @@ -405,11 +414,11 @@ func resourceAwsS3BucketWebsiteDelete(s3conn *s3.S3, d *schema.ResourceData) err
return nil
}

func websiteEndpoint(s3conn *s3.S3, d *schema.ResourceData) (string, error) {
func websiteEndpoint(s3conn *s3.S3, d *schema.ResourceData) (*S3Website, error) {
// If the bucket doesn't have a website configuration, return an empty
// endpoint
if _, ok := d.GetOk("website"); !ok {
return "", nil
return nil, nil
}

bucket := d.Get("bucket").(string)
Expand All @@ -421,26 +430,31 @@ func websiteEndpoint(s3conn *s3.S3, d *schema.ResourceData) (string, error) {
},
)
if err != nil {
return "", err
return nil, err
}
var region string
if location.LocationConstraint != nil {
region = *location.LocationConstraint
}

return WebsiteEndpointUrl(bucket, region), nil
return WebsiteEndpoint(bucket, region), nil
}

func WebsiteEndpointUrl(bucket string, region string) string {
func WebsiteEndpoint(bucket string, region string) *S3Website {
domain := WebsiteDomainUrl(region)
return &S3Website{Endpoint: fmt.Sprintf("%s.%s", bucket, domain), Domain: domain}
}

func WebsiteDomainUrl(region string) string {
region = normalizeRegion(region)

// Frankfurt(and probably future) regions uses different syntax for website endpoints
// http://docs.aws.amazon.com/AmazonS3/latest/dev/WebsiteEndpoints.html
if region == "eu-central-1" {
return fmt.Sprintf("%s.s3-website.%s.amazonaws.com", bucket, region)
return fmt.Sprintf("s3-website.%s.amazonaws.com", region)
}

return fmt.Sprintf("%s.s3-website-%s.amazonaws.com", bucket, region)
return fmt.Sprintf("s3-website-%s.amazonaws.com", region)
}

func normalizeJson(jsonString interface{}) string {
Expand All @@ -465,3 +479,7 @@ func normalizeRegion(region string) string {

return region
}

type S3Website struct {
Endpoint, Domain string
}
6 changes: 3 additions & 3 deletions builtin/providers/aws/website_endpoint_url_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,9 @@ var websiteEndpoints = []struct {

func TestWebsiteEndpointUrl(t *testing.T) {
for _, tt := range websiteEndpoints {
s := WebsiteEndpointUrl("bucket-name", tt.in)
if s != tt.out {
t.Errorf("WebsiteEndpointUrl(\"bucket-name\", %q) => %q, want %q", tt.in, s, tt.out)
s := WebsiteEndpoint("bucket-name", tt.in)
if s.Endpoint != tt.out {
t.Errorf("WebsiteEndpointUrl(\"bucket-name\", %q) => %q, want %q", tt.in, s.Endpoint, tt.out)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -67,3 +67,4 @@ The following attributes are exported:
* `hosted_zone_id` - The [Route 53 Hosted Zone ID](http://docs.aws.amazon.com/general/latest/gr/rande.html#s3_website_region_endpoints) for this bucket's region.
* `region` - The AWS region this bucket resides in.
* `website_endpoint` - The website endpoint, if the bucket is configured with a website. If not, this will be an empty string.
* `website_domain` - The domain of the website endpoint, if the bucket is configured with a website. If not, this will be an empty string. This is used to create Route 53 alias records.

0 comments on commit cbe9be4

Please sign in to comment.