Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

provider/aws: Add support for AWS IoT #6961

Closed
wants to merge 52 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
52 commits
Select commit Hold shift + click to select a range
4ddaaf7
Fix deps conflict
jhedev Jun 1, 2016
6921142
Add basic support for AWS IoT things
jhedev May 16, 2016
94616fd
Add schemas for the remaining IoT resources
jhedev May 17, 2016
b7e0608
Get principals support working
jhedev May 28, 2016
d49b60b
Implement IoT certificate functionality
jhedev May 28, 2016
9bcc40e
Implement IoT policy functionality
jhedev May 28, 2016
e6ace1e
Make IoT policy implementation compile
jhedev May 28, 2016
fbab587
Add some implementation for IoT policy attachment
jhedev May 28, 2016
29bb099
Correct schema description of IoT topic rule
jhedev May 28, 2016
5320b3b
Add tests for AWS IoT thing
jhedev May 28, 2016
30bd454
Do not store pem of cert
jhedev May 28, 2016
5aec619
Force recreation of cert if CSR has changed
jhedev May 28, 2016
2315b7d
Fixes for IoT certificate
jhedev May 30, 2016
b468cc7
Add sql version to schema of IoT topic rule
jhedev May 30, 2016
178e233
Add tests for aws iot certificate
jhedev May 30, 2016
902637a
More tests for aws iot thing
jhedev May 30, 2016
4286d08
Add aws iot policy test
jhedev May 30, 2016
1ffa2c4
Some fixes for iot policy attachment
jhedev May 30, 2016
c785050
Implement functionality for IoT topic rule
jhedev May 30, 2016
b6cd40b
Add IoT topic rule tests
jhedev May 30, 2016
8bb3a78
Start documenting AWS IoT resources
jhedev Jun 25, 2016
10932d5
Add some new TODOs
jhedev Jun 25, 2016
cfcd9c6
Get basic policy attachment test working
jhedev Jun 25, 2016
6d56073
Add csr.pem
jhedev Jun 27, 2016
53ef1c2
Get update of attached principals for IoT thing working
jhedev Jun 28, 2016
08450f4
Fix csr.pem path
jhedev Jun 28, 2016
ecdbef5
Add ARN as computed attribute to IoT thing
jhedev Jun 28, 2016
68c82df
Document attributes of IoT policies
jhedev Jun 28, 2016
d56f682
Correct returns
jhedev Jun 28, 2016
44a2462
Fix compilation
jhedev Jun 28, 2016
38c9238
Implement update function
jhedev Jun 28, 2016
c39b418
Fix merge
jhedev Jun 28, 2016
5386afe
Remove godeps directory
jhedev Jun 28, 2016
7c0e43d
Some improvements for IoT topic rule
jhedev Jun 28, 2016
828e41b
vendor: Add AWS IoT dependency
jhedev Jun 28, 2016
1515e9b
Update documentation for topic rule
jhedev Jun 28, 2016
50a1ea9
Use AWS SDK 1.4.2
Aug 23, 2016
01e3d0e
Can't cast *schema.Set to []string
Aug 23, 2016
01e549c
Fix path to csr.pem in IoT thing test
Aug 23, 2016
85df881
AWS does not want spaces in attribute
Aug 23, 2016
0e44158
Check all errors
jhedev Oct 7, 2016
f117dd6
Update interface of resource_aws_iot_policy_attachment
jhedev Oct 7, 2016
6ba2968
Update documentation to mirror new interface of aws_iot_policy_attach…
jhedev Oct 7, 2016
9033080
bring IoT dependency up to v1.5.13
Dec 5, 2016
c9ce4f0
Minor corrections for the iot certificate resource
jhedev Feb 25, 2017
591dc27
Minor corrections for the iot policy resource
jhedev Feb 25, 2017
ccb178a
Always force new if there is change to a policy attachment
jhedev Feb 25, 2017
a4bc7c2
Minor changes to the read funtion of the iot thing resource
jhedev Feb 25, 2017
10f9ac9
Minor fix
jhedev Feb 25, 2017
3e45a2c
Fix principal and policy order in IoT policy attachment
jhedev Apr 24, 2017
0aab8e3
Fix dynamodb implementation
jhedev Apr 24, 2017
370027f
Update AWS IoT dep
jhedev Apr 24, 2017
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 42 additions & 0 deletions builtin/providers/aws/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ import (
"github.com/aws/aws-sdk-go/service/glacier"
"github.com/aws/aws-sdk-go/service/iam"
"github.com/aws/aws-sdk-go/service/inspector"
"github.com/aws/aws-sdk-go/service/iot"
"github.com/aws/aws-sdk-go/service/kinesis"
"github.com/aws/aws-sdk-go/service/kms"
"github.com/aws/aws-sdk-go/service/lambda"
Expand Down Expand Up @@ -161,6 +162,7 @@ type AWSClient struct {
sfnconn *sfn.SFN
ssmconn *ssm.SSM
wafconn *waf.WAF
iotconn *iot.IoT
}

func (c *AWSClient) S3() *s3.S3 {
Expand Down Expand Up @@ -274,6 +276,46 @@ func (c *Config) Client() (interface{}, error) {
client.partition = partition
client.accountid = accountId
}

client.apigateway = apigateway.New(sess)
client.appautoscalingconn = applicationautoscaling.New(sess)
client.autoscalingconn = autoscaling.New(sess)
client.cfconn = cloudformation.New(sess)
client.cloudfrontconn = cloudfront.New(sess)
client.cloudtrailconn = cloudtrail.New(sess)
client.cloudwatchconn = cloudwatch.New(sess)
client.cloudwatcheventsconn = cloudwatchevents.New(sess)
client.cloudwatchlogsconn = cloudwatchlogs.New(sess)
client.codecommitconn = codecommit.New(usEast1Sess)
client.codedeployconn = codedeploy.New(sess)
client.dsconn = directoryservice.New(sess)
client.dynamodbconn = dynamodb.New(dynamoSess)
client.ec2conn = ec2.New(awsEc2Sess)
client.ecrconn = ecr.New(sess)
client.ecsconn = ecs.New(sess)
client.efsconn = efs.New(sess)
client.elasticacheconn = elasticache.New(sess)
client.elasticbeanstalkconn = elasticbeanstalk.New(sess)
client.elastictranscoderconn = elastictranscoder.New(sess)
client.elbconn = elb.New(awsElbSess)
client.elbv2conn = elbv2.New(awsElbSess)
client.emrconn = emr.New(sess)
client.esconn = elasticsearch.New(sess)
client.firehoseconn = firehose.New(sess)
client.glacierconn = glacier.New(sess)
client.iotconn = iot.New(sess)
client.kinesisconn = kinesis.New(kinesisSess)
client.kmsconn = kms.New(sess)
client.lambdaconn = lambda.New(sess)
client.opsworksconn = opsworks.New(usEast1Sess)
client.r53conn = route53.New(usEast1Sess)
client.rdsconn = rds.New(sess)
client.redshiftconn = redshift.New(sess)
client.simpledbconn = simpledb.New(sess)
client.s3conn = s3.New(awsS3Sess)
client.sesConn = ses.New(sess)
client.snsconn = sns.New(sess)
client.sqsconn = sqs.New(sess)
}

authErr := c.ValidateAccountId(client.accountid)
Expand Down
5 changes: 5 additions & 0 deletions builtin/providers/aws/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -341,6 +341,11 @@ func Provider() terraform.ResourceProvider {
"aws_inspector_resource_group": resourceAWSInspectorResourceGroup(),
"aws_instance": resourceAwsInstance(),
"aws_internet_gateway": resourceAwsInternetGateway(),
"aws_iot_thing": resourceAwsIotThing(),
"aws_iot_certificate": resourceAwsIotCertificate(),
"aws_iot_policy": resourceAwsIotPolicy(),
"aws_iot_policy_attachment": resourceAwsIotPolicyAttachment(),
"aws_iot_topic_rule": resourceAwsIotTopicRule(),
"aws_key_pair": resourceAwsKeyPair(),
"aws_kinesis_firehose_delivery_stream": resourceAwsKinesisFirehoseDeliveryStream(),
"aws_kinesis_stream": resourceAwsKinesisStream(),
Expand Down
146 changes: 146 additions & 0 deletions builtin/providers/aws/resource_aws_iot_certificate.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
package aws

import (
"log"

"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/iot"
"github.com/hashicorp/terraform/helper/schema"
)

func resourceAwsIotCertificate() *schema.Resource {
return &schema.Resource{
Create: resourceAwsIotCertificateCreate,
Read: resourceAwsIotCertificateRead,
Update: resourceAwsIotCertificateUpdate,
Delete: resourceAwsIotCertificateDelete,
Schema: map[string]*schema.Schema{
"csr": &schema.Schema{
Type: schema.TypeString,
Required: true,
},
"active": &schema.Schema{
Type: schema.TypeBool,
Required: true,
},
"arn": &schema.Schema{
Type: schema.TypeString,
Computed: true,
},
},
}
}

func resourceAwsIotCertificateCreate(d *schema.ResourceData, meta interface{}) error {
conn := meta.(*AWSClient).iotconn

log.Printf("[DEBUG] Creating certificate from csr")
out, err := conn.CreateCertificateFromCsr(&iot.CreateCertificateFromCsrInput{
CertificateSigningRequest: aws.String(d.Get("csr").(string)),
SetAsActive: aws.Bool(d.Get("active").(bool)),
})

if err != nil {
log.Printf("[ERROR] %s", err)
return err
}
log.Printf("[DEBUG] Created certificate from csr")

d.SetId(*out.CertificateId)

return resourceAwsIotCertificateRead(d, meta)
}

func resourceAwsIotCertificateRead(d *schema.ResourceData, meta interface{}) error {

conn := meta.(*AWSClient).iotconn

out, err := conn.DescribeCertificate(&iot.DescribeCertificateInput{
CertificateId: aws.String(d.Id()),
})

if err != nil {
log.Printf("[ERROR] %s", err)
return err
}

d.Set("arn", out.CertificateDescription.CertificateArn)

return nil
}

func resourceAwsIotCertificateUpdate(d *schema.ResourceData, meta interface{}) error {
conn := meta.(*AWSClient).iotconn

if d.HasChange("csr") {
// First create certificate with new CSR
out, err := conn.CreateCertificateFromCsr(&iot.CreateCertificateFromCsrInput{
CertificateSigningRequest: aws.String(d.Get("csr").(string)),
SetAsActive: aws.Bool(d.Get("active").(bool)),
})

if err != nil {
log.Printf("[ERROR] %s", err)
return nil
}

// If everything worked, make the old one inactive
_, err = conn.UpdateCertificate(&iot.UpdateCertificateInput{
CertificateId: aws.String(d.Id()),
NewStatus: aws.String("INACTIVE"),
})

if err != nil {
log.Printf("[ERROR] %s", err)
return err
}

d.SetId(*out.CertificateId)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't need to set these here


} else {

if d.HasChange("active") {
status := "INACTIVE"
if d.Get("active").(bool) {
status = "ACTIVE"
}

_, err := conn.UpdateCertificate(&iot.UpdateCertificateInput{
CertificateId: aws.String(d.Id()),
NewStatus: aws.String(status),
})

if err != nil {
return err
}
}
}

return resourceAwsIotCertificateRead(d, meta)
}

func resourceAwsIotCertificateDelete(d *schema.ResourceData, meta interface{}) error {

conn := meta.(*AWSClient).iotconn

_, err := conn.UpdateCertificate(&iot.UpdateCertificateInput{
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this action take a period of time? If we try and do this and AWS is performing an action, then the Delete may fail

CertificateId: aws.String(d.Id()),
NewStatus: aws.String("INACTIVE"),
})

if err != nil {
log.Printf("[ERROR], %s", err)
return err
}

_, err = conn.DeleteCertificate(&iot.DeleteCertificateInput{
CertificateId: aws.String(d.Id()),
})

if err != nil {
log.Printf("[ERROR] %s", err)
return err
}

return nil
}
69 changes: 69 additions & 0 deletions builtin/providers/aws/resource_aws_iot_certificate_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
package aws

import (
"fmt"
"testing"

"github.com/aws/aws-sdk-go/service/iot"
"github.com/hashicorp/terraform/helper/resource"
"github.com/hashicorp/terraform/terraform"
)

func TestAccAWSIoTCertificate_basic(t *testing.T) {
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckAWSIoTCertificateDestroy_basic,
Steps: []resource.TestStep{
resource.TestStep{
Config: testAccAWSIoTCertificate_basic,
Check: resource.ComposeTestCheckFunc(
testAccCheckAWSIoTCertificateExists_basic("aws_iot_certificate.foo_cert"),
),
},
},
})
}

func testAccCheckAWSIoTCertificateDestroy_basic(s *terraform.State) error {
conn := testAccProvider.Meta().(*AWSClient).iotconn

for _, rs := range s.RootModule().Resources {
if rs.Type != "aws_iot_certificate" {
continue
}

out, err := conn.ListCertificates(&iot.ListCertificatesInput{})

if err != nil {
return err
}

for _, t := range out.Certificates {
if *t.CertificateId == rs.Primary.ID {
return fmt.Errorf("IoT certificate still exists:\n%s", t)
}
}

}

return nil
}

func testAccCheckAWSIoTCertificateExists_basic(name string) resource.TestCheckFunc {
return func(s *terraform.State) error {
_, ok := s.RootModule().Resources[name]
if !ok {
return fmt.Errorf("Not found: %s", name)
}

return nil
}
}

var testAccAWSIoTCertificate_basic = `
resource "aws_iot_certificate" "foo_cert" {
csr = "${file("test-fixtures/csr.pem")}"
active = true
}
`
Loading