aws / aws-cdk

The AWS Cloud Development Kit is a framework for defining cloud infrastructure in code
https://aws.amazon.com/cdk
Apache License 2.0
11.7k stars 3.93k forks source link

How to create IOT thing with certificate and policy. #19303

Closed matart15 closed 2 years ago

matart15 commented 2 years ago

General Issue

https://ap-northeast-1.console.aws.amazon.com/iot/home?region=ap-northeast-1#/connectdevice/

The Question

When I start AWS: IOT, Get start page creates simple IoT thing, certificate, policy.

I want to create the same thing with CDK.

How to do that. I googled and looks like there is not much info.

As my understanding

  1. To create IotThing

    const iotCoreThing = new iot.CfnThing(this, 'iotCoreThing', {
      thingName: 'iotCoreThing-iot-thing',
    });
  2. create certificate

    const iotCoreThingCertificate = new iot.CfnCertificate(
      this,
      'IotCoreThingCertificate',
      {
        status: 'ACTIVE',
        certificateSigningRequest:
          'arn:aws:acm-pca:::template/RootCACertificate/V1',
        // caCertificatePem: fs
        //   .readFileSync(`${__dirname}/../iot_certs/root-CA.crt`) // <---- this is th file I got from get started page.  i thought I can reuse it
        //   .toString(),
        // certificatePem: fs
        //   .readFileSync(`${__dirname}/../iot_certs/raspi.cert.pem`) // <---- this is th file I got from get started page.  i thought I can reuse it
        //   .toString(),
      },
    );
  3. create policy

    const iotPolicy = new iot.CfnPolicy(this, 'Policy', {
      policyName: 'Raspberry_Pi_Policy',
      policyDocument: {
        Version: '2012-10-17',
        Statement: [
          {
            Effect: 'Allow',
            Action: ['iot:*'],
            Resource: ['*'],
          },
        ],
      },
    });
  4. connect thing and certificate

    
    const policyPrincipalAttachment = new iot.CfnPolicyPrincipalAttachment(
      this,
      'PolicyPrincipalAttachment',
      {
        policyName: iotPolicy.policyName || 'PolicyPrincipalAttachment',
        principal: iotCoreThingCertificate.attrArn,
      },
    );
  5. connect policy and certificate

    
    const thingPrincipalAttachment = new iot.CfnThingPrincipalAttachment(
      this,
      'ThingPrincipalAttachment',
      {
        thingName: iotThing.thingName || 'ThingPrincipalAttachment',
        principal: iotCoreThingCertificate.attrArn,
      },
    );

on 2. create certificate i get this error : Invalid request provided: CSR violates constraints

If I use commented code ( caCertificatePem + certificatePem ) : Invalid request provided: No CA certificate exists for the given certificate

this is created YAML

