Merge remote-tracking branch 'upstream/master' into f-aws-volume-attachment
* upstream/master: (21 commits) fix typo fix typo, use awslabs/aws-sdk-go Update CHANGELOG.md More internal links in template documentation. providers/aws: Requires ttl and records attributes if there isn't an ALIAS block. Condense switch fallthroughs into expr lists Fix docs for aws_route53_record params Update CHANGELOG.md provider/aws: Add IAM Server Certificate resource aws_db_instance docs updated per #2070 providers/aws: Adds link to AWS docs about RDS parameters. Downgrade middleman to 3.3.12 as 3.3.13 does not exist providers/aws: Clarifies db_security_group usage. "More more" no more! Indentation issue Export ARN in SQS queue and SNS topic / subscription; updated tests for new AWS SDK errors; updated documentation. Changed Required: false to Optional: true in the SNS topic schema Initial SNS support correct resource name in example added attributes reference section for AWS_EBS_VOLUME ...
This commit is contained in:
commit
3f68ea7d0e
|
@ -2,7 +2,10 @@
|
|||
|
||||
IMPROVEMENTS:
|
||||
|
||||
* **New resource: `aws_iam_server_certificate`** [GH-2086]
|
||||
* **New resource: `aws_sqs_queue`** [GH-1939]
|
||||
* **New resource: `aws_sns_topic`** [GH-1974]
|
||||
* **New resource: `aws_sns_topic_subscription`** [GH-1974]
|
||||
* provider/aws: support ec2 termination protection [GH-1988]
|
||||
* provider/aws: support for RDS Read Replicas [GH-1946]
|
||||
* provider/aws: `aws_s3_bucket` add support for `policy` [GH-1992]
|
||||
|
|
|
@ -18,6 +18,7 @@ import (
|
|||
"github.com/awslabs/aws-sdk-go/service/route53"
|
||||
"github.com/awslabs/aws-sdk-go/service/s3"
|
||||
"github.com/awslabs/aws-sdk-go/service/sqs"
|
||||
"github.com/awslabs/aws-sdk-go/service/sns"
|
||||
)
|
||||
|
||||
type Config struct {
|
||||
|
@ -37,6 +38,7 @@ type AWSClient struct {
|
|||
autoscalingconn *autoscaling.AutoScaling
|
||||
s3conn *s3.S3
|
||||
sqsconn *sqs.SQS
|
||||
snsconn *sns.SNS
|
||||
r53conn *route53.Route53
|
||||
region string
|
||||
rdsconn *rds.RDS
|
||||
|
@ -89,6 +91,9 @@ func (c *Config) Client() (interface{}, error) {
|
|||
log.Println("[INFO] Initializing SQS connection")
|
||||
client.sqsconn = sqs.New(awsConfig)
|
||||
|
||||
log.Println("[INFO] Initializing SNS connection")
|
||||
client.snsconn = sns.New(awsConfig)
|
||||
|
||||
log.Println("[INFO] Initializing RDS Connection")
|
||||
client.rdsconn = rds.New(awsConfig)
|
||||
|
||||
|
|
|
@ -103,6 +103,7 @@ func Provider() terraform.ResourceProvider {
|
|||
"aws_iam_policy": resourceAwsIamPolicy(),
|
||||
"aws_iam_role_policy": resourceAwsIamRolePolicy(),
|
||||
"aws_iam_role": resourceAwsIamRole(),
|
||||
"aws_iam_server_certificate": resourceAwsIAMServerCertificate(),
|
||||
"aws_iam_user_policy": resourceAwsIamUserPolicy(),
|
||||
"aws_iam_user": resourceAwsIamUser(),
|
||||
"aws_instance": resourceAwsInstance(),
|
||||
|
@ -123,6 +124,8 @@ func Provider() terraform.ResourceProvider {
|
|||
"aws_security_group": resourceAwsSecurityGroup(),
|
||||
"aws_security_group_rule": resourceAwsSecurityGroupRule(),
|
||||
"aws_sqs_queue": resourceAwsSqsQueue(),
|
||||
"aws_sns_topic": resourceAwsSnsTopic(),
|
||||
"aws_sns_topic_subscription": resourceAwsSnsTopicSubscription(),
|
||||
"aws_subnet": resourceAwsSubnet(),
|
||||
"aws_volume_attachment": resourceAwsVolumeAttachment(),
|
||||
"aws_vpc_dhcp_options_association": resourceAwsVpcDhcpOptionsAssociation(),
|
||||
|
|
|
@ -5,9 +5,9 @@ import (
|
|||
"log"
|
||||
"time"
|
||||
|
||||
"github.com/awslabs/aws-sdk-go/aws"
|
||||
"github.com/awslabs/aws-sdk-go/aws/awserr"
|
||||
"github.com/awslabs/aws-sdk-go/service/elasticache"
|
||||
"github.com/hashicorp/aws-sdk-go/aws"
|
||||
"github.com/hashicorp/terraform/helper/hashcode"
|
||||
"github.com/hashicorp/terraform/helper/resource"
|
||||
"github.com/hashicorp/terraform/helper/schema"
|
||||
|
|
|
@ -0,0 +1,147 @@
|
|||
package aws
|
||||
|
||||
import (
|
||||
"crypto/sha1"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/awslabs/aws-sdk-go/aws"
|
||||
"github.com/awslabs/aws-sdk-go/aws/awserr"
|
||||
"github.com/awslabs/aws-sdk-go/service/iam"
|
||||
"github.com/hashicorp/terraform/helper/schema"
|
||||
)
|
||||
|
||||
func resourceAwsIAMServerCertificate() *schema.Resource {
|
||||
return &schema.Resource{
|
||||
Create: resourceAwsIAMServerCertificateCreate,
|
||||
Read: resourceAwsIAMServerCertificateRead,
|
||||
Delete: resourceAwsIAMServerCertificateDelete,
|
||||
|
||||
Schema: map[string]*schema.Schema{
|
||||
"certificate_body": &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
ForceNew: true,
|
||||
StateFunc: normalizeCert,
|
||||
},
|
||||
|
||||
"certificate_chain": &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
ForceNew: true,
|
||||
},
|
||||
|
||||
"path": &schema.Schema{
|
||||
Type: schema.TypeBool,
|
||||
Optional: true,
|
||||
ForceNew: true,
|
||||
},
|
||||
|
||||
"private_key": &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
ForceNew: true,
|
||||
StateFunc: normalizeCert,
|
||||
},
|
||||
|
||||
"name": &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
ForceNew: true,
|
||||
},
|
||||
|
||||
"arn": &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func resourceAwsIAMServerCertificateCreate(d *schema.ResourceData, meta interface{}) error {
|
||||
conn := meta.(*AWSClient).iamconn
|
||||
|
||||
createOpts := &iam.UploadServerCertificateInput{
|
||||
CertificateBody: aws.String(d.Get("certificate_body").(string)),
|
||||
PrivateKey: aws.String(d.Get("private_key").(string)),
|
||||
ServerCertificateName: aws.String(d.Get("name").(string)),
|
||||
}
|
||||
|
||||
if v, ok := d.GetOk("certificate_chain"); ok {
|
||||
createOpts.CertificateChain = aws.String(v.(string))
|
||||
}
|
||||
|
||||
if v, ok := d.GetOk("Path"); ok {
|
||||
createOpts.Path = aws.String(v.(string))
|
||||
}
|
||||
|
||||
resp, err := conn.UploadServerCertificate(createOpts)
|
||||
if err != nil {
|
||||
if awsErr, ok := err.(awserr.Error); ok {
|
||||
return fmt.Errorf("[WARN] Error uploading server certificate, error: %s: %s", awsErr.Code(), awsErr.Message())
|
||||
}
|
||||
return fmt.Errorf("[WARN] Error uploading server certificate, error: %s", err)
|
||||
}
|
||||
|
||||
d.SetId(*resp.ServerCertificateMetadata.ServerCertificateID)
|
||||
|
||||
return resourceAwsIAMServerCertificateRead(d, meta)
|
||||
}
|
||||
|
||||
func resourceAwsIAMServerCertificateRead(d *schema.ResourceData, meta interface{}) error {
|
||||
conn := meta.(*AWSClient).iamconn
|
||||
resp, err := conn.GetServerCertificate(&iam.GetServerCertificateInput{
|
||||
ServerCertificateName: aws.String(d.Get("name").(string)),
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
if awsErr, ok := err.(awserr.Error); ok {
|
||||
return fmt.Errorf("[WARN] Error reading IAM Server Certificate: %s: %s", awsErr.Code(), awsErr.Message())
|
||||
}
|
||||
return fmt.Errorf("[WARN] Error reading IAM Server Certificate: %s", err)
|
||||
}
|
||||
|
||||
// these values should always be present, and have a default if not set in
|
||||
// configuration, and so safe to reference with nil checks
|
||||
d.Set("certificate_body", normalizeCert(resp.ServerCertificate.CertificateBody))
|
||||
d.Set("certificate_chain", resp.ServerCertificate.CertificateChain)
|
||||
d.Set("path", resp.ServerCertificate.ServerCertificateMetadata.Path)
|
||||
d.Set("arn", resp.ServerCertificate.ServerCertificateMetadata.ARN)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func resourceAwsIAMServerCertificateDelete(d *schema.ResourceData, meta interface{}) error {
|
||||
conn := meta.(*AWSClient).iamconn
|
||||
_, err := conn.DeleteServerCertificate(&iam.DeleteServerCertificateInput{
|
||||
ServerCertificateName: aws.String(d.Get("name").(string)),
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
if awsErr, ok := err.(awserr.Error); ok {
|
||||
return fmt.Errorf("[WARN] Error deleting server certificate: %s: %s", awsErr.Code(), awsErr.Message())
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
d.SetId("")
|
||||
return nil
|
||||
}
|
||||
|
||||
func normalizeCert(cert interface{}) string {
|
||||
if cert == nil {
|
||||
return ""
|
||||
}
|
||||
switch cert.(type) {
|
||||
case string:
|
||||
hash := sha1.Sum([]byte(strings.TrimSpace(cert.(string))))
|
||||
return hex.EncodeToString(hash[:])
|
||||
case *string:
|
||||
hash := sha1.Sum([]byte(strings.TrimSpace(*cert.(*string))))
|
||||
return hex.EncodeToString(hash[:])
|
||||
default:
|
||||
return ""
|
||||
}
|
||||
}
|
|
@ -0,0 +1,194 @@
|
|||
package aws
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/awslabs/aws-sdk-go/aws"
|
||||
"github.com/awslabs/aws-sdk-go/service/iam"
|
||||
"github.com/hashicorp/terraform/helper/resource"
|
||||
"github.com/hashicorp/terraform/terraform"
|
||||
)
|
||||
|
||||
func TestAccIAMServerCertificate_basic(t *testing.T) {
|
||||
var cert iam.ServerCertificate
|
||||
|
||||
resource.Test(t, resource.TestCase{
|
||||
PreCheck: func() { testAccPreCheck(t) },
|
||||
Providers: testAccProviders,
|
||||
CheckDestroy: testAccCheckIAMServerCertificateDestroy,
|
||||
Steps: []resource.TestStep{
|
||||
resource.TestStep{
|
||||
Config: testAccIAMServerCertConfig,
|
||||
Check: resource.ComposeTestCheckFunc(
|
||||
testAccCheckCertExists("aws_iam_server_certificate.test_cert", &cert),
|
||||
testAccCheckAWSServerCertAttributes(&cert),
|
||||
),
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func testAccCheckCertExists(n string, cert *iam.ServerCertificate) resource.TestCheckFunc {
|
||||
return func(s *terraform.State) error {
|
||||
rs, ok := s.RootModule().Resources[n]
|
||||
if !ok {
|
||||
return fmt.Errorf("Not found: %s", n)
|
||||
}
|
||||
|
||||
if rs.Primary.ID == "" {
|
||||
return fmt.Errorf("No Server Cert ID is set")
|
||||
}
|
||||
|
||||
conn := testAccProvider.Meta().(*AWSClient).iamconn
|
||||
describeOpts := &iam.GetServerCertificateInput{
|
||||
ServerCertificateName: aws.String(rs.Primary.Attributes["name"]),
|
||||
}
|
||||
resp, err := conn.GetServerCertificate(describeOpts)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
*cert = *resp.ServerCertificate
|
||||
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func testAccCheckAWSServerCertAttributes(cert *iam.ServerCertificate) resource.TestCheckFunc {
|
||||
return func(s *terraform.State) error {
|
||||
if !strings.HasPrefix(*cert.ServerCertificateMetadata.ServerCertificateName, "terraform-test-cert") {
|
||||
return fmt.Errorf("Bad Server Cert Name: %s", *cert.ServerCertificateMetadata.ServerCertificateName)
|
||||
}
|
||||
|
||||
if *cert.CertificateBody != strings.TrimSpace(certBody) {
|
||||
return fmt.Errorf("Bad Server Cert body\n\t expected: %s\n\tgot: %s\n", certBody, *cert.CertificateBody)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func testAccCheckIAMServerCertificateDestroy(s *terraform.State) error {
|
||||
conn := testAccProvider.Meta().(*AWSClient).iamconn
|
||||
|
||||
for _, rs := range s.RootModule().Resources {
|
||||
if rs.Type != "aws_iam_server_certificate" {
|
||||
continue
|
||||
}
|
||||
|
||||
// Try to find the Cert
|
||||
opts := &iam.GetServerCertificateInput{
|
||||
ServerCertificateName: aws.String(rs.Primary.Attributes["name"]),
|
||||
}
|
||||
resp, err := conn.GetServerCertificate(opts)
|
||||
if err == nil {
|
||||
if resp.ServerCertificate != nil {
|
||||
return fmt.Errorf("Error: Server Cert still exists")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
var certBody = fmt.Sprintf(`
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIExDCCA6ygAwIBAgIJALX7Jt7ddT3eMA0GCSqGSIb3DQEBBQUAMIGcMQswCQYD
|
||||
VQQGEwJVUzERMA8GA1UECBMITWlzc291cmkxETAPBgNVBAcTCENvbHVtYmlhMRIw
|
||||
EAYDVQQKEwlIYXNoaUNvcnAxEjAQBgNVBAsTCVRlcnJhZm9ybTEbMBkGA1UEAxMS
|
||||
d3d3Lm5vdGV4YW1wbGUuY29tMSIwIAYJKoZIhvcNAQkBFhNjbGludEBoYXNoaWNv
|
||||
cnAuY29tMB4XDTE1MDUyNjE0MzA1MloXDTE4MDUyNTE0MzA1MlowgZwxCzAJBgNV
|
||||
BAYTAlVTMREwDwYDVQQIEwhNaXNzb3VyaTERMA8GA1UEBxMIQ29sdW1iaWExEjAQ
|
||||
BgNVBAoTCUhhc2hpQ29ycDESMBAGA1UECxMJVGVycmFmb3JtMRswGQYDVQQDExJ3
|
||||
d3cubm90ZXhhbXBsZS5jb20xIjAgBgkqhkiG9w0BCQEWE2NsaW50QGhhc2hpY29y
|
||||
cC5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCownyOIKXBbYxh
|
||||
PynVAw30eaJj2OmilFJagwGeFHMT0rErCodY8lAQsPz6gj83NC9D4MzDt1H+GmoR
|
||||
MSDphJEUxxTxvaNWTTN5sZ9WvE+sbw5YkkTXc4DmVsVMoa3urQO20f0tcHXyULj0
|
||||
sXbtG+q/QhKxqeFjYON46Z6l7x32d/cj4mIcXwLpIf+W2wpvXCKAc8851skJ+O9W
|
||||
UW0/h/ivwwkKfzGfiObL16IUaq+fxwnkYt3fUI2Z4rSKAULMEcquzfKr3JR6wkeI
|
||||
J66ZSb6fMNlCPGPcINDhzwSgGRpqRqeuRl4Z9m2fZaaYVltHqjwDH1tKr+3qXFnv
|
||||
nZmq7pzJAgMBAAGjggEFMIIBATAdBgNVHQ4EFgQUO8bEvPq+V/rtnlhTxQDusR7o
|
||||
n6QwgdEGA1UdIwSByTCBxoAUO8bEvPq+V/rtnlhTxQDusR7on6ShgaKkgZ8wgZwx
|
||||
CzAJBgNVBAYTAlVTMREwDwYDVQQIEwhNaXNzb3VyaTERMA8GA1UEBxMIQ29sdW1i
|
||||
aWExEjAQBgNVBAoTCUhhc2hpQ29ycDESMBAGA1UECxMJVGVycmFmb3JtMRswGQYD
|
||||
VQQDExJ3d3cubm90ZXhhbXBsZS5jb20xIjAgBgkqhkiG9w0BCQEWE2NsaW50QGhh
|
||||
c2hpY29ycC5jb22CCQC1+ybe3XU93jAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEB
|
||||
BQUAA4IBAQBsJ/NP1uBYm+8ejrpUu2mipT5JfBahpiUxef5BeubSrSM3zmdrtLLA
|
||||
+DdDkrt0AfOaasBXMTEwrR3NunBAmn/6PX0r/PAjlqk/tOVBnASC9t3cmi88fO10
|
||||
gQw+se86MiCr/hTavq2YTQZ652+ksjxeQwyHIzKrYS/rRGPKKHX70H5Asb1CY44p
|
||||
/GRyLvAckzZ1Gp64ym6XCLTS53wOur6wLX1/lqshBo2utUmm/2a/XF4psSDx/k2J
|
||||
E2oHzGoJ2F/+QkiXHzvPcUXRFVhXkQnZDocCv/nhcEwNkN9Z1OxCNqsZw+FiJm2E
|
||||
FVSdVaOstOHOVllblhWxvjm55a44feFX
|
||||
-----END CERTIFICATE-----`)
|
||||
|
||||
var testAccIAMServerCertConfig = fmt.Sprintf(`
|
||||
resource "aws_iam_server_certificate" "test_cert" {
|
||||
name = "terraform-test-cert-%d"
|
||||
certificate_body = <<EOF
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIExDCCA6ygAwIBAgIJALX7Jt7ddT3eMA0GCSqGSIb3DQEBBQUAMIGcMQswCQYD
|
||||
VQQGEwJVUzERMA8GA1UECBMITWlzc291cmkxETAPBgNVBAcTCENvbHVtYmlhMRIw
|
||||
EAYDVQQKEwlIYXNoaUNvcnAxEjAQBgNVBAsTCVRlcnJhZm9ybTEbMBkGA1UEAxMS
|
||||
d3d3Lm5vdGV4YW1wbGUuY29tMSIwIAYJKoZIhvcNAQkBFhNjbGludEBoYXNoaWNv
|
||||
cnAuY29tMB4XDTE1MDUyNjE0MzA1MloXDTE4MDUyNTE0MzA1MlowgZwxCzAJBgNV
|
||||
BAYTAlVTMREwDwYDVQQIEwhNaXNzb3VyaTERMA8GA1UEBxMIQ29sdW1iaWExEjAQ
|
||||
BgNVBAoTCUhhc2hpQ29ycDESMBAGA1UECxMJVGVycmFmb3JtMRswGQYDVQQDExJ3
|
||||
d3cubm90ZXhhbXBsZS5jb20xIjAgBgkqhkiG9w0BCQEWE2NsaW50QGhhc2hpY29y
|
||||
cC5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCownyOIKXBbYxh
|
||||
PynVAw30eaJj2OmilFJagwGeFHMT0rErCodY8lAQsPz6gj83NC9D4MzDt1H+GmoR
|
||||
MSDphJEUxxTxvaNWTTN5sZ9WvE+sbw5YkkTXc4DmVsVMoa3urQO20f0tcHXyULj0
|
||||
sXbtG+q/QhKxqeFjYON46Z6l7x32d/cj4mIcXwLpIf+W2wpvXCKAc8851skJ+O9W
|
||||
UW0/h/ivwwkKfzGfiObL16IUaq+fxwnkYt3fUI2Z4rSKAULMEcquzfKr3JR6wkeI
|
||||
J66ZSb6fMNlCPGPcINDhzwSgGRpqRqeuRl4Z9m2fZaaYVltHqjwDH1tKr+3qXFnv
|
||||
nZmq7pzJAgMBAAGjggEFMIIBATAdBgNVHQ4EFgQUO8bEvPq+V/rtnlhTxQDusR7o
|
||||
n6QwgdEGA1UdIwSByTCBxoAUO8bEvPq+V/rtnlhTxQDusR7on6ShgaKkgZ8wgZwx
|
||||
CzAJBgNVBAYTAlVTMREwDwYDVQQIEwhNaXNzb3VyaTERMA8GA1UEBxMIQ29sdW1i
|
||||
aWExEjAQBgNVBAoTCUhhc2hpQ29ycDESMBAGA1UECxMJVGVycmFmb3JtMRswGQYD
|
||||
VQQDExJ3d3cubm90ZXhhbXBsZS5jb20xIjAgBgkqhkiG9w0BCQEWE2NsaW50QGhh
|
||||
c2hpY29ycC5jb22CCQC1+ybe3XU93jAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEB
|
||||
BQUAA4IBAQBsJ/NP1uBYm+8ejrpUu2mipT5JfBahpiUxef5BeubSrSM3zmdrtLLA
|
||||
+DdDkrt0AfOaasBXMTEwrR3NunBAmn/6PX0r/PAjlqk/tOVBnASC9t3cmi88fO10
|
||||
gQw+se86MiCr/hTavq2YTQZ652+ksjxeQwyHIzKrYS/rRGPKKHX70H5Asb1CY44p
|
||||
/GRyLvAckzZ1Gp64ym6XCLTS53wOur6wLX1/lqshBo2utUmm/2a/XF4psSDx/k2J
|
||||
E2oHzGoJ2F/+QkiXHzvPcUXRFVhXkQnZDocCv/nhcEwNkN9Z1OxCNqsZw+FiJm2E
|
||||
FVSdVaOstOHOVllblhWxvjm55a44feFX
|
||||
-----END CERTIFICATE-----
|
||||
EOF
|
||||
|
||||
private_key = <<EOF
|
||||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIEowIBAAKCAQEAqMJ8jiClwW2MYT8p1QMN9HmiY9jpopRSWoMBnhRzE9KxKwqH
|
||||
WPJQELD8+oI/NzQvQ+DMw7dR/hpqETEg6YSRFMcU8b2jVk0zebGfVrxPrG8OWJJE
|
||||
13OA5lbFTKGt7q0DttH9LXB18lC49LF27Rvqv0ISsanhY2DjeOmepe8d9nf3I+Ji
|
||||
HF8C6SH/ltsKb1wigHPPOdbJCfjvVlFtP4f4r8MJCn8xn4jmy9eiFGqvn8cJ5GLd
|
||||
31CNmeK0igFCzBHKrs3yq9yUesJHiCeumUm+nzDZQjxj3CDQ4c8EoBkaakanrkZe
|
||||
GfZtn2WmmFZbR6o8Ax9bSq/t6lxZ752Zqu6cyQIDAQABAoIBAFq2kHVlnzPmSvtL
|
||||
FJVn2ux7JYs+Yff+enYkzY3HuEQDkTBtrGtndRpDyPhvYsOtzWpTQD5EIFLSqAkt
|
||||
u19K3yGoEd4P7ejJ/s1/aQMankk2OSPrHA4kDDnEkrGqhvAxGDoBjnIKbZwfQAxo
|
||||
CGFUDE9amOnfQ0REJIIuMhVH/3coDbsLUQstf43xU0Hl8C7vEPZ0WjX0LKZJsQEg
|
||||
TVp4kF/ohxCsl/rtasrrCTIEWLgsqzYoIs5EivxZR6FwudaM3C/Dlcad3rISHXCe
|
||||
w+dBWhIKqr7c695wkbtKb9x44hAKYAZdPG2eupy+SlQhm1mkl3aV3g6ylwEwhMJW
|
||||
8nV3WcECgYEA0phtwHvXhRuSaCjTHAMf3DBqi8GDg+x9oKDPpFNROjot/rUqkfX8
|
||||
vpHR7roN5bqX/4nDe/CfJE5UmJBbGcKXburRkwRqteT30N3qx9X+Yla9lPXbKo2F
|
||||
TE+jQO5oZ7IdKdycyPOoFvlB0RB8c7pLwXlwWaybvb/2sqEcL0a3zW0CgYEAzST7
|
||||
6YXMKKNvbw9vivm+LenpV6BVk5SOLXbMWtKmOjKLmc2dlD38jL2ZTlWzTbbAncta
|
||||
Kkd4hDwH7rnXueMWwJjhRXKweNG5BsNhSl0NyQeujzHmxT54wGS8nYk48xGZuMNa
|
||||
F0tfodJ2OA2IzyQHHzZ7YJPt85533Wj9CPt4P00CgYBi6T7bIg9msD2CeHI2/Oyw
|
||||
4XiZbWlUw/V5RS5hUtSa0Yqa0AJPjcaIxzpfsrkmRg5v8geDpc9JIRUwltSC89dm
|
||||
PBn0wCVSi1ktm51TAJo7G9xtI1At20xZPCpEK/WThp+V8s0cwPwY1jdodyLMxBoi
|
||||
o+P16lE3vPqkiXEQb1mSvQKBgQCRLddJkHLHX8KA6n+Z7tx0SdHlPYbShpOIAUbm
|
||||
D6WsEhFRq34VZzjPsW5JTcUy/l6aTUtmGGZlzsYeYE8XMmrrqkXijCPvnRxAeQzl
|
||||
P619033pwPr8JBX4slH5ex9ehdowM7ASRDlNoFAhoxJq5ahUoo317zq66i8R9jb8
|
||||
oFqdEQKBgCKhmR2NCfeVuklmnGGKOqpHD5IUnirmsm6/AtIk4HOR7NO+YOEmw9QN
|
||||
0bOSNJPRbWAAZtvWT9/eJi61cAm2UhGN8iTSEWM+ixAn8v+9G+KzcNjccZu39ZCf
|
||||
GWrW9VPbefh6Bhfdh34IQexYbivSxvi4ZZB4lJ8ce0rPJihQILBl
|
||||
-----END RSA PRIVATE KEY-----
|
||||
EOF
|
||||
}
|
||||
`, rand.New(rand.NewSource(time.Now().UnixNano())).Int())
|
|
@ -380,6 +380,14 @@ func resourceAwsRoute53RecordBuildSet(d *schema.ResourceData, zoneName string) (
|
|||
HostedZoneID: aws.String(alias["zone_id"].(string)),
|
||||
}
|
||||
log.Printf("[DEBUG] Creating alias: %#v", alias)
|
||||
} else {
|
||||
if _, ok := d.GetOk("ttl"); !ok {
|
||||
return nil, fmt.Errorf(`provider.aws: aws_route53_record: %s: "ttl": required field is not set`, d.Get("name").(string))
|
||||
}
|
||||
|
||||
if _, ok := d.GetOk("records"); !ok {
|
||||
return nil, fmt.Errorf(`provider.aws: aws_route53_record: %s: "records": required field is not set`, d.Get("name").(string))
|
||||
}
|
||||
}
|
||||
|
||||
if v, ok := d.GetOk("weight"); ok {
|
||||
|
|
|
@ -0,0 +1,153 @@
|
|||
package aws
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
|
||||
"github.com/hashicorp/terraform/helper/schema"
|
||||
|
||||
"github.com/awslabs/aws-sdk-go/aws"
|
||||
"github.com/awslabs/aws-sdk-go/service/sns"
|
||||
)
|
||||
|
||||
// Mutable attributes
|
||||
var SNSAttributeMap = map[string]string{
|
||||
"display_name" : "DisplayName",
|
||||
"policy" : "Policy",
|
||||
"delivery_policy": "DeliveryPolicy",
|
||||
}
|
||||
|
||||
|
||||
func resourceAwsSnsTopic() *schema.Resource {
|
||||
return &schema.Resource{
|
||||
Create: resourceAwsSnsTopicCreate,
|
||||
Read: resourceAwsSnsTopicRead,
|
||||
Update: resourceAwsSnsTopicUpdate,
|
||||
Delete: resourceAwsSnsTopicDelete,
|
||||
|
||||
Schema: map[string]*schema.Schema{
|
||||
"name": &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
ForceNew: true,
|
||||
},
|
||||
"display_name": &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
ForceNew: false,
|
||||
},
|
||||
"policy": &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
ForceNew: false,
|
||||
Computed: true,
|
||||
},
|
||||
"delivery_policy": &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
ForceNew: false,
|
||||
},
|
||||
"arn": &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func resourceAwsSnsTopicCreate(d *schema.ResourceData, meta interface{}) error {
|
||||
snsconn := meta.(*AWSClient).snsconn
|
||||
|
||||
name := d.Get("name").(string)
|
||||
|
||||
log.Printf("[DEBUG] SNS create topic: %s", name)
|
||||
|
||||
req := &sns.CreateTopicInput{
|
||||
Name: aws.String(name),
|
||||
}
|
||||
|
||||
output, err := snsconn.CreateTopic(req)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Error creating SNS topic: %s", err)
|
||||
}
|
||||
|
||||
d.SetId(*output.TopicARN)
|
||||
|
||||
// Write the ARN to the 'arn' field for export
|
||||
d.Set("arn", *output.TopicARN)
|
||||
|
||||
return resourceAwsSnsTopicUpdate(d, meta)
|
||||
}
|
||||
|
||||
func resourceAwsSnsTopicUpdate(d *schema.ResourceData, meta interface{}) error {
|
||||
snsconn := meta.(*AWSClient).snsconn
|
||||
|
||||
resource := *resourceAwsSnsTopic()
|
||||
|
||||
for k, _ := range resource.Schema {
|
||||
if attrKey, ok := SNSAttributeMap[k]; ok {
|
||||
if d.HasChange(k) {
|
||||
log.Printf("[DEBUG] Updating %s", attrKey)
|
||||
_, n := d.GetChange(k)
|
||||
// Ignore an empty policy
|
||||
if !(k == "policy" && n == "") {
|
||||
// Make API call to update attributes
|
||||
req := &sns.SetTopicAttributesInput{
|
||||
TopicARN: aws.String(d.Id()),
|
||||
AttributeName: aws.String(attrKey),
|
||||
AttributeValue: aws.String(n.(string)),
|
||||
}
|
||||
snsconn.SetTopicAttributes(req)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return resourceAwsSnsTopicRead(d, meta)
|
||||
}
|
||||
|
||||
func resourceAwsSnsTopicRead(d *schema.ResourceData, meta interface{}) error {
|
||||
snsconn := meta.(*AWSClient).snsconn
|
||||
|
||||
attributeOutput, err := snsconn.GetTopicAttributes(&sns.GetTopicAttributesInput{
|
||||
TopicARN: aws.String(d.Id()),
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if attributeOutput.Attributes != nil && len(*attributeOutput.Attributes) > 0 {
|
||||
attrmap := *attributeOutput.Attributes
|
||||
resource := *resourceAwsSnsTopic()
|
||||
// iKey = internal struct key, oKey = AWS Attribute Map key
|
||||
for iKey, oKey := range SNSAttributeMap {
|
||||
log.Printf("[DEBUG] Updating %s => %s", iKey, oKey)
|
||||
|
||||
if attrmap[oKey] != nil {
|
||||
// Some of the fetched attributes are stateful properties such as
|
||||
// the number of subscriptions, the owner, etc. skip those
|
||||
if resource.Schema[iKey] != nil {
|
||||
value := *attrmap[oKey]
|
||||
log.Printf("[DEBUG] Updating %s => %s -> %s", iKey, oKey, value)
|
||||
d.Set(iKey, *attrmap[oKey])
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func resourceAwsSnsTopicDelete(d *schema.ResourceData, meta interface{}) error {
|
||||
snsconn := meta.(*AWSClient).snsconn
|
||||
|
||||
log.Printf("[DEBUG] SNS Delete Topic: %s", d.Id())
|
||||
_, err := snsconn.DeleteTopic(&sns.DeleteTopicInput{
|
||||
TopicARN: aws.String(d.Id()),
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
|
@ -0,0 +1,181 @@
|
|||
package aws
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
|
||||
"github.com/hashicorp/terraform/helper/schema"
|
||||
|
||||
"github.com/awslabs/aws-sdk-go/aws"
|
||||
"github.com/awslabs/aws-sdk-go/service/sns"
|
||||
)
|
||||
|
||||
|
||||
func resourceAwsSnsTopicSubscription() *schema.Resource {
|
||||
return &schema.Resource{
|
||||
Create: resourceAwsSnsTopicSubscriptionCreate,
|
||||
Read: resourceAwsSnsTopicSubscriptionRead,
|
||||
Update: resourceAwsSnsTopicSubscriptionUpdate,
|
||||
Delete: resourceAwsSnsTopicSubscriptionDelete,
|
||||
|
||||
Schema: map[string]*schema.Schema{
|
||||
"protocol": &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
ForceNew: false,
|
||||
},
|
||||
"endpoint": &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
ForceNew: false,
|
||||
},
|
||||
"topic_arn": &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
ForceNew: false,
|
||||
},
|
||||
"delivery_policy": &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
ForceNew: false,
|
||||
},
|
||||
"raw_message_delivery": &schema.Schema{
|
||||
Type: schema.TypeBool,
|
||||
Optional: true,
|
||||
ForceNew: false,
|
||||
Default: false,
|
||||
},
|
||||
"arn": &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func resourceAwsSnsTopicSubscriptionCreate(d *schema.ResourceData, meta interface{}) error {
|
||||
snsconn := meta.(*AWSClient).snsconn
|
||||
|
||||
if(d.Get("protocol") == "email") {
|
||||
return fmt.Errorf("Email endpoints are not supported!")
|
||||
}
|
||||
|
||||
output, err := subscribeToSNSTopic(d, snsconn)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
log.Printf("New subscription ARN: %s", *output.SubscriptionARN)
|
||||
d.SetId(*output.SubscriptionARN)
|
||||
|
||||
// Write the ARN to the 'arn' field for export
|
||||
d.Set("arn", *output.SubscriptionARN)
|
||||
|
||||
return resourceAwsSnsTopicSubscriptionUpdate(d, meta)
|
||||
}
|
||||
|
||||
func resourceAwsSnsTopicSubscriptionUpdate(d *schema.ResourceData, meta interface{}) error {
|
||||
snsconn := meta.(*AWSClient).snsconn
|
||||
|
||||
// If any changes happened, un-subscribe and re-subscribe
|
||||
if d.HasChange("protocol") || d.HasChange("endpoint") || d.HasChange("topic_arn") {
|
||||
log.Printf("[DEBUG] Updating subscription %s", d.Id())
|
||||
// Unsubscribe
|
||||
_, err := snsconn.Unsubscribe(&sns.UnsubscribeInput{
|
||||
SubscriptionARN: aws.String(d.Id()),
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return fmt.Errorf("Error unsubscribing from SNS topic: %s", err)
|
||||
}
|
||||
|
||||
// Re-subscribe and set id
|
||||
output, err := subscribeToSNSTopic(d, snsconn)
|
||||
d.SetId(*output.SubscriptionARN)
|
||||
|
||||
}
|
||||
|
||||
if d.HasChange("raw_message_delivery") {
|
||||
_, n := d.GetChange("raw_message_delivery")
|
||||
|
||||
attrValue := "false"
|
||||
|
||||
if n.(bool) {
|
||||
attrValue = "true"
|
||||
}
|
||||
|
||||
req := &sns.SetSubscriptionAttributesInput{
|
||||
SubscriptionARN: aws.String(d.Id()),
|
||||
AttributeName: aws.String("RawMessageDelivery"),
|
||||
AttributeValue: aws.String(attrValue),
|
||||
}
|
||||
_, err := snsconn.SetSubscriptionAttributes(req)
|
||||
|
||||
if err != nil {
|
||||
return fmt.Errorf("Unable to set raw message delivery attribute on subscription")
|
||||
}
|
||||
}
|
||||
|
||||
return resourceAwsSnsTopicSubscriptionRead(d, meta)
|
||||
}
|
||||
|
||||
func resourceAwsSnsTopicSubscriptionRead(d *schema.ResourceData, meta interface{}) error {
|
||||
snsconn := meta.(*AWSClient).snsconn
|
||||
|
||||
log.Printf("[DEBUG] Loading subscription %s", d.Id())
|
||||
|
||||
attributeOutput, err := snsconn.GetSubscriptionAttributes(&sns.GetSubscriptionAttributesInput{
|
||||
SubscriptionARN: aws.String(d.Id()),
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if attributeOutput.Attributes != nil && len(*attributeOutput.Attributes) > 0 {
|
||||
attrHash := *attributeOutput.Attributes
|
||||
log.Printf("[DEBUG] raw message delivery: %s", *attrHash["RawMessageDelivery"])
|
||||
if *attrHash["RawMessageDelivery"] == "true" {
|
||||
d.Set("raw_message_delivery", true)
|
||||
} else {
|
||||
d.Set("raw_message_delivery", false)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func resourceAwsSnsTopicSubscriptionDelete(d *schema.ResourceData, meta interface{}) error {
|
||||
snsconn := meta.(*AWSClient).snsconn
|
||||
|
||||
log.Printf("[DEBUG] SNS delete topic subscription: %s", d.Id())
|
||||
_, err := snsconn.Unsubscribe(&sns.UnsubscribeInput{
|
||||
SubscriptionARN: aws.String(d.Id()),
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func subscribeToSNSTopic(d *schema.ResourceData, snsconn *sns.SNS) (output *sns.SubscribeOutput, err error) {
|
||||
protocol := d.Get("protocol").(string)
|
||||
endpoint := d.Get("endpoint").(string)
|
||||
topic_arn := d.Get("topic_arn").(string)
|
||||
|
||||
log.Printf("[DEBUG] SNS create topic subscription: %s (%s) @ '%s'", endpoint, protocol, topic_arn)
|
||||
|
||||
req := &sns.SubscribeInput{
|
||||
Protocol: aws.String(protocol),
|
||||
Endpoint: aws.String(endpoint),
|
||||
TopicARN: aws.String(topic_arn),
|
||||
}
|
||||
|
||||
output, err = snsconn.Subscribe(req)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Error creating SNS topic: %s", err)
|
||||
}
|
||||
|
||||
log.Printf("[DEBUG] Created new subscription!")
|
||||
return output, nil
|
||||
}
|
|
@ -0,0 +1,103 @@
|
|||
package aws
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/awslabs/aws-sdk-go/aws"
|
||||
"github.com/awslabs/aws-sdk-go/service/sns"
|
||||
"github.com/hashicorp/terraform/helper/resource"
|
||||
"github.com/hashicorp/terraform/terraform"
|
||||
"github.com/awslabs/aws-sdk-go/aws/awserr"
|
||||
)
|
||||
|
||||
func TestAccAWSSNSTopicSubscription(t *testing.T) {
|
||||
resource.Test(t, resource.TestCase{
|
||||
PreCheck: func() { testAccPreCheck(t) },
|
||||
Providers: testAccProviders,
|
||||
CheckDestroy: testAccCheckAWSSNSTopicSubscriptionDestroy,
|
||||
Steps: []resource.TestStep{
|
||||
resource.TestStep{
|
||||
Config: testAccAWSSNSTopicSubscriptionConfig,
|
||||
Check: resource.ComposeTestCheckFunc(
|
||||
testAccCheckAWSSNSTopicExists("aws_sns_topic.test_topic"),
|
||||
testAccCheckAWSSNSTopicSubscriptionExists("aws_sns_topic_subscription.test_subscription"),
|
||||
),
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
func testAccCheckAWSSNSTopicSubscriptionDestroy(s *terraform.State) error {
|
||||
conn := testAccProvider.Meta().(*AWSClient).snsconn
|
||||
|
||||
for _, rs := range s.RootModule().Resources {
|
||||
if rs.Type != "aws_sns_topic" {
|
||||
continue
|
||||
}
|
||||
|
||||
// Try to find key pair
|
||||
req := &sns.GetSubscriptionAttributesInput{
|
||||
SubscriptionARN: aws.String(rs.Primary.ID),
|
||||
}
|
||||
|
||||
|
||||
_, err := conn.GetSubscriptionAttributes(req)
|
||||
|
||||
if err == nil {
|
||||
return fmt.Errorf("Subscription still exists, can't continue.")
|
||||
}
|
||||
|
||||
// Verify the error is an API error, not something else
|
||||
_, ok := err.(awserr.Error)
|
||||
if !ok {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
func testAccCheckAWSSNSTopicSubscriptionExists(n string) resource.TestCheckFunc {
|
||||
return func(s *terraform.State) error {
|
||||
rs, ok := s.RootModule().Resources[n]
|
||||
if !ok {
|
||||
return fmt.Errorf("Not found: %s", n)
|
||||
}
|
||||
|
||||
if rs.Primary.ID == "" {
|
||||
return fmt.Errorf("No SNS subscription with that ARN exists")
|
||||
}
|
||||
|
||||
conn := testAccProvider.Meta().(*AWSClient).snsconn
|
||||
|
||||
params := &sns.GetSubscriptionAttributesInput{
|
||||
SubscriptionARN: aws.String(rs.Primary.ID),
|
||||
}
|
||||
_, err := conn.GetSubscriptionAttributes(params)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
const testAccAWSSNSTopicSubscriptionConfig = `
|
||||
resource "aws_sns_topic" "test_topic" {
|
||||
name = "terraform-test-topic"
|
||||
}
|
||||
|
||||
resource "aws_sqs_queue" "test_queue" {
|
||||
name = "terraform-subscription-test-queue"
|
||||
}
|
||||
|
||||
resource "aws_sns_topic_subscription" "test_subscription" {
|
||||
topic_arn = "${aws_sns_topic.test_topic.arn}"
|
||||
protocol = "sqs"
|
||||
endpoint = "${aws_sqs_queue.test_queue.arn}"
|
||||
}
|
||||
`
|
|
@ -0,0 +1,89 @@
|
|||
package aws
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/awslabs/aws-sdk-go/aws"
|
||||
"github.com/awslabs/aws-sdk-go/service/sns"
|
||||
"github.com/hashicorp/terraform/helper/resource"
|
||||
"github.com/hashicorp/terraform/terraform"
|
||||
"github.com/awslabs/aws-sdk-go/aws/awserr"
|
||||
)
|
||||
|
||||
func TestAccAWSSNSTopic(t *testing.T) {
|
||||
resource.Test(t, resource.TestCase{
|
||||
PreCheck: func() { testAccPreCheck(t) },
|
||||
Providers: testAccProviders,
|
||||
CheckDestroy: testAccCheckAWSSNSTopicDestroy,
|
||||
Steps: []resource.TestStep{
|
||||
resource.TestStep{
|
||||
Config: testAccAWSSNSTopicConfig,
|
||||
Check: resource.ComposeTestCheckFunc(
|
||||
testAccCheckAWSSNSTopicExists("aws_sns_topic.test_topic"),
|
||||
),
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
func testAccCheckAWSSNSTopicDestroy(s *terraform.State) error {
|
||||
conn := testAccProvider.Meta().(*AWSClient).snsconn
|
||||
|
||||
for _, rs := range s.RootModule().Resources {
|
||||
if rs.Type != "aws_sns_topic" {
|
||||
continue
|
||||
}
|
||||
|
||||
// Check if the topic exists by fetching its attributes
|
||||
params := &sns.GetTopicAttributesInput{
|
||||
TopicARN: aws.String(rs.Primary.ID),
|
||||
}
|
||||
_, err := conn.GetTopicAttributes(params)
|
||||
if err == nil {
|
||||
return fmt.Errorf("Topic exists when it should be destroyed!")
|
||||
}
|
||||
|
||||
// Verify the error is an API error, not something else
|
||||
_, ok := err.(awserr.Error)
|
||||
if !ok {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
func testAccCheckAWSSNSTopicExists(n string) resource.TestCheckFunc {
|
||||
return func(s *terraform.State) error {
|
||||
rs, ok := s.RootModule().Resources[n]
|
||||
if !ok {
|
||||
return fmt.Errorf("Not found: %s", n)
|
||||
}
|
||||
|
||||
if rs.Primary.ID == "" {
|
||||
return fmt.Errorf("No SNS topic with that ARN exists")
|
||||
}
|
||||
|
||||
conn := testAccProvider.Meta().(*AWSClient).snsconn
|
||||
|
||||
params := &sns.GetTopicAttributesInput{
|
||||
TopicARN: aws.String(rs.Primary.ID),
|
||||
}
|
||||
_, err := conn.GetTopicAttributes(params)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
const testAccAWSSNSTopicConfig = `
|
||||
resource "aws_sns_topic" "test_topic" {
|
||||
name = "terraform-test-topic"
|
||||
}
|
||||
`
|
|
@ -19,6 +19,7 @@ var AttributeMap = map[string]string{
|
|||
"visibility_timeout_seconds": "VisibilityTimeout",
|
||||
"policy": "Policy",
|
||||
"redrive_policy": "RedrivePolicy",
|
||||
"arn": "QueueArn",
|
||||
}
|
||||
|
||||
// A number of these are marked as computed because if you don't
|
||||
|
@ -70,6 +71,10 @@ func resourceAwsSqsQueue() *schema.Resource {
|
|||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
},
|
||||
"arn": &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
@ -154,6 +159,7 @@ func resourceAwsSqsQueueRead(d *schema.ResourceData, meta interface{}) error {
|
|||
QueueURL: aws.String(d.Id()),
|
||||
AttributeNames: []*string{aws.String("All")},
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -51,11 +51,7 @@ func (p *ResourceProvisioner) Validate(c *terraform.ResourceConfig) (ws []string
|
|||
num := 0
|
||||
for name := range c.Raw {
|
||||
switch name {
|
||||
case "scripts":
|
||||
fallthrough
|
||||
case "script":
|
||||
fallthrough
|
||||
case "inline":
|
||||
case "scripts", "script", "inline":
|
||||
num++
|
||||
default:
|
||||
es = append(es, fmt.Errorf("Unknown configuration '%s'", name))
|
||||
|
|
|
@ -33,9 +33,7 @@ type fileLoaderFunc func(path string) (configurable, []string, error)
|
|||
func loadTree(root string) (*importTree, error) {
|
||||
var f fileLoaderFunc
|
||||
switch ext(root) {
|
||||
case ".tf":
|
||||
fallthrough
|
||||
case ".tf.json":
|
||||
case ".tf", ".tf.json":
|
||||
f = loadFileHcl
|
||||
default:
|
||||
}
|
||||
|
|
|
@ -299,9 +299,7 @@ func (x *parserLex) lexString(yylval *parserSymType, quoted bool) (int, bool) {
|
|||
// Let's check to see if we're escaping anything.
|
||||
if c == '\\' {
|
||||
switch n := x.next(); n {
|
||||
case '\\':
|
||||
fallthrough
|
||||
case '"':
|
||||
case '\\', '"':
|
||||
c = n
|
||||
case 'n':
|
||||
c = '\n'
|
||||
|
|
|
@ -78,19 +78,11 @@ func addrToSchema(addr []string, schemaMap map[string]*Schema) []*Schema {
|
|||
}
|
||||
|
||||
switch t := current.Type; t {
|
||||
case TypeBool:
|
||||
fallthrough
|
||||
case TypeInt:
|
||||
fallthrough
|
||||
case TypeFloat:
|
||||
fallthrough
|
||||
case TypeString:
|
||||
case TypeBool, TypeInt, TypeFloat, TypeString:
|
||||
if len(addr) > 0 {
|
||||
return nil
|
||||
}
|
||||
case TypeList:
|
||||
fallthrough
|
||||
case TypeSet:
|
||||
case TypeList, TypeSet:
|
||||
switch v := current.Elem.(type) {
|
||||
case *Resource:
|
||||
current = &Schema{
|
||||
|
|
|
@ -80,13 +80,7 @@ func (r *ConfigFieldReader) readField(
|
|||
k := strings.Join(address, ".")
|
||||
schema := schemaList[len(schemaList)-1]
|
||||
switch schema.Type {
|
||||
case TypeBool:
|
||||
fallthrough
|
||||
case TypeFloat:
|
||||
fallthrough
|
||||
case TypeInt:
|
||||
fallthrough
|
||||
case TypeString:
|
||||
case TypeBool, TypeFloat, TypeInt, TypeString:
|
||||
return r.readPrimitive(k, schema)
|
||||
case TypeList:
|
||||
return readListField(&nestedConfigFieldReader{r}, address, schema)
|
||||
|
|
|
@ -39,13 +39,7 @@ func (r *DiffFieldReader) ReadField(address []string) (FieldReadResult, error) {
|
|||
|
||||
schema := schemaList[len(schemaList)-1]
|
||||
switch schema.Type {
|
||||
case TypeBool:
|
||||
fallthrough
|
||||
case TypeInt:
|
||||
fallthrough
|
||||
case TypeFloat:
|
||||
fallthrough
|
||||
case TypeString:
|
||||
case TypeBool, TypeInt, TypeFloat, TypeString:
|
||||
return r.readPrimitive(address, schema)
|
||||
case TypeList:
|
||||
return readListField(r, address, schema)
|
||||
|
|
|
@ -21,13 +21,7 @@ func (r *MapFieldReader) ReadField(address []string) (FieldReadResult, error) {
|
|||
|
||||
schema := schemaList[len(schemaList)-1]
|
||||
switch schema.Type {
|
||||
case TypeBool:
|
||||
fallthrough
|
||||
case TypeInt:
|
||||
fallthrough
|
||||
case TypeFloat:
|
||||
fallthrough
|
||||
case TypeString:
|
||||
case TypeBool, TypeInt, TypeFloat, TypeString:
|
||||
return r.readPrimitive(address, schema)
|
||||
case TypeList:
|
||||
return readListField(r, address, schema)
|
||||
|
|
|
@ -74,13 +74,7 @@ func (w *MapFieldWriter) set(addr []string, value interface{}) error {
|
|||
|
||||
schema := schemaList[len(schemaList)-1]
|
||||
switch schema.Type {
|
||||
case TypeBool:
|
||||
fallthrough
|
||||
case TypeInt:
|
||||
fallthrough
|
||||
case TypeFloat:
|
||||
fallthrough
|
||||
case TypeString:
|
||||
case TypeBool, TypeInt, TypeFloat, TypeString:
|
||||
return w.setPrimitive(addr, value, schema)
|
||||
case TypeList:
|
||||
return w.setList(addr, value, schema)
|
||||
|
|
|
@ -378,13 +378,7 @@ func (m schemaMap) Input(
|
|||
|
||||
var value interface{}
|
||||
switch v.Type {
|
||||
case TypeBool:
|
||||
fallthrough
|
||||
case TypeInt:
|
||||
fallthrough
|
||||
case TypeFloat:
|
||||
fallthrough
|
||||
case TypeSet:
|
||||
case TypeBool, TypeInt, TypeFloat, TypeSet:
|
||||
continue
|
||||
case TypeString:
|
||||
value, err = m.inputString(input, k, v)
|
||||
|
@ -522,13 +516,7 @@ func (m schemaMap) diff(
|
|||
all bool) error {
|
||||
var err error
|
||||
switch schema.Type {
|
||||
case TypeBool:
|
||||
fallthrough
|
||||
case TypeInt:
|
||||
fallthrough
|
||||
case TypeFloat:
|
||||
fallthrough
|
||||
case TypeString:
|
||||
case TypeBool, TypeInt, TypeFloat, TypeString:
|
||||
err = m.diffString(k, schema, diff, d, all)
|
||||
case TypeList:
|
||||
err = m.diffList(k, schema, diff, d, all)
|
||||
|
@ -1170,9 +1158,7 @@ func (m schemaMap) validateType(
|
|||
var ws []string
|
||||
var es []error
|
||||
switch schema.Type {
|
||||
case TypeSet:
|
||||
fallthrough
|
||||
case TypeList:
|
||||
case TypeSet, TypeList:
|
||||
ws, es = m.validateList(k, raw, schema, c)
|
||||
case TypeMap:
|
||||
ws, es = m.validateMap(k, raw, schema, c)
|
||||
|
|
|
@ -149,15 +149,11 @@ func (d *ModuleDiff) ChangeType() DiffChangeType {
|
|||
for _, r := range d.Resources {
|
||||
change := r.ChangeType()
|
||||
switch change {
|
||||
case DiffCreate:
|
||||
fallthrough
|
||||
case DiffDestroy:
|
||||
case DiffCreate, DiffDestroy:
|
||||
if result == DiffNone {
|
||||
result = change
|
||||
}
|
||||
case DiffDestroyCreate:
|
||||
fallthrough
|
||||
case DiffUpdate:
|
||||
case DiffDestroyCreate, DiffUpdate:
|
||||
result = DiffUpdate
|
||||
}
|
||||
}
|
||||
|
|
|
@ -148,9 +148,7 @@ func (n *GraphNodeConfigResource) DynamicExpand(ctx EvalContext) (*Graph, error)
|
|||
// Primary and non-destroy modes are responsible for creating/destroying
|
||||
// all the nodes, expanding counts.
|
||||
switch n.DestroyMode {
|
||||
case DestroyNone:
|
||||
fallthrough
|
||||
case DestroyPrimary:
|
||||
case DestroyNone, DestroyPrimary:
|
||||
steps = append(steps, &ResourceCountTransformer{
|
||||
Resource: n.Resource,
|
||||
Destroy: n.DestroyMode != DestroyNone,
|
||||
|
|
|
@ -79,18 +79,18 @@ GEM
|
|||
celluloid (~> 0.16.0)
|
||||
rb-fsevent (>= 0.9.3)
|
||||
rb-inotify (>= 0.9)
|
||||
middleman (3.3.13)
|
||||
middleman (3.3.12)
|
||||
coffee-script (~> 2.2)
|
||||
compass (>= 1.0.0, < 2.0.0)
|
||||
compass-import-once (= 1.0.5)
|
||||
execjs (~> 2.0)
|
||||
haml (>= 4.0.5)
|
||||
kramdown (~> 1.2)
|
||||
middleman-core (= 3.3.13)
|
||||
middleman-core (= 3.3.12)
|
||||
middleman-sprockets (>= 3.1.2)
|
||||
sass (>= 3.4.0, < 4.0)
|
||||
uglifier (~> 2.5)
|
||||
middleman-core (3.3.13)
|
||||
middleman-core (3.3.12)
|
||||
activesupport (~> 4.1.0)
|
||||
bundler (~> 1.1)
|
||||
erubis
|
||||
|
|
|
@ -133,7 +133,7 @@ The supported built-in functions are:
|
|||
|
||||
## Templates
|
||||
|
||||
Long strings can be managed using templates. Templates are [resources](/docs/configuration/resources.html) defined by a filename and some variables to use during interpolation. They have a computed `rendered` attribute containing the result.
|
||||
Long strings can be managed using templates. [Templates](/docs/providers/template/index.html) are [resources](/docs/configuration/resources.html) defined by a filename and some variables to use during interpolation. They have a computed `rendered` attribute containing the result.
|
||||
|
||||
A template resource looks like:
|
||||
|
||||
|
|
|
@ -29,6 +29,9 @@ resource "aws_db_instance" "default" {
|
|||
|
||||
## Argument Reference
|
||||
|
||||
For a more detailed documentation about the each argument refer to
|
||||
the [AWS official documentation](http://docs.aws.amazon.com/AmazonRDS/latest/CommandLineReference/CLIReference-cmd-ModifyDBInstance.html).
|
||||
|
||||
The following arguments are supported:
|
||||
|
||||
* `allocated_storage` - (Required) The allocated storage in gigabytes.
|
||||
|
@ -65,7 +68,7 @@ The following arguments are supported:
|
|||
* `storage_encrypted` - (Optional) Specifies whether the DB instance is encrypted. The default is `false` if not specified.
|
||||
* `apply_immediately` - (Optional) Specifies whether any database modifications
|
||||
are applied immediately, or during the next maintenance window. Default is
|
||||
`false`. See [Amazon RDS Documentation for more for more information.](http://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/Overview.DBInstance.Modifying.html)
|
||||
`false`. See [Amazon RDS Documentation for more information.](http://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/Overview.DBInstance.Modifying.html)
|
||||
* `replicate_source_db` - (Optional) Specifies that this resource is a Replicate
|
||||
database, and to use this value as the source database. This correlates to the
|
||||
`identifier` of another Amazon RDS Database to replicate. See
|
||||
|
@ -100,5 +103,4 @@ The following attributes are exported:
|
|||
* `username` - The master username for the database
|
||||
* `storage_encrypted` - Specifies whether the DB instance is encrypted
|
||||
|
||||
|
||||
[1]: http://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/Overview.Replication.html
|
||||
|
|
|
@ -8,7 +8,10 @@ description: |-
|
|||
|
||||
# aws\_db\_security\_group
|
||||
|
||||
Provides an RDS security group resource.
|
||||
Provides an RDS security group resource. This is only for DB instances in the
|
||||
EC2-Classic Platform. For instances inside a VPC, use the
|
||||
[`aws_db_instance.vpc_security_group_ids`](/docs/providers/aws/r/db_instance.html#vpc_security_group_ids)
|
||||
attribute instead.
|
||||
|
||||
## Example Usage
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@ layout: "aws"
|
|||
page_title: "AWS: aws_ebs_volume"
|
||||
sidebar_current: "docs-aws-resource-ebs-volume"
|
||||
description: |-
|
||||
Provides an Elastic IP resource.
|
||||
Provides an elastic block storage resource.
|
||||
---
|
||||
|
||||
# aws\_ebs\_volume
|
||||
|
@ -30,3 +30,12 @@ The following arguments are supported:
|
|||
* `snapshot_id` (Optinal) A snapshot to base the EBS volume off of.
|
||||
* `type` - (Optional) The type of EBS volume.
|
||||
* `kms_key_id` - (Optional) The KMS key ID for the volume.
|
||||
|
||||
|
||||
## Attributes Reference
|
||||
|
||||
The following attributes are exported:
|
||||
|
||||
* `id` - The volume ID (e.g. vol-59fcb34e).
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1,102 @@
|
|||
---
|
||||
layout: "aws"
|
||||
page_title: "AWS: aws_iam_server_certificate"
|
||||
sidebar_current: "docs-aws-resource-iam-server-certificate"
|
||||
description: |-
|
||||
Provides an IAM Server Certificate
|
||||
---
|
||||
|
||||
# aws\_iam\_server\_certificate
|
||||
|
||||
Provides an IAM Server Certificate resource to upload Server Certificates.
|
||||
Certs uploated to IAM can easily work with other AWS services such as:
|
||||
|
||||
- AWS Elastic Beanstalk
|
||||
- Elastic Load Balancing
|
||||
- CloudFront
|
||||
- AWS OpsWorks
|
||||
|
||||
For information about server certificates in IAM, see [Managing Server
|
||||
Certficates][2] in AWS Documentation.
|
||||
|
||||
## Example Usage
|
||||
|
||||
**Using certs on file:**
|
||||
|
||||
```
|
||||
resource "aws_iam_server_certificate" "test_cert" {
|
||||
name = "some_test_cert"
|
||||
certificate_body = "${file("self-ca-cert.pem")}"
|
||||
private_key = "${file("test-key.pem")}"
|
||||
}
|
||||
```
|
||||
|
||||
**Example with cert in-line:**
|
||||
|
||||
```
|
||||
resource "aws_iam_server_certificate" "test_cert_alt" {
|
||||
name = "alt_test_cert"
|
||||
certificate_body = <<EOF
|
||||
-----BEGIN CERTIFICATE-----
|
||||
[......] # cert contents
|
||||
-----END CERTIFICATE-----
|
||||
EOF
|
||||
|
||||
private_key = <<EOF
|
||||
-----BEGIN RSA PRIVATE KEY-----
|
||||
[......] # cert contents
|
||||
-----END CERTIFICATE-----
|
||||
EOF
|
||||
}
|
||||
```
|
||||
|
||||
**Use in combination with an AWS ELB resource:**
|
||||
|
||||
```
|
||||
resource "aws_iam_server_certificate" "test_cert" {
|
||||
name = "some_test_cert"
|
||||
certificate_body = "${file("self-ca-cert.pem")}"
|
||||
private_key = "${file("test-key.pem")}"
|
||||
}
|
||||
|
||||
resource "aws_elb" "ourapp" {
|
||||
name = "terraform-asg-deployment-example"
|
||||
availability_zones = ["us-west-2a"]
|
||||
cross_zone_load_balancing = true
|
||||
|
||||
listener {
|
||||
instance_port = 8000
|
||||
instance_protocol = "http"
|
||||
lb_port = 443
|
||||
lb_protocol = "https"
|
||||
ssl_certificate_id = "${aws_iam_server_certificate.test_cert.arn}"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Argument Reference
|
||||
|
||||
The following arguments are supported:
|
||||
|
||||
* `name` - (Required) The name of the Server Certificate. Do not include the
|
||||
path in this value.
|
||||
* `certificate_body` – (Required) The contents of the public key certificate in
|
||||
PEM-encoded format.
|
||||
* `certificate_chain` – (Optional) The contents of the certificate chain.
|
||||
This is typically a concatenation of the PEM-encoded public key certificates
|
||||
of the chain.
|
||||
* `private_key` – (Required) The contents of the private key in PEM-encoded format.
|
||||
* `path` - (Optional) The IAM path for the server certificate. If it is not
|
||||
included, it defaults to a slash (/). If this certificate is for use with
|
||||
AWS CloudFront, the path must be in format `/cloudfront/your_path_here`.
|
||||
See [IAM Identifiers][1] for more details on IAM Paths.
|
||||
|
||||
## Attributes Reference
|
||||
|
||||
* `id` - The unique Server Certificate name
|
||||
* `name` - The name of the Server Certificate
|
||||
* `arn` - The Amazon Resource Name (ARN) specifying the server certificate.
|
||||
|
||||
|
||||
[1]: http://docs.aws.amazon.com/IAM/latest/UserGuide/Using_Identifiers.html
|
||||
[2]: http://docs.aws.amazon.com/IAM/latest/UserGuide/ManagingServerCerts.html
|
|
@ -89,12 +89,13 @@ The following arguments are supported:
|
|||
* `zone_id` - (Required) The ID of the hosted zone to contain this record.
|
||||
* `name` - (Required) The name of the record.
|
||||
* `type` - (Required) The record type.
|
||||
* `ttl` - (Required) The TTL of the record.
|
||||
* `records` - (Required) A string list of records.
|
||||
* `ttl` - (Required for non-alias records) The TTL of the record.
|
||||
* `records` - (Required for non-alias records) A string list of records.
|
||||
* `weight` - (Optional) The weight of weighted record (0-255).
|
||||
* `set_identifier` - (Optional) Unique identifier to differentiate weighted
|
||||
record from one another. Required for each weighted record.
|
||||
* `alias` - (Optional) An alias block. Alias record documented below.
|
||||
* `alias` - (Optional) An alias block. Conflicts with `ttl` & `records`.
|
||||
Alias record documented below.
|
||||
|
||||
Exactly one of `records` or `alias` must be specified: this determines whether it's an alias record.
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@ description: |-
|
|||
|
||||
# aws\_security\_group\_rule
|
||||
|
||||
Provides a security group rule resource. Represents a signle `ingress` or
|
||||
Provides a security group rule resource. Represents a single `ingress` or
|
||||
`egress` group rule, which can be added to external Security Groups.
|
||||
|
||||
~> **NOTE on Security Groups and Security Group Rules:** Terraform currently
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
---
|
||||
layout: "aws"
|
||||
page_title: "AWS: sns_topic"
|
||||
sidebar_current: "docs-aws-resource-sns-topic"
|
||||
description: |-
|
||||
Provides an SNS topic resource.
|
||||
---
|
||||
|
||||
# aws\_sns\_topic
|
||||
|
||||
Provides an SNS topic resource
|
||||
|
||||
## Example Usage
|
||||
|
||||
```
|
||||
resource "aws_sns_topic" "user_updates" {
|
||||
name = "user-updates-topic"
|
||||
}
|
||||
```
|
||||
|
||||
## Argument Reference
|
||||
|
||||
The following arguments are supported:
|
||||
|
||||
* `name` - (Required) The friendly name for the SNS topic
|
||||
* `policy` - (Optional) The fully-formed AWS policy as JSON
|
||||
* `delivery_policy` - (Optional) The SNS delivery policy
|
||||
|
||||
## Attributes Reference
|
||||
|
||||
The following attributes are exported:
|
||||
|
||||
* `id` - The ARN of the SNS topic
|
||||
* `arn` - The ARN of the SNS topic, as a more obvious property (clone of id)
|
||||
|
|
@ -0,0 +1,93 @@
|
|||
---
|
||||
layout: "aws"
|
||||
page_title: "AWS: sns_topic_subscription"
|
||||
sidebar_current: "docs-aws-resource-sns-topic-subscription"
|
||||
description: |-
|
||||
Provides a resource for subscribing to SNS topics.
|
||||
---
|
||||
|
||||
# aws\_sns\_topic\_subscription
|
||||
|
||||
Provides a resource for subscribing to SNS topics. Requires that an SNS topic exist for the subscription to attach to.
|
||||
This resource allows you to automatically place messages sent to SNS topics in SQS queues, send them as HTTP(S) POST requests
|
||||
to a given endpoint, send SMS messages, or notify devices / applications. The most likely use case for Terraform users will
|
||||
probably be SQS queues.
|
||||
|
||||
## Example Usage
|
||||
|
||||
You can directly supply a topic and ARN by hand in the `topic_arn` property along with the queue ARN:
|
||||
|
||||
```
|
||||
resource "aws_sns_topic_subscription" "user_updates_sqs_target" {
|
||||
topic_arn = "arn:aws:sns:us-west-2:432981146916:user-updates-topic"
|
||||
protocol = "sqs"
|
||||
endpoint = "arn:aws:sqs:us-west-2:432981146916:terraform-queue-too"
|
||||
}
|
||||
```
|
||||
|
||||
Alternatively you can use the ARN properties of a managed SNS topic and SQS queue:
|
||||
|
||||
```
|
||||
resource "aws_sns_topic" "user_updates" {
|
||||
name = "user-updates-topic"
|
||||
}
|
||||
|
||||
resource "aws_sqs_queue" "user_updates_queue" {
|
||||
name = "user-updates-queue"
|
||||
}
|
||||
|
||||
resource "aws_sns_topic_subscription" "user_updates_sqs_target" {
|
||||
topic_arn = "${aws_sns_topic.user_updates.arn}"
|
||||
protocol = "sqs"
|
||||
endpoint = "${aws_sqs_queue.user_updates_queue.arn}"
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
## Argument Reference
|
||||
|
||||
The following arguments are supported:
|
||||
|
||||
* `topic_arn` - (Required) The ARN of the SNS topic to subscribe to
|
||||
* `protocol` - (Required) The protocol to use. The possible values for this are: `sqs`, `http`, `https`, `sms`, or `application`. (`email` is an option but unsupported, see below)
|
||||
* `endpoint` - (Required) The endpoint to send data to, the contents will vary with the protocol. (see below for more information)
|
||||
* `raw_message_delivery` - (Optional) Boolean indicating whether or not to enable raw message delivery (the original message is directly passed, not wrapped in JSON with the original message in the message property).
|
||||
|
||||
### Protocols supported
|
||||
|
||||
Supported SNS protocols include:
|
||||
|
||||
* `http` -- delivery of JSON-encoded message via HTTP POST
|
||||
* `https` -- delivery of JSON-encoded message via HTTPS POST
|
||||
* `sms` -- delivery of message via SMS
|
||||
* `sqs` -- delivery of JSON-encoded message to an Amazon SQS queue
|
||||
* `application` -- delivery of JSON-encoded message to an EndpointArn for a mobile app and device
|
||||
|
||||
Unsupported protocols include the following:
|
||||
|
||||
* `email` -- delivery of message via SMTP
|
||||
* `email-json` -- delivery of JSON-encoded message via SMTP
|
||||
|
||||
These are unsupported because the email address needs to be authorized and does not generate an ARN until the target email address has been validated. This breaks
|
||||
the Terraform model and as a result are not currently supported.
|
||||
|
||||
### Specifying endpoints
|
||||
|
||||
Endpoints have different format requirements according to the protocol that is chosen.
|
||||
|
||||
* HTTP/HTTPS endpoints will require a URL to POST data to
|
||||
* SMS endpoints are mobile numbers that are capable of receiving an SMS
|
||||
* SQS endpoints come in the form of the SQS queue's ARN (not the URL of the queue) e.g: `arn:aws:sqs:us-west-2:432981146916:terraform-queue-too`
|
||||
* Application endpoints are also the endpoint ARN for the mobile app and device.
|
||||
|
||||
|
||||
## Attributes Reference
|
||||
|
||||
The following attributes are exported:
|
||||
|
||||
* `id` - The ARN of the subscription
|
||||
* `topic_arn` - The ARN of the topic the subscription belongs to
|
||||
* `protocol` - The protocol being used
|
||||
* `endpoint` - The full endpoint to send data to (SQS ARN, HTTP(S) URL, Application ARN, SMS number, etc.)
|
||||
* `arn` - The ARN of the subscription stored as a more user-friendly property
|
||||
|
|
@ -11,7 +11,7 @@ description: |-
|
|||
## Example Usage
|
||||
|
||||
```
|
||||
resource "aws_sqs_queue" "terrform_queue" {
|
||||
resource "aws_sqs_queue" "terraform_queue" {
|
||||
name = "terraform-example-queue"
|
||||
delay_seconds = 90
|
||||
max_message_size = 2048
|
||||
|
@ -35,4 +35,5 @@ The following arguments are supported:
|
|||
|
||||
The following attributes are exported:
|
||||
|
||||
* `id` - The URL for the created Amazon SQS queue.
|
||||
* `id` - The URL for the created Amazon SQS queue.
|
||||
* `arn` - The ARN of the SQS queue
|
|
@ -41,3 +41,6 @@ The following attributes are exported:
|
|||
* `vars` - See Argument Reference above.
|
||||
* `rendered` - The final rendered template.
|
||||
|
||||
## Template files syntax
|
||||
|
||||
The syntax of the template files is [documented here](/docs/configuration/interpolation.html), under the "Templates" section.
|
||||
|
|
|
@ -53,7 +53,7 @@ resource "terraform_remote_state" "vpc" {
|
|||
|
||||
resource "aws_instance" "foo" {
|
||||
# ...
|
||||
subnet_id = "${terraform_state.vpc.output.subnet_id}"
|
||||
subnet_id = "${terraform_remote_state.vpc.output.subnet_id}"
|
||||
}
|
||||
```
|
||||
|
||||
|
|
|
@ -89,6 +89,10 @@
|
|||
<a href="/docs/providers/aws/r/iam_role_policy.html">aws_iam_role_policy</a>
|
||||
</li>
|
||||
|
||||
<li<%= sidebar_current("docs-aws-resource-iam-server-certificate") %>>
|
||||
<a href="/docs/providers/aws/r/iam_server_certificate.html">aws_iam_server_certificate</a>
|
||||
</li>
|
||||
|
||||
<li<%= sidebar_current("docs-aws-resource-iam-user") %>>
|
||||
<a href="/docs/providers/aws/r/iam_user.html">aws_iam_user</a>
|
||||
</li>
|
||||
|
@ -152,6 +156,14 @@
|
|||
<a href="/docs/providers/aws/r/s3_bucket.html">aws_s3_bucket</a>
|
||||
</li>
|
||||
|
||||
<li<%= sidebar_current("docs-aws-resource-sns-topic") %>>
|
||||
<a href="/docs/providers/aws/r/sns_topic.html">aws_sns_topic</a>
|
||||
</li>
|
||||
|
||||
<li<%= sidebar_current("docs-aws-resource-sns-topic-subscription") %>>
|
||||
<a href="/docs/providers/aws/r/sns_topic_subscription.html">aws_sns_topic_subscription</a>
|
||||
</li>
|
||||
|
||||
<li<%= sidebar_current("docs-aws-resource-security-group") %>>
|
||||
<a href="/docs/providers/aws/r/security_group.html">aws_security_group</a>
|
||||
</li>
|
||||
|
|
Loading…
Reference in New Issue