Repository: noqdev/iambic
Issue: Errors with AWS: extra fields not permitted (type=value_error.extra)

**Describe the bug**
Using iambic 0.9.1 I'm getting a couple of errors when importing my AWS Organisation with SSO, both during setup and also when running import.

During setup:
```
2023/06/15 16:40:35 [info     ] Failed to refresh AWS accounts
  error=ValidationError(model='RoleProperties', errors=[{'loc': ('InlinePolicies', 2, 'id'), 'msg': 'extra fields not permitted', 'type': 'value_error.extra'}])
? What would you like to configure in AWS? Go back
```

During import afterwards:
```
2023/06/15 16:45:22 [info     ] Finished templated user generation
Traceback (most recent call last):
  File "/Users/simon/.local/share/virtualenvs/iambic-templates-5HIzPko0/bin/iambic", line 8, in <module>
    sys.exit(cli())
             ^^^^^
  File "/Users/simon/.local/share/virtualenvs/iambic-templates-5HIzPko0/lib/python3.11/site-packages/click/core.py", line 1130, in __call__
    return self.main(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/simon/.local/share/virtualenvs/iambic-templates-5HIzPko0/lib/python3.11/site-packages/click/core.py", line 1055, in main
    rv = self.invoke(ctx)
         ^^^^^^^^^^^^^^^^
  File "/Users/simon/.local/share/virtualenvs/iambic-templates-5HIzPko0/lib/python3.11/site-packages/click/core.py", line 1657, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/simon/.local/share/virtualenvs/iambic-templates-5HIzPko0/lib/python3.11/site-packages/click/core.py", line 1404, in invoke
    return ctx.invoke(self.callback, **ctx.params)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/simon/.local/share/virtualenvs/iambic-templates-5HIzPko0/lib/python3.11/site-packages/click/core.py", line 760, in invoke
    return __callback(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/simon/.local/share/virtualenvs/iambic-templates-5HIzPko0/lib/python3.11/site-packages/iambic/main.py", line 411, in import_
    asyncio.run(config.run_import(exe_message, repo_dir))
  File "/opt/homebrew/Cellar/python@3.11/3.11.4/Frameworks/Python.framework/Versions/3.11/lib/python3.11/asyncio/runners.py", line 190, in run
    return runner.run(main)
           ^^^^^^^^^^^^^^^^
  File "/opt/homebrew/Cellar/python@3.11/3.11.4/Frameworks/Python.framework/Versions/3.11/lib/python3.11/asyncio/runners.py", line 118, in run
    return self._loop.run_until_complete(task)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/homebrew/Cellar/python@3.11/3.11.4/Frameworks/Python.framework/Versions/3.11/lib/python3.11/asyncio/base_events.py", line 653, in run_until_complete
    return future.result()
           ^^^^^^^^^^^^^^^
  File "/Users/simon/.local/share/virtualenvs/iambic-templates-5HIzPko0/lib/python3.11/site-packages/iambic/config/dynamic_config.py", line 245, in run_import
    await asyncio.gather(*tasks)
  File "/Users/simon/.local/share/virtualenvs/iambic-templates-5HIzPko0/lib/python3.11/site-packages/iambic/plugins/v0_1_0/aws/handlers.py", line 458, in import_aws_resources
    await asyncio.gather(*tasks)
  File "/Users/simon/.local/share/virtualenvs/iambic-templates-5HIzPko0/lib/python3.11/site-packages/iambic/plugins/v0_1_0/aws/handlers.py", line 335, in import_service_resources
    await asyncio.gather(
  File "/Users/simon/.local/share/virtualenvs/iambic-templates-5HIzPko0/lib/python3.11/site-packages/iambic/plugins/v0_1_0/aws/iam/role/template_generation.py", line 605, in generate_aws_role_templates
    resource_template = await create_templated_role(
                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/simon/.local/share/virtualenvs/iambic-templates-5HIzPko0/lib/python3.11/site-packages/iambic/plugins/v0_1_0/aws/iam/role/template_generation.py", line 435, in create_templated_role
    RoleProperties(**role_template_properties),
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/simon/.local/share/virtualenvs/iambic-templates-5HIzPko0/lib/python3.11/site-packages/iambic/core/models.py", line 85, in __init__
    super().__init__(*args, **kwargs)
  File "pydantic/main.py", line 341, in pydantic.main.BaseModel.__init__
pydantic.error_wrappers.ValidationError: 1 validation error for RoleProperties
InlinePolicies -> 2 -> id
  extra fields not permitted (type=value_error.extra)
```

**To Reproduce**
Steps to reproduce the behavior:

Run `iambic import`

**Expected behavior**
A successful import

**Screenshots**
If applicable, add screenshots to help explain your problem.

**Additional context**
Add any other context about the problem here.

**Community Engagement**
Your vote counts! Please support this bug report by adding a 👍 reaction to the original issue, which will aid the community and maintainers in addressing this problem.

