Skip to content

Commit

Permalink
Merge pull request #35234 from acwwat/b-aws_iot_ca_certificate-fix_ro…
Browse files Browse the repository at this point in the history
…le_arn_data_type

fix: Set `role_arn` data type to String in `aws_iot_ca_certificate`
  • Loading branch information
ewbankkit authored Jan 12, 2024
2 parents a8fa674 + 0cd1074 commit e8ee3c9
Show file tree
Hide file tree
Showing 3 changed files with 191 additions and 4 deletions.
3 changes: 3 additions & 0 deletions .changelog/35234.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:bug
resource/aws_iot_ca_certificate: Change `registration_config.role_arn` from `TypeBool` to `TypeString`, fixing `Inappropriate value for attribute "role_arn": a bool is required` errors
```
16 changes: 12 additions & 4 deletions internal/service/iot/ca_certificate.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ func ResourceCACertificate() *schema.Resource {
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"role_arn": {
Type: schema.TypeBool,
Type: schema.TypeString,
Optional: true,
ValidateFunc: verify.ValidARN,
},
Expand Down Expand Up @@ -159,13 +159,17 @@ func resourceCACertificateCreate(ctx context.Context, d *schema.ResourceData, me
input.VerificationCertificate = aws.String(v.(string))
}

output, err := conn.RegisterCACertificateWithContext(ctx, input)
outputRaw, err := tfresource.RetryWhenAWSErrMessageContains(ctx, propagationTimeout,
func() (interface{}, error) {
return conn.RegisterCACertificateWithContext(ctx, input)
},
iot.ErrCodeInvalidRequestException, "included in the RegistrationConfig does not exist or cannot be assumed by AWS IoT")

if err != nil {
return sdkdiag.AppendErrorf(diags, "registering IoT CA Certificate: %s", err)
}

d.SetId(aws.StringValue(output.CertificateId))
d.SetId(aws.StringValue(outputRaw.(*iot.RegisterCACertificateOutput).CertificateId))

return append(diags, resourceCACertificateRead(ctx, d, meta)...)
}
Expand Down Expand Up @@ -239,7 +243,11 @@ func resourceCACertificateUpdate(ctx context.Context, d *schema.ResourceData, me
}
}

_, err := conn.UpdateCACertificateWithContext(ctx, input)
_, err := tfresource.RetryWhenAWSErrMessageContains(ctx, propagationTimeout,
func() (interface{}, error) {
return conn.UpdateCACertificateWithContext(ctx, input)
},
iot.ErrCodeInvalidRequestException, "included in the RegistrationConfig does not exist or cannot be assumed by AWS IoT")

if err != nil {
return sdkdiag.AppendErrorf(diags, "updating IoT CA Certificate (%s): %s", d.Id(), err)
Expand Down
176 changes: 176 additions & 0 deletions internal/service/iot/ca_certificate_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,36 @@ func TestAccIoTCACertificate_defaultMode(t *testing.T) {
})
}

func TestAccIoTCACertificate_registrationConfig(t *testing.T) {
ctx := acctest.Context(t)
resourceName := "aws_iot_ca_certificate.test"
testExternalProviders := map[string]resource.ExternalProvider{
"tls": {
Source: "hashicorp/tls",
VersionConstraint: "4.0.4",
},
}

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { acctest.PreCheck(ctx, t) },
ErrorCheck: acctest.ErrorCheck(t, iot.EndpointsID),
ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories,
ExternalProviders: testExternalProviders,
CheckDestroy: testAccCheckCACertificateDestroy(ctx),
Steps: []resource.TestStep{
{
Config: testAccCACertificateConfig_registrationConfig(),
Check: resource.ComposeTestCheckFunc(
testAccCheckCACertificateExists(ctx, resourceName),
resource.TestCheckResourceAttr(resourceName, "registration_config.#", "1"),
resource.TestCheckResourceAttrSet(resourceName, "registration_config.0.role_arn"),
resource.TestCheckResourceAttrSet(resourceName, "registration_config.0.template_body"),
),
},
},
})
}

func testAccCheckCACertificateExists(ctx context.Context, n string) resource.TestCheckFunc {
return func(s *terraform.State) error {
rs, ok := s.RootModule().Resources[n]
Expand Down Expand Up @@ -301,3 +331,149 @@ resource "aws_iot_ca_certificate" "test" {
data "aws_iot_registration_code" "test" {}
`, active, allowAutoRegistration)
}

