Skip to content

Commit

Permalink
feat: add service control policies support (en-1912)
Browse files Browse the repository at this point in the history
  • Loading branch information
JonathanLoscalzo committed May 22, 2023
1 parent 2abf7e8 commit 1a0c3a7
Show file tree
Hide file tree
Showing 17 changed files with 1,814 additions and 26 deletions.
7 changes: 5 additions & 2 deletions iambic/config/wizard.py
Original file line number Diff line number Diff line change
Expand Up @@ -1853,8 +1853,9 @@ def configuration_wizard_change_detection_setup(self, aws_org: AWSOrganization):
return

session, _ = self.get_boto3_session_for_account(aws_org.org_account_id)
# cloudtrail is not cross-region, so we need to use us-east-1
cf_client = session.client(
"cloudformation", region_name=self.aws_default_region
"cloudformation", region_name="us-east-1" # self.aws_default_region
)
org_client = session.client(
"organizations", region_name=self.aws_default_region
Expand All @@ -1875,7 +1876,9 @@ def configuration_wizard_change_detection_setup(self, aws_org: AWSOrganization):

role_name = IAMBIC_SPOKE_ROLE_NAME
hub_account_id = self.hub_account_id
sqs_arn = f"arn:aws:sqs:{self.aws_default_region}:{hub_account_id}:IAMbicChangeDetectionQueue{IAMBIC_CHANGE_DETECTION_SUFFIX}"
# cloudtrail is not cross-region, so we need to use us-east-1
# sqs_arn = f"arn:aws:sqs:{self.aws_default_region}:{hub_account_id}:IAMbicChangeDetectionQueue{IAMBIC_CHANGE_DETECTION_SUFFIX}"
sqs_arn = f"arn:aws:sqs:us-east-1:{hub_account_id}:IAMbicChangeDetectionQueue{IAMBIC_CHANGE_DETECTION_SUFFIX}"

if not self.existing_role_template_map:
log.info("Loading AWS role templates...")
Expand Down
2 changes: 2 additions & 0 deletions iambic/core/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -310,6 +310,8 @@ class ProposedChangeType(Enum):
DELETE = "Delete"
ATTACH = "Attach"
DETACH = "Detach"
# This is used for states that we don't know how to handle. e.g. Exceptions during apply time
UNKNOWN = "Unknown"


class ProposedChange(PydanticBaseModel):
Expand Down
2 changes: 1 addition & 1 deletion iambic/core/template_generation.py
Original file line number Diff line number Diff line change
Expand Up @@ -1070,7 +1070,7 @@ def merge_model( # noqa: C901
setattr(merged_model, key, new_value)
else:
raise TypeError(
f"Type of {type(new_value)} is not supported. {IAMBIC_ERR_MSG}"
f"Type of {type(new_value)}({key}) is not supported. {IAMBIC_ERR_MSG}"
)
elif key not in iambic_fields:
setattr(merged_model, key, new_value)
Expand Down
3 changes: 3 additions & 0 deletions iambic/core/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -402,6 +402,9 @@ def evaluate_on_provider(
"""
from iambic.core.models import AccessModelMixin

if getattr(resource, "organization_account_needed", None):
return getattr(provider_details, "organization_account", False)

no_op_values = [IambicManaged.DISABLED]
if exclude_import_only:
no_op_values.append(IambicManaged.IMPORT_ONLY)
Expand Down
3 changes: 2 additions & 1 deletion iambic/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ def run_expire(templates: list[str], repo_dir: str = str(pathlib.Path.cwd())):
"repo_dir",
required=False,
type=click.Path(exists=True),
default=os.getenv("IAMBIC_REPO_DIR"),
help="The repo directory containing the templates. Example: ~/iambic-templates",
)
def detect(repo_dir: str):
Expand Down Expand Up @@ -398,7 +399,7 @@ def config_discovery(repo_dir: str):
)
def import_(repo_dir: str):
config_path = asyncio.run(resolve_config_template_path(repo_dir))
config = asyncio.run(load_config(config_path))
config: Config = asyncio.run(load_config(config_path))
check_and_update_resource_limit(config)
exe_message = ExecutionMessage(
execution_id=str(uuid.uuid4()), command=Command.IMPORT
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,20 @@ Resources:
- sqs:GetQueueUrl
- sqs:GetQueueAttributes
Resource:
- 'arn:aws:sqs:*:*:IAMbicChangeDetectionQueue'
- 'arn:aws:sqs:*:*:IAMbicChangeDetectionQueue*'
- Sid: SCPsReadWrite
Effect: Allow
Action:
- organizations:CreatePolicy
- organizations:DeletePolicy
- organizations:DescribePolicy
- organizations:UpdatePolicy
- organizations:ListPolicies
- organizations:AttachPolicy
- organizations:DetachPolicy
- organizations:TagResource
- organizations:UntagResource
- organizations:ListTagsForResource
Resource: '*'
ManagedPolicyArns:
- 'arn:aws:iam::aws:policy/ReadOnlyAccess'
34 changes: 34 additions & 0 deletions iambic/plugins/v0_1_0/aws/event_bridge/models.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from __future__ import annotations
from typing import Literal, Optional

from pydantic import BaseModel as PydanticBaseModel

Expand Down Expand Up @@ -32,3 +33,36 @@ class UserMessageDetails(PydanticBaseModel):
account_id: str
user_name: str
delete: bool


class SCPMessageDetails(PydanticBaseModel):
account_id: str
policy_id: str
delete: bool
event: Literal[
"CreatePolicy",
"DeletePolicy",
"UpdatePolicy",
"AttachPolicy",
"DetachPolicy",
"TagResource",
"UntagResource",
]

@staticmethod
def tag_event(event, source) -> bool:
"""Returns True if the event is a tag/untag event related to SCPs"""
return (
event in ["TagResource", "UntagResource"]
and source == "organizations.amazonaws.com"
)

@staticmethod
def get_policy_id(request_params, response_elements) -> Optional[str]:
"""Returns the policy ID from the request parameters or response elements (last one if it is a CreatePolicy event)"""
return (request_params and request_params.get("policyId", None)) or (
response_elements
and response_elements.get("policy", {})
.get("policySummary", {})
.get("id", None)
)
Loading

0 comments on commit 1a0c3a7

Please sign in to comment.