Please refrain from adding "+1" or "me too" comments, as these create unnecessary noise for issue followers and do not help in prioritizing the issue. If you wish to contribute to solving this issue or have submitted a pull request, please leave a comment.


Changed files:
test/plugins/v0_1_0/aws/iam/role/test_utils.py, iambic/plugins/v0_1_0/aws/iam/policy/models.py, iambic/plugins/v0_1_0/aws/iam/role/template_generation.py, test/plugins/v0_1_0/aws/iam/role/test_models.py

diff --git a/iambic/plugins/v0_1_0/aws/iam/policy/models.py b/iambic/plugins/v0_1_0/aws/iam/policy/models.py
index 76cc6948..1d135f52 100644
--- a/iambic/plugins/v0_1_0/aws/iam/policy/models.py
+++ b/iambic/plugins/v0_1_0/aws/iam/policy/models.py
@@ -201,6 +201,10 @@ class PolicyDocument(AccessModel, ExpiryModel):
         None,
         description="List of policy statements",
     )
+    id: Optional[str] = Field(
+        None,
+        description="The Id element specifies an optional identifier for the policy. The ID is used differently in different services.",
+    )
 
     @property
     def resource_type(self):
diff --git a/iambic/plugins/v0_1_0/aws/iam/role/template_generation.py b/iambic/plugins/v0_1_0/aws/iam/role/template_generation.py
index 2a9c9385..0af67d4e 100644
--- a/iambic/plugins/v0_1_0/aws/iam/role/template_generation.py
+++ b/iambic/plugins/v0_1_0/aws/iam/role/template_generation.py
@@ -426,15 +426,26 @@ async def create_templated_role(  # noqa: C901
         role_template_params.get("included_accounts"),
         role_path=path,
     )
-    return create_or_update_template(
-        file_path,
-        existing_template_map,
-        role_name,
-        AwsIamRoleTemplate,
-        role_template_params,
-        RoleProperties(**role_template_properties),
-        list(aws_account_map.values()),
-    )
+    try:
+        return create_or_update_template(
+            file_path,
+            existing_template_map,
+            role_name,
+            AwsIamRoleTemplate,
+            role_template_params,
+            RoleProperties(**role_template_properties),
+            list(aws_account_map.values()),
+        )
+    except Exception as e:
+        log_params = {
+            "role_name": role_name,
+            "role_template_params": role_template_params,
+        }
+        log.error(
+            "Not able to create_or_update_template",
+            **log_params,
+        )
+        raise e
 
 
 async def collect_aws_roles(
diff --git a/test/plugins/v0_1_0/aws/iam/role/test_models.py b/test/plugins/v0_1_0/aws/iam/role/test_models.py
index 175906ec..62fd3ab0 100644
--- a/test/plugins/v0_1_0/aws/iam/role/test_models.py
+++ b/test/plugins/v0_1_0/aws/iam/role/test_models.py
@@ -796,3 +796,42 @@ def test_mixed_type_description_merges():
     new_properties = RoleProperties(role_name="foo", description=new_description)
     merged_model = merge_model(new_properties, existing_properties, [])
     assert merged_model.description[0].description == "foo"
+
+
+def test_role_policy_id():
+    role_properties_kwargs = {
+        "role_name": "bar",
+        "inline_policies": [
+            {
+                "policy_name": "hello",
+                "included_accounts": ["*"],
+                "id": "uuid-4",
+                "statement": {
+                    "effect": "Deny",
+                    "action": ["s3:GetObject"],
+                    "resource": "*",
+                },
+            },
+        ],
+    }
+    role_properties = RoleProperties(**role_properties_kwargs)
+    assert role_properties
+
+
+def test_role_no_policy_id():
+    role_properties_kwargs = {
+        "role_name": "bar",
+        "inline_policies": [
+            {
+                "policy_name": "hello",
+                "included_accounts": ["*"],
+                "statement": {
+                    "effect": "Deny",
+                    "action": ["s3:GetObject"],
+                    "resource": "*",
+                },
+            },
+        ],
+    }
+    role_properties = RoleProperties(**role_properties_kwargs)
+    assert role_properties
diff --git a/test/plugins/v0_1_0/aws/iam/role/test_utils.py b/test/plugins/v0_1_0/aws/iam/role/test_utils.py
index 89097374..c3b9731d 100644
--- a/test/plugins/v0_1_0/aws/iam/role/test_utils.py
+++ b/test/plugins/v0_1_0/aws/iam/role/test_utils.py
@@ -46,6 +46,7 @@ EXAMPLE_INLINE_POLICY_NAME = "example_inline_policy_name"
 EXAMPLE_INLINE_POLICY_DOCUMENT = """
 {
    "Version":"2012-10-17",
+   "Id": "cd3ad3d9-2776-4ef1-a904-4c229d1642ee",
    "Statement":[
       {
          "Effect":"Allow",