func testAccCACertificateConfig_registrationConfig_iamRole() string {
return `
resource "aws_iam_role" "test" {
name = "test_iot_role"
assume_role_policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Effect = "Allow"
Principal = {
Service = "iot.amazonaws.com"
}
Action = "sts:AssumeRole"
}
]
})
}
`
}

func testAccCACertificateConfig_registrationConfig() string {
return acctest.ConfigCompose(testAccCACertificateConfig_registrationConfig_iamRole(), `
data "aws_caller_identity" "current" {}
data "aws_partition" "current" {}
data "aws_region" "current" {}
resource "tls_self_signed_cert" "ca" {
private_key_pem = tls_private_key.ca.private_key_pem
subject {
common_name = "example.com"
organization = "ACME Examples, Inc"
}
validity_period_hours = 12
allowed_uses = [
"key_encipherment",
"digital_signature",
"server_auth",
]
is_ca_certificate = true
}
resource "tls_private_key" "ca" {
algorithm = "RSA"
}
resource "tls_cert_request" "verification" {
private_key_pem = tls_private_key.verification.private_key_pem
subject {
common_name = data.aws_iot_registration_code.test.registration_code
}
}
resource "tls_private_key" "verification" {
algorithm = "RSA"
}
resource "tls_locally_signed_cert" "verification" {
cert_request_pem = tls_cert_request.verification.cert_request_pem
ca_private_key_pem = tls_private_key.ca.private_key_pem
ca_cert_pem = tls_self_signed_cert.ca.cert_pem
validity_period_hours = 12
allowed_uses = [
"key_encipherment",
"digital_signature",
"server_auth",
]
}
resource "aws_iot_ca_certificate" "test" {
active = true
allow_auto_registration = true
ca_certificate_pem = tls_self_signed_cert.ca.cert_pem
certificate_mode = "DEFAULT"
verification_certificate_pem = tls_locally_signed_cert.verification.cert_pem
registration_config {
role_arn = aws_iam_role.test.arn
template_body = <<EOF
{
"Parameters": {
"AWS::IoT::Certificate::CommonName": {
"Type": "String"
},
"AWS::IoT::Certificate::SerialNumber": {
"Type": "String"
},
"AWS::IoT::Certificate::Country": {
"Type": "String"
},
"AWS::IoT::Certificate::Id": {
"Type": "String"
}
},
"Resources": {
"thing": {
"Type":"AWS::IoT::Thing",
"Properties": {
"ThingName": {
"Ref": "AWS::IoT::Certificate::CommonName"
},
"AttributePayload": {
"version":"v1",
"serialNumber": {
"Ref": "AWS::IoT::Certificate::SerialNumber"
}
},
"ThingTypeName": "lightBulb-versionA",
"ThingGroups": [
"v1-lightbulbs",
{
"Ref": "AWS::IoT::Certificate::Country"
}
]
},
"OverrideSettings": {
"AttributePayload": "MERGE",
"ThingTypeName": "REPLACE",
"ThingGroups": "DO_NOTHING"
}
},
"certificate": {
"Type": "AWS::IoT::Certificate",
"Properties": {
"CertificateId": {
"Ref": "AWS::IoT::Certificate::Id"
},
"Status": "ACTIVE"
}
},
"policy": {
"Type": "AWS::IoT::Policy",
"Properties": {
"PolicyDocument":"{ \"Version\": \"2012-10-17\", \"Statement\": [{ \"Effect\": \"Allow\", \"Action\":[\"iot:Publish\"], \"Resource\": [\"arn:${data.aws_partition.current.partition}:iot:${data.aws_region.current.name}:${data.aws_caller_identity.current.account_id}:topic/foo/bar\"] }] }"
}
}
}
}
EOF
}
}
data "aws_iot_registration_code" "test" {}
`)
}

0 comments on commit e8ee3c9

Please sign in to comment.