Repository: cloud-custodian/cloud-custodian

Issue:
SecurityHub include public ips for EC2 instances
**Describe the bug**
Currently when reporting a finding for an EC2 instance to the Security, an incorrect resource field is used to populate the detail for the resource as a finding. When creating a finding for a public IP violation, the private IP of the EC2 instance is used as the IPV4 address in the finding, not the public IP address. 

The IP value that is reported is only accessible via the API, it is not populated in the UI. This is the resource object structure where IPV4 address is the private IP assigned to the instance
```
  "Resources": [
    {
      "Type": "",
      "Id": "",
      "Region": "",
      "Tags": {
        "",
        "Name": ""
      },
      "Details": {
        "AwsEc2Instance": {
          "Type": "",
          "ImageId": "",
          "IpV4Addresses": [
            "$PRIVATE IP"
          ],
          "IamInstanceProfileArn": "",
          "VpcId": "",
          "SubnetId": "",
          "LaunchedAt": ""
        }
      }
    }
  ],
```

**To Reproduce**
Create a policy to report on `PublicIP` on EC2 instances that publishes a finding to the SecurityHub service. 

```
 - name: public_ip_check
    resource: aws.ec2
    filters:
      - "PublicIpAddress": present
    actions:
      - type: post-finding
        description: |
          Public IP Address
        severity_normalized: 8
        types:
          - "Software and Configuration Checks/Industry and Regulatory Standards/NIST CSF Controls (USA)"
        recommendation: "Remove Public IP"
        recommendation_url: "https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-instance-addressing.html"
        confidence: 100
        compliance_status: FAILED
```

**Expected behavior**
A clear and concise description of what you expected to happen.
The IPV4 field in the Security hub finding  should be populated with the violating public IP address for a given EC2 instance. 



Discussion:
your example makes it hard to understand what your actualy looking for since its ommitted all the content, ie using your policy results in this finding.

```json
            "Resources": [
                {
                    "Type": "AwsEc2Instance",
                    "Id": "arn:aws:ec2:us-east-1:nnnnnnnn:instance/i-0c42a3120a1d4a236",
                    "Region": "us-east-1",
                    "Details": {
                        "AwsEc2Instance": {
                            "Type": "t2.micro",
                            "ImageId": "ami-07ebfd5b3428b6f4d",
                            "IpV4Addresses": [
                                "172.31.59.83"
                            ],
                            "VpcId": "vpc-d2d616b5",
                            "SubnetId": "subnet-3a334610",
                            "LaunchedAt": "2020-04-22T13:37:22+00:00"
                        }
                    }
                }
            ],
```

what your asking for is public ip addresses to be included in ipv4/ipv6.

the format here is the ASFF standard for security hub, i'm not sure why your sayings custodian is using an incorrect field.
https://docs.aws.amazon.com/securityhub/latest/userguide/securityhub-findings-format.html

Hey @kapilt  thanks for the quick response. Yes, correct. The IPV4 address in the finding should be the public IP since that is the violating resource. 

Or the other option would be to add the public and private IP to the finding if you think it is helpful to also populate the private IP. 
well given an instance may not have any public ips, but a policy wants to post a finding, it makes sense to have both. note security hub limits to 10 ips on import per instance.

Resolving patch:
diff --git a/c7n/resources/ec2.py b/c7n/resources/ec2.py
--- a/c7n/resources/ec2.py
+++ b/c7n/resources/ec2.py
@@ -1086,8 +1086,10 @@ def disable_monitoring(self, client, resources):
 class InstanceFinding(PostFinding):
     def format_resource(self, r):
         ip_addresses = jmespath.search(
-            "NetworkInterfaces[].PrivateIpAddresses[].PrivateIpAddress", r)
-
+            "NetworkInterfaces[].Association.PublicIp", r)
+        ip_addresses.extend(jmespath.search(
+            "NetworkInterfaces[].PrivateIpAddresses[].PrivateIpAddress", r))
+        ip_addresses = list(filter(None, ip_addresses))
         # limit to max 10 ip addresses, per security hub service limits
         ip_addresses = ip_addresses and ip_addresses[:10] or ip_addresses
         details = {


Test patch:
diff --git a/tools/c7n_azure/tests_azure/test_session.py b/tools/c7n_azure/tests_azure/test_session.py
--- a/tools/c7n_azure/tests_azure/test_session.py
+++ b/tools/c7n_azure/tests_azure/test_session.py
@@ -233,7 +233,8 @@ def test_get_functions_auth_string_overrides(self):
 
                 self.assertEqual(json.loads(auth), json.loads(expected))
 
-    def test_get_function_target_subscription(self):
+    # TODO this test has been flakey in ci, disabling temporarily
+    def xtest_get_function_target_subscription(self):
         with patch('azure.common.credentials.ServicePrincipalCredentials.__init__',
                    autospec=True, return_value=None):
             with patch.dict(os.environ,