```yaml IotCoreThingCertificate: Type: AWS::IoT::Certificate Properties: Status: ACTIVE CACertificatePem: | -----BEGIN CERTIFICATE----- MIIDQTCCAimgAwIBAgITBmyfz5m/jAo54vB4ikPmljZbyjANBgkqhkiG9w0BAQsF ADA5MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6 b24gUm9vdCBDQSAxMB4XDTE1MDUyNjAwMDAwMFoXDTM4MDExNzAwMDAwMFowOTEL MAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJv b3QgQ0EgMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALJ4gHHKeNXj ca9HgFB0fW7Y14h29Jlo91ghYPl0hAEvrAIthtOgQ3pOsqTQNroBvo3bSMgHFzZM 9O6II8c+6zf1tRn4SWiw3te5djgdYZ6k/oI2peVKVuRF4fn9tBb6dNqcmzU5L/qw IFAGbHrQgLKm+a/sRxmPUDgH3KKHOVj4utWp+UhnMJbulHheb4mjUcAwhmahRWa6 VOujw5H5SNz/0egwLX0tdHA114gk957EWW67c4cX8jJGKLhD+rcdqsq08p8kDi1L 93FcXmn/6pUCyziKrlA4b9v7LWIbxcceVOF34GfID5yHI9Y/QCB/IIDEgEw+OyQm jgSubJrIqg0CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC AYYwHQYDVR0OBBYEFIQYzIU07LwMlJQuCFmcx7IQTgoIMA0GCSqGSIb3DQEBCwUA A4IBAQCY8jdaQZChGsV2USggNiMOruYou6r4lK5IpDB/G/wkjUu0yKGX9rbxenDI U5PMCCjjmCXPI6T53iHTfIUJrU6adTrCC2qJeHZERxhlbI1Bjjt/msv0tadQ1wUs N+gDS63pYaACbvXy8MWy7Vu33PqUXHeeE6V/Uq2V8viTO96LXFvKWlJbYK8U90vv o/ufQJVtMVT8QtPHRh8jrdkPSHCa2XV4cdFyQzR1bldZwgJcJmApzyMZFo6IQ6XU 5MsI+yMRQ+hDKXJioaldXgjUkK642M4UwtBV8ob2xJNDd2ZhwLnoQdeXeGADbkpy rqXRfboQnoZsG4q5WTP468SQvvG5 -----END CERTIFICATE----- CertificatePem: | -----BEGIN CERTIFICATE----- MIIDWTCCAkGgAwIBAgIUPHbm7WxXRz1i5hOxA5I+jZnf1y8wDQYJKoZIhvcNAQEL BQAwTTFLMEkGA1UECwxCQW1hem9uIFdlYiBTZXJ2aWNlcyBPPUFtYXpvbi5jb20g SW5jLiBMPVNlYXR0bGUgU1Q9V2FzaGluZ3RvbiBDPVVTMB4XDTIyMDIxMTA1MTgy MFoXDTQ5MTIzMTIzNTk1OVowHjEcMBoGA1UEAwwTQVdTIElvVCBDZXJ0aWZpY2F0 ZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL3i7LgVzGYWidqwJdmq nt5eTc3msYTzGZDeQ1NSbC1L/Yfj1EmYQaogIMDoVbUmfba26Ym+FM6bPMnC56oj LmBabgOv+ut1fv0cXQTsD5qltIk67vV7rds71w2zrYmsPrJ2Xo1QPADvVsSeUsUO +2ada7VlWQuE8KWlf8kKOETk5sL9oMBp0OnEs1cHHr5cSLaFkB8iTOG/Cpheh652 zM2j5ozl90wjOoBbPJLcOL+o6LGFUHXNExSERgcD1ilxOROHYIqTli3zLdeMk8qs JgyWCFqK1sHQnZCLaaaGgHdmGNod2xYRaQXUy+VZxvXLjt2+/HawGA1S0CwUFG3l JEkCAwEAAaNgMF4wHwYDVR0jBBgwFoAUHrOxsJYLwaXCqpXGbS6PuPXEL9wwHQYD VR0OBBYEFDMW6pe8bDCVKe1iWWbvtoa9T2BMMAwGA1UdEwEB/wQCMAAwDgYDVR0P AQH/BAQDAgeAMA0GCSqGSIb3DQEBCwUAA4IBAQBTUglnvw6y7hfQuvK5zmNX9hgd TXqklTEQyw6S8vLwjX8vkeGmFlQosbJD2jwRa8pqckICMrITEygVju+3u2Js9vdc zR4R/tt7AKrRo5m37UkM5wtUHie9a+zhHsum9680fwVoxE5qymeYkLvF5u3HO7N4 vyN09APU8ea6YHPIZ5mUGfr9mJjaGtko7pydIwg0m8dYETMoqqda8xRhXu4Nhvk3 OetElbXTbV/MNz6OL7uxKFBGZqgabpWZOUljSSqm/GR1xNIHMvAxaLegvbV1543c 8Y8cBsJVvfCZgHNKP3z4Xfo1ctYPzKdoyWex71pzD9f2CFydArK6p6oNWrMN -----END CERTIFICATE----- Metadata: aws:cdk:path: myproject-dev-main/IotCoreThingCertificate iotCoreThing: Type: AWS::IoT::Thing Properties: ThingName: myproject-iot-thing Metadata: aws:cdk:path: myproject-dev-main/iotCoreThing Policy: Type: AWS::IoT::Policy Properties: PolicyDocument: Version: "2012-10-17" Statement: - Effect: Allow Action: - iot:* Resource: - "*" PolicyName: Raspberry_Pi_Policy DependsOn: - iotCoreThing Metadata: aws:cdk:path: myproject-dev-main/Policy PolicyPrincipalAttachment: Type: AWS::IoT::PolicyPrincipalAttachment Properties: PolicyName: Raspberry_Pi_Policy Principal: Fn::GetAtt: - IotCoreThingCertificate - Arn DependsOn: - Policy Metadata: aws:cdk:path: myproject-dev-main/PolicyPrincipalAttachment ```

Question :

  1. How to create IOTThing + Certificate + IOTPolicy. Is there any example or documentation?. current docs only says The certificate signing request (CSR).
  2. What is the input string of CertificateSigningRequest?.
  3. What Am I doing wrong?.

CDK CLI Version

2.15.0 (build 151055e)

Framework Version

No response

Node.js Version

v14.18.3

OS

mac

skinny85 commented 2 years ago

Thanks for opening the issue @matart15!

@yamatatsu any ideas? You know more about IoT than I do 🙂.

skinny85 commented 2 years ago

What's certificateSigningRequest: 'arn:aws:acm-pca:::template/RootCACertificate/V1'? Is that some Amazon-owned Certificate Authority?

brucegl commented 2 years ago

Hi all, I'm working on exactly the same thing right now. This is how I build my CSR value:

certificateSigningRequest: path.join( __dirname, "../../iot-certs/iot.com.csr"),

However, the violation can be more simply repeated, thus:

$ openssl genrsa -out key_name.key 4096
$ openssl req -out CSR.csr -key key_name.key -new -sha256
$ aws iot create-certificate-from-csr --certificate-signing-request=file:/CSR.csr

I have no issue when using the AWS GUI console. The CSR is accepted and a certificate is created.

Thanks

UPDATE: I missed a forward slash after file:/ This works now

$ aws iot create-certificate-from-csr --certificate-signing-request=file://CSR.csr

matart15 commented 2 years ago

@skinny85

What's certificateSigningRequest: 'arn:aws:acm-pca:::template/RootCACertificate/V1'? Is that some Amazon-owned Certificate Authority?

No. I just did not know what value to input. I think I saw that on someone's cloud formation template

matart15 commented 2 years ago

@brucegl

Thank you. I tried GUI : there is two options to create certificate.

Screen Shot 2022-03-10 at 10 27 18

  1. Auto-generate. which gives me five file Screen Shot 2022-03-10 at 10 29 42

  2. use CSR. used CSR.csr file output of your command. which gave me three files.

AmazonRootCA1.pem
AmazonRootCA3.pem
ddade268d08460c28dec5bb57cf29f2a21cf7203ffc28c4b1c5acc69b623195d.pem.crt

Problem

Now I don't know which file to use for which key

new iot.CfnCertificate(
      this,
      'IotCoreThingCertificate',
      {
        status: 'ACTIVE',
        // certificateSigningRequest: path.join(__dirname, '../iot-certs/CSR.csr'),
        caCertificatePem: path.join( __dirname, '/../iot_certs/AmazonRootCA1.pem'),  // <----- which pem or crt file to use
        certificatePem: path.join(__dirname, '/../iot_certs/AmazonRootCA3.pem'),        // <----- which pem or crt file to use
      },
    );

I tried all possible combinations. they resulted Invalid request provided: The certificate is not valid.

yamatatsu commented 2 years ago

@matart15 @brucegl certificateSigningRequest, caCertificatePem and certificatePem can take the content of file(key, cert ot csr) instead of path of file. So using fs.readFileSync() is needed.

First, create csr:

mkdir cert
cd cert
openssl genrsa -out privatekey.pem 2048
openssl req -new -subj "/C=JP/ST=Tokyo/L=Chiyodaku/O=MyCompany/CN=AWS IoT Certificate" -key privatekey.pem -out cert.csr

Then you can use the cert with fs.readFileSync():

const iotCoreThingCertificate = new iot.CfnCertificate(
  this,
  "IotCoreThingCertificate",
  {
    status: "ACTIVE",
    certificateSigningRequest: fs.readFileSync(
      path.resolve("cert/cert.csr"),
      "utf8"
    ),
  }
);
yamatatsu commented 2 years ago

@matart15 If you created the cert in web console, it is not needed to register the cert to IoT Core with CDK. Because the cert is already registered. Probably, You can see the cert and its ARN in web console. And you can use the ARN in CDK to attach to policies and things as principal in step 4 and 5.

yamatatsu commented 2 years ago

Just for reference, AWS provides an API that creates a key and a certificate at the same time (like you created them in web console), which can be used in CloudFormation custom resource. This repository may be helpful. https://github.com/devops-at-home/cdk-iot-core-certificates

I hope these help you!

matart15 commented 2 years ago

@yamatatsu

I see. I am using web GUI just as a reference. My goal is to create everything by CDK code.

But your suggested code worked

I think my mistake was not using utf8 to read the file.

closing the issue. thank you again.

brucegl commented 2 years ago

@matart15 and @yamatatsu thanks for the updates. This works for me too!

@yamatatsu thanks for the L3 construct tip - I'll circle back and check on what other L2 and L3 constructs I can use.

github-actions[bot] commented 2 years ago

⚠️COMMENT VISIBILITY WARNING⚠️

Comments on closed issues are hard for our team to see. If you need more assistance, please either tag a team member or open a new issue that references this one. If you wish to keep having a conversation with other community members under this issue feel free to do so.

skinny85 commented 2 years ago

Thanks so much for the help here @yamatatsu! You're a much better owner of IoT in CDK than I am 😃.

badmintoncryer commented 1 month ago

The previous construct has already been archived and is no longer functioning properly due to issues with the SDK version.

Therefore, I recommend using a different construct with an updated SDK version, which has now been released.

https://constructs.dev/packages/cdk-iot-core-certificates-v3