diff --git a/.github/prerequisites/README.md b/.github/prerequisites/README.md
new file mode 100644
index 0000000..c77ade8
--- /dev/null
+++ b/.github/prerequisites/README.md
@@ -0,0 +1,24 @@
+# AWS PREREQUISITES FOR THE GITHUB ACTIONS CI/CD PIPELINE
+
+Inspired on:
+
+- https://github.com/aws-actions/configure-aws-credentials/tree/main/examples
+
+## Part 1 (CDK Bootstrap)
+
+Make sure that the target account (on the needed regions) have CDK Bootstrapped already. If not, please follow these steps to have CDK init stack already in place:
+
+- [AWS CDK Bootstrapping Guide](https://docs.aws.amazon.com/cdk/v2/guide/bootstrapping.html)
+
+## Part 2 (GitHub OIDC Federation and Role)
+
+The CI/CD uses aws-action `configure-aws-credentials` with OIDC federation. Prior to using this project, we need to deploy the [github-actions-oidc-federation-and-role](github-actions-oidc-federation-and-role.yml) CloudFormation template in the AWS account(s) that we need to deploy the solution. Specify the GitHub Organization Name, Repository Name, and the specific branch you want to deploy on.
+
+> Note: In this case, "GitHub Organization Name" is "san99tiago" (my GitHub account).
+
+To use the example you will need to set the following GitHub Action Secrets:
+
+| Secret Key | Used With | Description |
+| --------------- | ------------------------- | ------------------------ |
+| AWS_ACCOUNT_ID | configure-aws-credentials | The AWS account ID |
+| AWS_DEPLOY_ROLE | configure-aws-credentials | The name of the IAM role |
diff --git a/.github/prerequisites/github-actions-oidc-federation-and-role.yml b/.github/prerequisites/github-actions-oidc-federation-and-role.yml
new file mode 100644
index 0000000..cc8cdc9
--- /dev/null
+++ b/.github/prerequisites/github-actions-oidc-federation-and-role.yml
@@ -0,0 +1,92 @@
+---
+AWSTemplateFormatVersion: "2010-09-09"
+Description: Github Actions configuration - OIDC IAM IdP and associated role CI/CD
+
+Parameters:
+
+ GitHubOrganization:
+ Type: String
+ Description: This is the root organization or personal account where repos are stored (Case Sensitive)
+
+ RepositoryName:
+ Type: String
+ Description: The repo(s) these roles will have access to. (Use * for all org or personal repos)
+ Default: "*"
+
+ BranchName:
+ Type: String
+ Description: Name of the git branch to to trust. (Use * for all branches)
+ Default: "*"
+
+ RoleName:
+ Type: String
+ Description: Name the Role
+
+ UseExistingProvider:
+ Type: String
+ Description: "Only one GitHub Provider can exists. Choose yes if one is already present in account"
+ Default: "no"
+ AllowedValues:
+ - "yes"
+ - "no"
+
+Conditions:
+
+ CreateProvider: !Equals ["no", !Ref UseExistingProvider]
+
+Resources:
+
+ IdpGitHubOidc:
+ Type: AWS::IAM::OIDCProvider
+ Condition: CreateProvider
+ Properties:
+ Url: https://token.actions.githubusercontent.com
+ ClientIdList:
+ - sts.amazonaws.com
+ - !Sub https://github.com/${GitHubOrganization}/${RepositoryName}
+ ThumbprintList:
+ - 6938fd4d98bab03faadb97b34396831e3780aea1
+ Tags:
+ - Key: Name
+ Value: !Sub ${RoleName}-OIDC-Provider
+
+ RoleGithubActions:
+ Type: AWS::IAM::Role
+ Properties:
+ RoleName: !Ref RoleName
+ AssumeRolePolicyDocument:
+ Statement:
+ - Effect: Allow
+ Action: sts:AssumeRoleWithWebIdentity
+ Principal:
+ Federated: !If
+ - CreateProvider
+ - !Ref IdpGitHubOidc
+ - !Sub arn:${AWS::Partition}:iam::${AWS::AccountId}:oidc-provider/token.actions.githubusercontent.com
+ Condition:
+ StringLike:
+ token.actions.githubusercontent.com:sub: !Sub repo:${GitHubOrganization}/${RepositoryName}:ref:refs/heads/${BranchName}
+
+ RoleGithubActionsPolicies:
+ Type: "AWS::IAM::Policy"
+ Properties:
+ PolicyName: !Sub ${RoleName}-Policy
+ PolicyDocument:
+ Version: "2012-10-17"
+ Statement:
+ - Effect: "Allow"
+ Action: "sts:AssumeRole"
+ Resource: "arn:aws:iam::*:role/cdk-*"
+ Roles:
+ - !Ref RoleGithubActions
+
+Outputs:
+
+ IdpGitHubOidc:
+ Condition: CreateProvider
+ Description: "ARN of Github OIDC Provider"
+ Value: !GetAtt IdpGitHubOidc.Arn
+
+ RoleGithubActionsARN:
+ Description: "CICD Role for GitHub Actions"
+ Value: !GetAtt RoleGithubActions.Arn
\ No newline at end of file
diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml
new file mode 100644
index 0000000..e2c639d
--- /dev/null
+++ b/.github/workflows/deploy.yml
@@ -0,0 +1,198 @@
+name: deploy
+
+on:
+ push:
+ branches: [ 'main', 'feature/**']
+ tags: [ 'v*']
+env:
+ AWS_DEFAULT_REGION: us-east-1
+ AWS_DEFAULT_OUTPUT: json
+
+jobs:
+ code-quality:
+ name: Check coding standards
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v3
+ - run: echo "Job triggered by ${{ github.event_name }} event."
+ - run: echo "Job running on a ${{ runner.os }} server hosted by GitHub."
+ - run: echo "Branch name is ${{ github.ref }} and repository is ${{ github.repository }}."
+ - uses: actions/setup-python@v4
+ with:
+ python-version: 3.11
+ - name: Install Poetry
+ uses: snok/install-poetry@v1
+ with:
+ virtualenvs-create: true
+ virtualenvs-in-project: true
+ installer-parallel: true
+ - name: Install Poetry dependencies
+ run: poetry install --no-interaction
+ - name: Check code formatting
+ run: poetry run poe black-check
+
+ tests:
+ name: Run tests
+ needs: code-quality
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v3
+
+ - uses: actions/setup-python@v4
+ with:
+ python-version: 3.11
+ - name: Install Poetry
+ uses: snok/install-poetry@v1
+ with:
+ virtualenvs-create: true
+ virtualenvs-in-project: true
+ installer-parallel: true
+
+ - name: Install Poetry dependencies
+ run: poetry install --no-interaction
+
+ - name: Run tests
+ run: poetry run poe test-unit
+
+ - name: Archive code coverage results
+ uses: actions/upload-artifact@v3
+ with:
+ name: code-coverage-report
+ path: htmlcov
+
+ cdk-synth-diff:
+ name: CDK Synth & Diff
+ runs-on: ubuntu-latest
+ needs: code-quality
+ permissions:
+ id-token: write # This is required for requesting the JWT
+ contents: read # This is required for actions/checkout
+ steps:
+ - uses: actions/checkout@v3
+ - uses: actions/setup-python@v4
+ with:
+ python-version: 3.11
+
+ - name: Install Poetry
+ uses: snok/install-poetry@v1
+ with:
+ virtualenvs-create: true
+ virtualenvs-in-project: true
+ installer-parallel: true
+
+ - name: Install Poetry dependencies
+ run: poetry install --no-interaction
+
+ - name: Set up NodeJs
+ uses: actions/setup-node@v3
+ with:
+ node-version: "20"
+
+ - name: Install CDK
+ run: |
+ npm install -g aws-cdk
+
+ - name: Configure AWS Credentials
+ uses: aws-actions/configure-aws-credentials@v4
+ with:
+ aws-region: ${{ env.AWS_DEFAULT_REGION }}
+ role-to-assume: arn:aws:iam::${{ secrets.AWS_ACCOUNT_ID }}:role/${{ secrets.AWS_DEPLOY_ROLE }}
+ role-session-name: myGitHubActions
+
+ # Sample STS get caller identity for tests
+ - name: sts get-caller-identity
+ run: |
+ aws sts get-caller-identity
+
+ - name: CDK Synth
+ run: |
+ source .venv/bin/activate
+ cdk synth
+
+ - name: CDK Diff
+ run: |
+ source .venv/bin/activate
+ cdk diff
+
+ - name: Archive CDK Synth results (no assets)
+ uses: actions/upload-artifact@v3
+ with:
+ name: cdk-synth-folder
+ path: |
+ ./cdk.out
+ !./cdk.out/asset.*
+ retention-days: 1
+
+ iac-checkov:
+ name: IaC Checkov Validations
+ runs-on: ubuntu-latest
+ needs: cdk-synth-diff
+ steps:
+ - uses: actions/checkout@v3
+
+ - name: Dowload CDK Synth results
+ uses: actions/download-artifact@v3
+ with:
+ name: cdk-synth-folder
+ path: ./cdk-synth-output-folder
+
+ - name: Display files in the output folder
+ run: ls -lrta
+ working-directory: ./cdk-synth-output-folder
+
+ - name: Run Checkov action
+ id: checkov
+ uses: bridgecrewio/checkov-action@v12
+ with:
+ directory: cdk-synth-output-folder/
+ framework: cloudformation
+ soft_fail: true # optional: do not return an error code if there are failed checks
+ skip_check: CKV_AWS_2 # optional: skip a specific check_id. can be comma separated list
+ quiet: true # optional: display only failed checks
+
+ cdk-deploy:
+ name: Deploy CDK
+ runs-on: ubuntu-latest
+ needs:
+ - iac-checkov
+ - tests
+ if: github.ref == 'refs/heads/main'
+ permissions:
+ id-token: write # This is required for requesting the JWT
+ contents: read # This is required for actions/checkout
+ steps:
+ - uses: actions/checkout@v3
+ - uses: actions/setup-python@v4
+ with:
+ python-version: 3.11
+
+ - name: Install Poetry
+ uses: snok/install-poetry@v1
+ with:
+ virtualenvs-create: true
+ virtualenvs-in-project: true
+ installer-parallel: true
+
+ - name: Install Poetry dependencies
+ run: poetry install --no-interaction
+
+ - name: Set up NodeJs
+ uses: actions/setup-node@v3
+ with:
+ node-version: "20"
+
+ - name: Install CDK
+ run: npm install -g aws-cdk
+
+ - name: Configure AWS Credentials
+ uses: aws-actions/configure-aws-credentials@v4
+ with:
+ aws-region: ${{ env.AWS_DEFAULT_REGION }}
+ role-to-assume: arn:aws:iam::${{ secrets.AWS_ACCOUNT_ID }}:role/${{ secrets.AWS_DEPLOY_ROLE }}
+ role-session-name: myGitHubActions
+
+ # NOTE: for now no manual approvals are required
+ - name: Deploy to AWS
+ run: |
+ source .venv/bin/activate
+ cdk deploy --require-approval=never
diff --git a/README.md b/README.md
index c14d861..51cd155 100644
--- a/README.md
+++ b/README.md
@@ -1,11 +1,42 @@
# :bank: AWS-CDK-ORGANIZATIONS-DEMO :bank:
+![Badge Workflow](https://github.com/san99tiago/aws-cdk-organizations-demo/actions/workflows/deploy.yml/badge.svg)
+
DEMO for the best practices of AWS Organizations with Infrastructure as Code on CDK-Python.
## TODO:
-Add a detailed README with diagram, explanation and examples of usage.
+Add a detailed README with diagrams, explanations and examples of usage.
+
+## CI/CD and Deployment 🚀
+
+The deployment process is intended to run with GitHub Actions Workflows.
+
+- On `feature/****` branches commits, the CDK project gets **synthesized** and it shows the **state diff** between the current AWS resources and the expected ones.
+
+- When merged to `main` branch, it will get deployed to the AWS Account automatically.
+
+To understand the AWS Credentials usage, please refer to the [`prerequisites/README.md`](.github/prerequisites/README.md).
+
+## Special thanks :gift:
+
+- Thanks to all contributors of the great OpenSource projects that I am using.
+
+## Author :musical_keyboard:
+
+### Santiago Garcia Arango
+
+
+
+
+ Curious DevOps Engineer passionate about advanced cloud-based solutions and deployments in AWS. I am convinced that today's greatest challenges must be solved by people that love what they do.
+ |
+
+
+ |
+
+
## LICENSE
-Copyright 2023 Santiago Garcia Arango
+Copyright 2023 Santiago Garcia Arango.
diff --git a/assets/SantiagoGarciaArangoCDK.png b/assets/SantiagoGarciaArangoCDK.png
new file mode 100644
index 0000000..507b49c
Binary files /dev/null and b/assets/SantiagoGarciaArangoCDK.png differ
diff --git a/cdk.context.json b/cdk.context.json
new file mode 100644
index 0000000..b5ede40
--- /dev/null
+++ b/cdk.context.json
@@ -0,0 +1,8 @@
+{
+ "main_resources_name": "san99tiago-demo-organization",
+ "tags": {
+ "Owner": "Santiago Garcia Arango",
+ "Source": "https://github.com/san99tiago/aws-cdk-organizations-demo",
+ "Usage": "Configuration of AWS Organizations for san99tiago-demo AWS accounts setup"
+ }
+}
diff --git a/cdk.json b/cdk.json
new file mode 100644
index 0000000..912fe87
--- /dev/null
+++ b/cdk.json
@@ -0,0 +1,3 @@
+{
+ "app": "python3 cdk/app.py"
+}
diff --git a/cdk/.gitignore b/cdk/.gitignore
new file mode 100644
index 0000000..37833f8
--- /dev/null
+++ b/cdk/.gitignore
@@ -0,0 +1,10 @@
+*.swp
+package-lock.json
+__pycache__
+.pytest_cache
+.venv
+*.egg-info
+
+# CDK asset staging directory
+.cdk.staging
+cdk.out
diff --git a/cdk/app.py b/cdk/app.py
new file mode 100644
index 0000000..5087676
--- /dev/null
+++ b/cdk/app.py
@@ -0,0 +1,47 @@
+################################################################################
+# SAN99TIAGODEMO AWS ORGANIZATION (INFRASTRUCTURE AS CODE CDK SOLUTION)
+# ! --> PLEASE SEE NOTES ON "stacks/cdk_organization.py" file. (IMPORTANT)
+################################################################################
+
+# Built-in imports
+import os
+
+# External imports
+import aws_cdk as cdk
+
+# Own imports
+from helpers.add_tags import add_tags_to_app
+from stacks.cdk_organization import OrganizationStack
+
+
+print("--> Deployment AWS configuration (safety first):")
+print("CDK_DEFAULT_ACCOUNT", os.getenv("CDK_DEFAULT_ACCOUNT"))
+print("CDK_DEFAULT_REGION", os.getenv("CDK_DEFAULT_REGION"))
+
+app = cdk.App()
+
+# Configurations for the deployment (obtained from env vars and CDK context)
+DEPLOYMENT_ENVIRONMENT = os.environ.get("DEPLOYMENT_ENVIRONMENT", "prod")
+MAIN_RESOURCES_NAME = app.node.try_get_context("main_resources_name")
+
+
+org_stack = OrganizationStack(
+ app,
+ MAIN_RESOURCES_NAME,
+ DEPLOYMENT_ENVIRONMENT,
+ env={
+ "account": os.getenv("CDK_DEFAULT_ACCOUNT"),
+ "region": os.getenv("CDK_DEFAULT_REGION"),
+ },
+ description="Stack for {} infrastructure in {} environment".format(
+ MAIN_RESOURCES_NAME, DEPLOYMENT_ENVIRONMENT
+ ),
+)
+
+add_tags_to_app(
+ app,
+ MAIN_RESOURCES_NAME,
+ DEPLOYMENT_ENVIRONMENT,
+)
+
+app.synth()
diff --git a/cdk/helpers/add_tags.py b/cdk/helpers/add_tags.py
new file mode 100644
index 0000000..9d2fe74
--- /dev/null
+++ b/cdk/helpers/add_tags.py
@@ -0,0 +1,22 @@
+import aws_cdk as cdk
+
+
+def add_tags_to_app(
+ app: cdk.App, main_resources_name: str, deployment_environment: str
+) -> None:
+ """
+ Function to add custom tags to app in a centralized fashion.
+
+ :param app: (aws_cdk.App) to apply tags to.
+ :param main_resources_name: (str) the main solution name being deployed.
+ :param deployment_environment: (str) value of the tag "environment".
+ """
+
+ app_tags = cdk.Tags.of(app)
+ app_tags.add("MainResourcesName", main_resources_name)
+ app_tags.add("Environment", deployment_environment)
+
+ # Add tags from CDK context
+ context_tags = app.node.try_get_context("tags")
+ for key in context_tags:
+ app_tags.add(key, context_tags[key])
diff --git a/cdk/requirements.txt b/cdk/requirements.txt
new file mode 100644
index 0000000..5ccefb1
--- /dev/null
+++ b/cdk/requirements.txt
@@ -0,0 +1,3 @@
+aws-cdk-lib==2.87.0
+constructs>=10.0.0,<11.0.0
+pepperize.cdk-organizations==0.7.577
diff --git a/cdk/stacks/__init__.py b/cdk/stacks/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/cdk/stacks/cdk_organization.py b/cdk/stacks/cdk_organization.py
new file mode 100644
index 0000000..c71ee3c
--- /dev/null
+++ b/cdk/stacks/cdk_organization.py
@@ -0,0 +1,225 @@
+################################################################################
+# SAN99TIAGODEMO AWS ORGANIZATION (INFRASTRUCTURE AS CODE CDK SOLUTION)
+# NOTE 1: I am using a CDK-based approach that is not maintained by AWS (yet):
+# --> https://github.com/pepperize/cdk-organizations
+# NOTE 2: As multiple accounts are being created, there are some "CDK" node
+# ... dependencies. See example at the end on the source repo (link above)
+################################################################################
+
+# Built-in imports
+import os
+import json
+
+# External imports
+from aws_cdk import (
+ Stack,
+ CfnOutput,
+)
+from constructs import Construct
+from pepperize_cdk_organizations import (
+ Account,
+ FeatureSet,
+ Organization,
+ OrganizationalUnit,
+ Policy,
+ PolicyType,
+)
+
+
+class OrganizationStack(Stack):
+ """
+ Class to create the infrastructure of the AWS Organizations.
+ """
+
+ def __init__(
+ self, scope: Construct, construct_id: str, deployment_environment: str, **kwargs
+ ) -> None:
+ super().__init__(scope, construct_id, **kwargs)
+
+ self.construct_id = construct_id
+ self.deployment_environment = deployment_environment
+
+ # Organization creation, services configuration and SCPs
+ self.create_root_organization()
+ self.configure_organization_services()
+ self.configure_service_control_policies()
+
+ # Create "sandbox" OU with inner OUs and accounts inside
+ self.create_ou_sandbox()
+ self.create_accounts_inside_ou_sandbox()
+
+ # !IMPORTANT: this is mandatory for adding CDK dependencies for each account
+ self.add_cdk_accounts_dependencies() # DO NOT REMOVE!
+
+ # Create CloudFormation outputs
+ self.generate_cloudformation_outputs()
+
+ def create_root_organization(self):
+ """
+ Method that creates the AWS Organization (root).
+ """
+ self.organization = Organization(
+ self,
+ id="RootOrganization",
+ feature_set=FeatureSet.ALL,
+ )
+
+ def configure_organization_services(self):
+ """
+ Method that configures the AWS Organization with the desired enabled
+ services and policies (enable the desired ones).
+ """
+ # Note 1: for more details on services, see full list at:
+ # --> https://docs.aws.amazon.com/organizations/latest/userguide/orgs_integrate_services_list.html
+ # Note 2: for more details on policies, see full list at:
+ # --> https://docs.aws.amazon.com/organizations/latest/userguide/orgs_manage_policies.html
+
+ # Enable service for AWS IAM Identity Center (AWS Single Sign-On Dashboard)
+ self.organization.enable_aws_service_access("sso.amazonaws.com")
+
+ # Enable service for Resource Access Manager (RAM)
+ self.organization.enable_aws_service_access("ram.amazonaws.com")
+
+ # Enable Service Control Policies (SCPs)
+ self.organization.enable_policy_type(PolicyType.SERVICE_CONTROL_POLICY)
+
+ def configure_service_control_policies(self):
+ """
+ Method that configures the AWS Organization with the desired Service
+ Control Policies (SCPs) at organization level.
+ """
+
+ # Get OS path to SCPs files and load them (for easier read/write of SCPs)
+ path_scp_prevent_leaving_org = os.path.join(
+ os.path.dirname(__file__),
+ "scp_prevent_leaving_org.json",
+ )
+ with open(path_scp_prevent_leaving_org, "r") as file:
+ scp_prevent_leaving_org = json.load(file)
+
+ path_scp_allow_specific_regions = os.path.join(
+ os.path.dirname(__file__),
+ "scp_allow_specific_regions.json",
+ )
+ with open(path_scp_allow_specific_regions, "r") as file:
+ scp_allow_specific_regions = json.load(file)
+
+ # SCP for preventing accounts of leaving organization
+ self.policy_deny_leave_org = Policy(
+ self,
+ id="PolicyDenyLeave",
+ content=json.dumps(scp_prevent_leaving_org),
+ policy_name="PreventLeavingOrganization",
+ policy_type=PolicyType.SERVICE_CONTROL_POLICY,
+ description="SCP to prevent accounts from leaving the organization",
+ )
+ self.organization.attach_policy(self.policy_deny_leave_org)
+
+ # SCP for only allow access to specific regions in AWS (deny others)
+ self.policy_allow_specific_regions = Policy(
+ self,
+ id="PolicyAllowSpecificRegions",
+ content=json.dumps(scp_allow_specific_regions),
+ policy_name="AllowSpecificRegions",
+ policy_type=PolicyType.SERVICE_CONTROL_POLICY,
+ description="SCP to only allow access to specific AWS Regions",
+ )
+ self.organization.attach_policy(self.policy_allow_specific_regions)
+
+ def create_ou_sandbox(self):
+ """
+ Method that creates inner Organizational Units (OUs) inside organization.
+ """
+ self.top_level_ou_sandbox = OrganizationalUnit(
+ self,
+ id="SandboxOU",
+ parent=self.organization.root,
+ organizational_unit_name="sandbox",
+ )
+
+ def create_accounts_inside_ou_sandbox(self):
+ """
+ Method that creates AWS Accounts inside the required Organizational
+ Units (OUs).
+ """
+ self.account_sandbox_1 = Account(
+ self,
+ id="SandboxAccount1",
+ account_name="san99tiago-sandbox-1",
+ email="san99tiagodemo+san99tiago-sandbox-1@gmail.com",
+ parent=self.top_level_ou_sandbox,
+ role_name="OrganizationAccountAccessRole",
+ )
+ self.account_sandbox_2 = Account(
+ self,
+ id="SandboxAccount2",
+ account_name="san99tiago-sandbox-2",
+ email="san99tiagodemo+san99tiago-sandbox-2@gmail.com",
+ parent=self.top_level_ou_sandbox,
+ role_name="OrganizationAccountAccessRole",
+ )
+
+ def add_cdk_accounts_dependencies(self):
+ """
+ ULTRA IMPORTANT METHOD to add CDK dependencies for the AWS Accounts that
+ are being created (to avoid 2 accounts creation simultaneously, which is
+ not supported by AWS). This is because of AWS Organizations limitation.
+ """
+ # ! IMPORTANT: We MUST add these dependencies, as AWS Organizations only support
+ # ... one account creation "IN_PROGRESS". We add CDK dependency to solve issue
+ # ... and wait for the previous one to finish, to continue with the next...
+ self.account_sandbox_2.node.add_dependency(self.account_sandbox_1)
+
+ def generate_cloudformation_outputs(self):
+ """
+ Method to add the relevant CloudFormation outputs.
+ """
+
+ CfnOutput(
+ self,
+ "DeploymentEnvironment",
+ value=self.deployment_environment,
+ description="Deployment environment",
+ )
+
+ CfnOutput(
+ self,
+ "OrganizationId",
+ value=self.organization.organization_id,
+ description="ID of the Organization",
+ )
+
+ CfnOutput(
+ self,
+ "RootId",
+ value=self.organization.root.identifier(),
+ description="ID of the Root OU",
+ )
+
+ CfnOutput(
+ self,
+ "ManagementAccountId",
+ value=self.organization.management_account_id,
+ description="ID of the Management Account",
+ )
+
+ CfnOutput(
+ self,
+ "ManagementAccountEmail",
+ value=self.organization.management_account_email,
+ description="Email of the Management Account",
+ )
+
+ CfnOutput(
+ self,
+ "AccountSandbox1Id",
+ value=self.account_sandbox_1.account_id,
+ description="ID of the SandboxAccount1",
+ )
+
+ CfnOutput(
+ self,
+ "AccountSandbox2Id",
+ value=self.account_sandbox_2.account_id,
+ description="ID of the SandboxAccount2",
+ )
diff --git a/cdk/stacks/scp_allow_specific_regions.json b/cdk/stacks/scp_allow_specific_regions.json
new file mode 100644
index 0000000..378147f
--- /dev/null
+++ b/cdk/stacks/scp_allow_specific_regions.json
@@ -0,0 +1,64 @@
+{
+ "Version": "2012-10-17",
+ "Statement": [
+ {
+ "Sid": "DenyAllOutsideUS",
+ "Effect": "Deny",
+ "NotAction": [
+ "a4b:*",
+ "acm:*",
+ "aws-marketplace-management:*",
+ "aws-marketplace:*",
+ "aws-portal:*",
+ "budgets:*",
+ "ce:*",
+ "chime:*",
+ "cloudfront:*",
+ "config:*",
+ "cur:*",
+ "directconnect:*",
+ "ec2:DescribeRegions",
+ "ec2:DescribeTransitGateways",
+ "ec2:DescribeVpnGateways",
+ "fms:*",
+ "globalaccelerator:*",
+ "health:*",
+ "iam:*",
+ "importexport:*",
+ "kms:*",
+ "mobileanalytics:*",
+ "networkmanager:*",
+ "organizations:*",
+ "pricing:*",
+ "route53:*",
+ "route53domains:*",
+ "route53-recovery-cluster:*",
+ "route53-recovery-control-config:*",
+ "route53-recovery-readiness:*",
+ "s3:GetAccountPublic*",
+ "s3:ListAllMyBuckets",
+ "s3:ListMultiRegionAccessPoints",
+ "s3:PutAccountPublic*",
+ "shield:*",
+ "sts:*",
+ "support:*",
+ "trustedadvisor:*",
+ "waf-regional:*",
+ "waf:*",
+ "wafv2:*",
+ "wellarchitected:*"
+ ],
+ "Resource": "*",
+ "Condition": {
+ "StringNotEquals": {
+ "aws:RequestedRegion": [
+ "us-east-1",
+ "us-east-2",
+ "us-west-1",
+ "us-west-2"
+ ]
+ }
+ }
+ }
+ ]
+}
diff --git a/cdk/stacks/scp_prevent_leaving_org.json b/cdk/stacks/scp_prevent_leaving_org.json
new file mode 100644
index 0000000..7245daa
--- /dev/null
+++ b/cdk/stacks/scp_prevent_leaving_org.json
@@ -0,0 +1,10 @@
+{
+ "Version": "2012-10-17",
+ "Statement": [
+ {
+ "Effect": "Deny",
+ "Action": ["organizations:LeaveOrganization"],
+ "Resource": ["*"]
+ }
+ ]
+}
diff --git a/important_commands.sh b/important_commands.sh
new file mode 100644
index 0000000..15fe790
--- /dev/null
+++ b/important_commands.sh
@@ -0,0 +1,60 @@
+#!/bin/bash
+
+################################################################################
+# PART 1: Configure NodeJs, Python and CDK libraries
+################################################################################
+
+# Install NodeJs and Python
+# --> https://nodejs.org/en/download/
+# --> https://www.python.org/downloads/
+
+# Verify that NodeJs/npm is installed correctly
+node --version
+npm --version
+
+# Verify that Python/pip is installed correctly
+python --version || python3 --version
+pip --version || pip3 --version
+
+# Install AWS-CDK (on NodeJs)
+sudo npm install -g aws-cdk
+
+# Verify correct install of AWS-CDK
+npm list --global | grep aws-cdk
+
+
+################################################################################
+# PART 2: Initial Project Setup (Only run these at the beginning)
+################################################################################
+
+# Configure AWS credentials (follow steps)
+aws configure
+# --> Alternative 1: Environment variables added to terminal session
+# --> Alternative 2: AWS Cloud9 with the right permissions
+# --> Alternative 3: AWS SSO login
+
+# Bootstrap CDK (provision initial resources to work with CDK.. S3, roles, etc)
+#! Change "ACCOUNT-NUMBER" and "REGION" to your needed values
+cdk bootstrap aws://ACCOUNT-NUMBER/REGION
+
+# Install poetry (for managing Python dependencies)
+pip install poetry
+
+# Install poetry dependencies for the virtual environment
+poetry install
+
+
+################################################################################
+# PART 3: Main CDK and Python commands (most used)
+################################################################################
+
+# Activate Python virtual environment with Poetry tool
+poetry shell
+
+# Run unit tests
+poe test-unit
+
+# Deploy commands (NOTE: prefered method is with the CI/CD Pipeline)
+export DEPLOYMENT_ENVIRONMENT=dev
+cdk synth
+cdk deploy # I recommend to use GitHub Actions Pipeline instead
diff --git a/poetry.lock b/poetry.lock
index 95ef3e5..20b9729 100644
--- a/poetry.lock
+++ b/poetry.lock
@@ -92,61 +92,66 @@ publication = ">=0.0.3"
typeguard = ">=2.13.3,<2.14.0"
[[package]]
-name = "aws-lambda-powertools"
-version = "2.25.0"
-description = "Powertools for AWS Lambda (Python) is a developer toolkit to implement Serverless best practices and increase developer velocity."
+name = "black"
+version = "23.9.1"
+description = "The uncompromising code formatter."
category = "dev"
optional = false
-python-versions = ">=3.7.4,<4.0.0"
+python-versions = ">=3.8"
files = [
- {file = "aws_lambda_powertools-2.25.0-py3-none-any.whl", hash = "sha256:4abdef017650db820fc9c39d3a31e8f51be5ddb338b63741e5ea6c0966291b0e"},
- {file = "aws_lambda_powertools-2.25.0.tar.gz", hash = "sha256:29470dccd8bd8125aa5faa6f131f3b3d5641f4b8b505a8ea5fc70e082eacdade"},
+ {file = "black-23.9.1-cp310-cp310-macosx_10_16_arm64.whl", hash = "sha256:d6bc09188020c9ac2555a498949401ab35bb6bf76d4e0f8ee251694664df6301"},
+ {file = "black-23.9.1-cp310-cp310-macosx_10_16_universal2.whl", hash = "sha256:13ef033794029b85dfea8032c9d3b92b42b526f1ff4bf13b2182ce4e917f5100"},
+ {file = "black-23.9.1-cp310-cp310-macosx_10_16_x86_64.whl", hash = "sha256:75a2dc41b183d4872d3a500d2b9c9016e67ed95738a3624f4751a0cb4818fe71"},
+ {file = "black-23.9.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:13a2e4a93bb8ca74a749b6974925c27219bb3df4d42fc45e948a5d9feb5122b7"},
+ {file = "black-23.9.1-cp310-cp310-win_amd64.whl", hash = "sha256:adc3e4442eef57f99b5590b245a328aad19c99552e0bdc7f0b04db6656debd80"},
+ {file = "black-23.9.1-cp311-cp311-macosx_10_16_arm64.whl", hash = "sha256:8431445bf62d2a914b541da7ab3e2b4f3bc052d2ccbf157ebad18ea126efb91f"},
+ {file = "black-23.9.1-cp311-cp311-macosx_10_16_universal2.whl", hash = "sha256:8fc1ddcf83f996247505db6b715294eba56ea9372e107fd54963c7553f2b6dfe"},
+ {file = "black-23.9.1-cp311-cp311-macosx_10_16_x86_64.whl", hash = "sha256:7d30ec46de88091e4316b17ae58bbbfc12b2de05e069030f6b747dfc649ad186"},
+ {file = "black-23.9.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:031e8c69f3d3b09e1aa471a926a1eeb0b9071f80b17689a655f7885ac9325a6f"},
+ {file = "black-23.9.1-cp311-cp311-win_amd64.whl", hash = "sha256:538efb451cd50f43aba394e9ec7ad55a37598faae3348d723b59ea8e91616300"},
+ {file = "black-23.9.1-cp38-cp38-macosx_10_16_arm64.whl", hash = "sha256:638619a559280de0c2aa4d76f504891c9860bb8fa214267358f0a20f27c12948"},
+ {file = "black-23.9.1-cp38-cp38-macosx_10_16_universal2.whl", hash = "sha256:a732b82747235e0542c03bf352c126052c0fbc458d8a239a94701175b17d4855"},
+ {file = "black-23.9.1-cp38-cp38-macosx_10_16_x86_64.whl", hash = "sha256:cf3a4d00e4cdb6734b64bf23cd4341421e8953615cba6b3670453737a72ec204"},
+ {file = "black-23.9.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cf99f3de8b3273a8317681d8194ea222f10e0133a24a7548c73ce44ea1679377"},
+ {file = "black-23.9.1-cp38-cp38-win_amd64.whl", hash = "sha256:14f04c990259576acd093871e7e9b14918eb28f1866f91968ff5524293f9c573"},
+ {file = "black-23.9.1-cp39-cp39-macosx_10_16_arm64.whl", hash = "sha256:c619f063c2d68f19b2d7270f4cf3192cb81c9ec5bc5ba02df91471d0b88c4c5c"},
+ {file = "black-23.9.1-cp39-cp39-macosx_10_16_universal2.whl", hash = "sha256:6a3b50e4b93f43b34a9d3ef00d9b6728b4a722c997c99ab09102fd5efdb88325"},
+ {file = "black-23.9.1-cp39-cp39-macosx_10_16_x86_64.whl", hash = "sha256:c46767e8df1b7beefb0899c4a95fb43058fa8500b6db144f4ff3ca38eb2f6393"},
+ {file = "black-23.9.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:50254ebfa56aa46a9fdd5d651f9637485068a1adf42270148cd101cdf56e0ad9"},
+ {file = "black-23.9.1-cp39-cp39-win_amd64.whl", hash = "sha256:403397c033adbc45c2bd41747da1f7fc7eaa44efbee256b53842470d4ac5a70f"},
+ {file = "black-23.9.1-py3-none-any.whl", hash = "sha256:6ccd59584cc834b6d127628713e4b6b968e5f79572da66284532525a042549f9"},
+ {file = "black-23.9.1.tar.gz", hash = "sha256:24b6b3ff5c6d9ea08a8888f6977eae858e1f340d7260cf56d70a49823236b62d"},
]
[package.dependencies]
-aws-xray-sdk = {version = ">=2.8.0,<3.0.0", optional = true, markers = "extra == \"tracer\" or extra == \"all\""}
-fastjsonschema = {version = ">=2.14.5,<3.0.0", optional = true, markers = "extra == \"validation\" or extra == \"all\""}
-pydantic = {version = ">=1.8.2,<2.0.0", optional = true, markers = "extra == \"parser\" or extra == \"all\""}
-typing-extensions = ">=4.6.2,<5.0.0"
+click = ">=8.0.0"
+mypy-extensions = ">=0.4.3"
+packaging = ">=22.0"
+pathspec = ">=0.9.0"
+platformdirs = ">=2"
+tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""}
+typing-extensions = {version = ">=4.0.1", markers = "python_version < \"3.11\""}
[package.extras]
-all = ["aws-xray-sdk (>=2.8.0,<3.0.0)", "fastjsonschema (>=2.14.5,<3.0.0)", "pydantic (>=1.8.2,<2.0.0)"]
-aws-sdk = ["boto3 (>=1.20.32,<2.0.0)"]
-datadog = ["datadog-lambda (>=4.77.0,<5.0.0)"]
-parser = ["pydantic (>=1.8.2,<2.0.0)"]
-tracer = ["aws-xray-sdk (>=2.8.0,<3.0.0)"]
-validation = ["fastjsonschema (>=2.14.5,<3.0.0)"]
-
-[[package]]
-name = "aws-xray-sdk"
-version = "2.12.0"
-description = "The AWS X-Ray SDK for Python (the SDK) enables Python developers to record and emit information from within their applications to the AWS X-Ray service."
-category = "dev"
-optional = false
-python-versions = "*"
-files = [
- {file = "aws-xray-sdk-2.12.0.tar.gz", hash = "sha256:295afc237073a80956d7d4f27c31830edcb9a8ccca9ef8aa44990badef15e5b7"},
- {file = "aws_xray_sdk-2.12.0-py2.py3-none-any.whl", hash = "sha256:30886e23cc2daadc1c06a76f25b071205e84848419d1ddf097b62a565e156542"},
-]
-
-[package.dependencies]
-botocore = ">=1.11.3"
-wrapt = "*"
+colorama = ["colorama (>=0.4.3)"]
+d = ["aiohttp (>=3.7.4)"]
+jupyter = ["ipython (>=7.8.0)", "tokenize-rt (>=3.2.0)"]
+uvloop = ["uvloop (>=0.15.2)"]
[[package]]
name = "boto3"
-version = "1.28.50"
+version = "1.28.52"
description = "The AWS SDK for Python"
category = "dev"
optional = false
python-versions = ">= 3.7"
files = [
- {file = "boto3-1.28.50-py3-none-any.whl", hash = "sha256:cda98a2952cccb1db4208c53a1bba6585620fffa0ca05244827ca65884856d1f"},
- {file = "boto3-1.28.50.tar.gz", hash = "sha256:33062ab3801029ab7b2cb35b6bf4768715d13c5f9ea7d5dce22ace6219c1dc7a"},
+ {file = "boto3-1.28.52-py3-none-any.whl", hash = "sha256:1d36db102517d62c6968b3b0636303241f56859d12dd071def4882fc6e030b20"},
+ {file = "boto3-1.28.52.tar.gz", hash = "sha256:a34fc153cb2f6fb2f79a764286c967392e8aae9412381d943bddc576c4f7631a"},
]
[package.dependencies]
-botocore = ">=1.31.50,<1.32.0"
+botocore = ">=1.31.52,<1.32.0"
jmespath = ">=0.7.1,<2.0.0"
s3transfer = ">=0.6.0,<0.7.0"
@@ -155,14 +160,14 @@ crt = ["botocore[crt] (>=1.21.0,<2.0a0)"]
[[package]]
name = "botocore"
-version = "1.31.50"
+version = "1.31.52"
description = "Low-level, data-driven core of boto 3."
category = "dev"
optional = false
python-versions = ">= 3.7"
files = [
- {file = "botocore-1.31.50-py3-none-any.whl", hash = "sha256:5038a407783ea394aaf0671d1086cf55cc1e7c303e1fac244b76adc78cc7ef07"},
- {file = "botocore-1.31.50.tar.gz", hash = "sha256:a1343f2e38ea86e11247d61bd37a9d5656c16186f4a21b482c713589a054c605"},
+ {file = "botocore-1.31.52-py3-none-any.whl", hash = "sha256:46b0a75a38521aa6a75fddccb1542e002930e609d4e13516f40fef170d32e515"},
+ {file = "botocore-1.31.52.tar.gz", hash = "sha256:6d09881c5a8be34b497872ca3936f8757d886a6f42f2a8703411928189cfedc0"},
]
[package.dependencies]
@@ -373,6 +378,21 @@ files = [
{file = "charset_normalizer-3.2.0-py3-none-any.whl", hash = "sha256:8e098148dd37b4ce3baca71fb394c81dc5d9c7728c95df695d2dca218edf40e6"},
]
+[[package]]
+name = "click"
+version = "8.1.7"
+description = "Composable command line interface toolkit"
+category = "dev"
+optional = false
+python-versions = ">=3.7"
+files = [
+ {file = "click-8.1.7-py3-none-any.whl", hash = "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28"},
+ {file = "click-8.1.7.tar.gz", hash = "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de"},
+]
+
+[package.dependencies]
+colorama = {version = "*", markers = "platform_system == \"Windows\""}
+
[[package]]
name = "colorama"
version = "0.4.6"
@@ -469,35 +489,35 @@ toml = ["tomli"]
[[package]]
name = "cryptography"
-version = "41.0.3"
+version = "41.0.4"
description = "cryptography is a package which provides cryptographic recipes and primitives to Python developers."
category = "dev"
optional = false
python-versions = ">=3.7"
files = [
- {file = "cryptography-41.0.3-cp37-abi3-macosx_10_12_universal2.whl", hash = "sha256:652627a055cb52a84f8c448185922241dd5217443ca194d5739b44612c5e6507"},
- {file = "cryptography-41.0.3-cp37-abi3-macosx_10_12_x86_64.whl", hash = "sha256:8f09daa483aedea50d249ef98ed500569841d6498aa9c9f4b0531b9964658922"},
- {file = "cryptography-41.0.3-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4fd871184321100fb400d759ad0cddddf284c4b696568204d281c902fc7b0d81"},
- {file = "cryptography-41.0.3-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:84537453d57f55a50a5b6835622ee405816999a7113267739a1b4581f83535bd"},
- {file = "cryptography-41.0.3-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:3fb248989b6363906827284cd20cca63bb1a757e0a2864d4c1682a985e3dca47"},
- {file = "cryptography-41.0.3-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:42cb413e01a5d36da9929baa9d70ca90d90b969269e5a12d39c1e0d475010116"},
- {file = "cryptography-41.0.3-cp37-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:aeb57c421b34af8f9fe830e1955bf493a86a7996cc1338fe41b30047d16e962c"},
- {file = "cryptography-41.0.3-cp37-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:6af1c6387c531cd364b72c28daa29232162010d952ceb7e5ca8e2827526aceae"},
- {file = "cryptography-41.0.3-cp37-abi3-win32.whl", hash = "sha256:0d09fb5356f975974dbcb595ad2d178305e5050656affb7890a1583f5e02a306"},
- {file = "cryptography-41.0.3-cp37-abi3-win_amd64.whl", hash = "sha256:a983e441a00a9d57a4d7c91b3116a37ae602907a7618b882c8013b5762e80574"},
- {file = "cryptography-41.0.3-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:5259cb659aa43005eb55a0e4ff2c825ca111a0da1814202c64d28a985d33b087"},
- {file = "cryptography-41.0.3-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:67e120e9a577c64fe1f611e53b30b3e69744e5910ff3b6e97e935aeb96005858"},
- {file = "cryptography-41.0.3-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:7efe8041897fe7a50863e51b77789b657a133c75c3b094e51b5e4b5cec7bf906"},
- {file = "cryptography-41.0.3-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:ce785cf81a7bdade534297ef9e490ddff800d956625020ab2ec2780a556c313e"},
- {file = "cryptography-41.0.3-pp38-pypy38_pp73-macosx_10_12_x86_64.whl", hash = "sha256:57a51b89f954f216a81c9d057bf1a24e2f36e764a1ca9a501a6964eb4a6800dd"},
- {file = "cryptography-41.0.3-pp38-pypy38_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:4c2f0d35703d61002a2bbdcf15548ebb701cfdd83cdc12471d2bae80878a4207"},
- {file = "cryptography-41.0.3-pp38-pypy38_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:23c2d778cf829f7d0ae180600b17e9fceea3c2ef8b31a99e3c694cbbf3a24b84"},
- {file = "cryptography-41.0.3-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:95dd7f261bb76948b52a5330ba5202b91a26fbac13ad0e9fc8a3ac04752058c7"},
- {file = "cryptography-41.0.3-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:41d7aa7cdfded09b3d73a47f429c298e80796c8e825ddfadc84c8a7f12df212d"},
- {file = "cryptography-41.0.3-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:d0d651aa754ef58d75cec6edfbd21259d93810b73f6ec246436a21b7841908de"},
- {file = "cryptography-41.0.3-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:ab8de0d091acbf778f74286f4989cf3d1528336af1b59f3e5d2ebca8b5fe49e1"},
- {file = "cryptography-41.0.3-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:a74fbcdb2a0d46fe00504f571a2a540532f4c188e6ccf26f1f178480117b33c4"},
- {file = "cryptography-41.0.3.tar.gz", hash = "sha256:6d192741113ef5e30d89dcb5b956ef4e1578f304708701b8b73d38e3e1461f34"},
+ {file = "cryptography-41.0.4-cp37-abi3-macosx_10_12_universal2.whl", hash = "sha256:80907d3faa55dc5434a16579952ac6da800935cd98d14dbd62f6f042c7f5e839"},
+ {file = "cryptography-41.0.4-cp37-abi3-macosx_10_12_x86_64.whl", hash = "sha256:35c00f637cd0b9d5b6c6bd11b6c3359194a8eba9c46d4e875a3660e3b400005f"},
+ {file = "cryptography-41.0.4-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cecfefa17042941f94ab54f769c8ce0fe14beff2694e9ac684176a2535bf9714"},
+ {file = "cryptography-41.0.4-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e40211b4923ba5a6dc9769eab704bdb3fbb58d56c5b336d30996c24fcf12aadb"},
+ {file = "cryptography-41.0.4-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:23a25c09dfd0d9f28da2352503b23e086f8e78096b9fd585d1d14eca01613e13"},
+ {file = "cryptography-41.0.4-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:2ed09183922d66c4ec5fdaa59b4d14e105c084dd0febd27452de8f6f74704143"},
+ {file = "cryptography-41.0.4-cp37-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:5a0f09cefded00e648a127048119f77bc2b2ec61e736660b5789e638f43cc397"},
+ {file = "cryptography-41.0.4-cp37-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:9eeb77214afae972a00dee47382d2591abe77bdae166bda672fb1e24702a3860"},
+ {file = "cryptography-41.0.4-cp37-abi3-win32.whl", hash = "sha256:3b224890962a2d7b57cf5eeb16ccaafba6083f7b811829f00476309bce2fe0fd"},
+ {file = "cryptography-41.0.4-cp37-abi3-win_amd64.whl", hash = "sha256:c880eba5175f4307129784eca96f4e70b88e57aa3f680aeba3bab0e980b0f37d"},
+ {file = "cryptography-41.0.4-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:004b6ccc95943f6a9ad3142cfabcc769d7ee38a3f60fb0dddbfb431f818c3a67"},
+ {file = "cryptography-41.0.4-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:86defa8d248c3fa029da68ce61fe735432b047e32179883bdb1e79ed9bb8195e"},
+ {file = "cryptography-41.0.4-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:37480760ae08065437e6573d14be973112c9e6dcaf5f11d00147ee74f37a3829"},
+ {file = "cryptography-41.0.4-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:b5f4dfe950ff0479f1f00eda09c18798d4f49b98f4e2006d644b3301682ebdca"},
+ {file = "cryptography-41.0.4-pp38-pypy38_pp73-macosx_10_12_x86_64.whl", hash = "sha256:7e53db173370dea832190870e975a1e09c86a879b613948f09eb49324218c14d"},
+ {file = "cryptography-41.0.4-pp38-pypy38_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:5b72205a360f3b6176485a333256b9bcd48700fc755fef51c8e7e67c4b63e3ac"},
+ {file = "cryptography-41.0.4-pp38-pypy38_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:93530900d14c37a46ce3d6c9e6fd35dbe5f5601bf6b3a5c325c7bffc030344d9"},
+ {file = "cryptography-41.0.4-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:efc8ad4e6fc4f1752ebfb58aefece8b4e3c4cae940b0994d43649bdfce8d0d4f"},
+ {file = "cryptography-41.0.4-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:c3391bd8e6de35f6f1140e50aaeb3e2b3d6a9012536ca23ab0d9c35ec18c8a91"},
+ {file = "cryptography-41.0.4-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:0d9409894f495d465fe6fda92cb70e8323e9648af912d5b9141d616df40a87b8"},
+ {file = "cryptography-41.0.4-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:8ac4f9ead4bbd0bc8ab2d318f97d85147167a488be0e08814a37eb2f439d5cf6"},
+ {file = "cryptography-41.0.4-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:047c4603aeb4bbd8db2756e38f5b8bd7e94318c047cfe4efeb5d715e08b49311"},
+ {file = "cryptography-41.0.4.tar.gz", hash = "sha256:7febc3094125fc126a7f6fb1f420d0da639f3f32cb15c8ff0dc3997c4549f51a"},
]
[package.dependencies]
@@ -528,21 +548,6 @@ files = [
[package.extras]
test = ["pytest (>=6)"]
-[[package]]
-name = "fastjsonschema"
-version = "2.18.0"
-description = "Fastest Python implementation of JSON schema"
-category = "dev"
-optional = false
-python-versions = "*"
-files = [
- {file = "fastjsonschema-2.18.0-py3-none-any.whl", hash = "sha256:128039912a11a807068a7c87d0da36660afbfd7202780db26c4aa7153cfdc799"},
- {file = "fastjsonschema-2.18.0.tar.gz", hash = "sha256:e820349dd16f806e4bd1467a138dced9def4bc7d6213a34295272a6cac95b5bd"},
-]
-
-[package.extras]
-devel = ["colorama", "json-spec", "jsonschema", "pylint", "pytest", "pytest-benchmark", "pytest-cache", "validictory"]
-
[[package]]
name = "idna"
version = "3.4"
@@ -557,22 +562,22 @@ files = [
[[package]]
name = "importlib-resources"
-version = "6.0.1"
+version = "6.1.0"
description = "Read resources from Python packages"
category = "main"
optional = false
python-versions = ">=3.8"
files = [
- {file = "importlib_resources-6.0.1-py3-none-any.whl", hash = "sha256:134832a506243891221b88b4ae1213327eea96ceb4e407a00d790bb0626f45cf"},
- {file = "importlib_resources-6.0.1.tar.gz", hash = "sha256:4359457e42708462b9626a04657c6208ad799ceb41e5c58c57ffa0e6a098a5d4"},
+ {file = "importlib_resources-6.1.0-py3-none-any.whl", hash = "sha256:aa50258bbfa56d4e33fbd8aa3ef48ded10d1735f11532b8df95388cc6bdb7e83"},
+ {file = "importlib_resources-6.1.0.tar.gz", hash = "sha256:9d48dcccc213325e810fd723e7fbb45ccb39f6cf5c31f00cf2b965f5f10f3cb9"},
]
[package.dependencies]
zipp = {version = ">=3.1.0", markers = "python_version < \"3.10\""}
[package.extras]
-docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"]
-testing = ["pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy (>=0.9.1)", "pytest-ruff"]
+docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (<7.2.5)", "sphinx (>=3.5)", "sphinx-lint"]
+testing = ["pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy (>=0.9.1)", "pytest-ruff", "zipp (>=3.17)"]
[[package]]
name = "iniconfig"
@@ -618,14 +623,14 @@ files = [
[[package]]
name = "jsii"
-version = "1.88.0"
+version = "1.89.0"
description = "Python client for jsii runtime"
category = "main"
optional = false
python-versions = "~=3.7"
files = [
- {file = "jsii-1.88.0-py3-none-any.whl", hash = "sha256:b3888141c30b83a30bfbe03a877bbf8ae42f957b6ccca02bae448853debffaf8"},
- {file = "jsii-1.88.0.tar.gz", hash = "sha256:a59e0f962589dcc741d2bcf2a7b4c4a927a29d3f9a2804a192c734e2e3275018"},
+ {file = "jsii-1.89.0-py3-none-any.whl", hash = "sha256:20a463e8533eded656b285f532e5468a414c48ab083cf0cf93a86d593f0c36b8"},
+ {file = "jsii-1.89.0.tar.gz", hash = "sha256:6edbb79afc0b7407cb64e9dd0f27b512279201307c16dd9ae72462b3cbd09970"},
]
[package.dependencies]
@@ -746,6 +751,18 @@ server = ["PyYAML (>=5.1)", "aws-xray-sdk (>=0.93,!=0.96)", "cfn-lint (>=0.40.0)
ssm = ["PyYAML (>=5.1)"]
xray = ["aws-xray-sdk (>=0.93,!=0.96)", "setuptools"]
+[[package]]
+name = "mypy-extensions"
+version = "1.0.0"
+description = "Type system extensions for programs checked with the mypy type checker."
+category = "dev"
+optional = false
+python-versions = ">=3.5"
+files = [
+ {file = "mypy_extensions-1.0.0-py3-none-any.whl", hash = "sha256:4392f6c0eb8a5668a69e23d168ffa70f0be9ccfd32b5cc2d26a34ae5b844552d"},
+ {file = "mypy_extensions-1.0.0.tar.gz", hash = "sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782"},
+]
+
[[package]]
name = "packaging"
version = "23.1"
@@ -770,25 +787,53 @@ files = [
{file = "pastel-0.2.1.tar.gz", hash = "sha256:e6581ac04e973cac858828c6202c1e1e81fee1dc7de7683f3e1ffe0bfd8a573d"},
]
+[[package]]
+name = "pathspec"
+version = "0.11.2"
+description = "Utility library for gitignore style pattern matching of file paths."
+category = "dev"
+optional = false
+python-versions = ">=3.7"
+files = [
+ {file = "pathspec-0.11.2-py3-none-any.whl", hash = "sha256:1d6ed233af05e679efb96b1851550ea95bbb64b7c490b0f5aa52996c11e92a20"},
+ {file = "pathspec-0.11.2.tar.gz", hash = "sha256:e0d8d0ac2f12da61956eb2306b69f9469b42f4deb0f3cb6ed47b9cce9996ced3"},
+]
+
[[package]]
name = "pepperize-cdk-organizations"
-version = "0.7.680"
+version = "0.7.687"
description = "Manage AWS organizations, organizational units (OU), accounts and service control policies (SCP)."
category = "main"
optional = false
python-versions = "~=3.7"
files = [
- {file = "pepperize.cdk-organizations-0.7.680.tar.gz", hash = "sha256:d975d957b1149c00038eecfedff334c5fd406ebc60b0657ba6a212068fc3f01b"},
- {file = "pepperize.cdk_organizations-0.7.680-py3-none-any.whl", hash = "sha256:94404b108726533e07cdd0577d7d97116e2a526eacf79ac020d731acbc527aa3"},
+ {file = "pepperize.cdk-organizations-0.7.687.tar.gz", hash = "sha256:f3cce8add55c84a5ef6afb2ed5b61f0cca8f014708c1b63c6c3f348bc9dacd58"},
+ {file = "pepperize.cdk_organizations-0.7.687-py3-none-any.whl", hash = "sha256:200ce977fe178c844b4ac1fdffdac2f32ca88be1f0e71eec103011ed33c7125f"},
]
[package.dependencies]
aws-cdk-lib = ">=2.37.1,<3.0.0"
constructs = ">=10.0.5,<11.0.0"
-jsii = ">=1.88.0,<2.0.0"
+jsii = ">=1.89.0,<2.0.0"
publication = ">=0.0.3"
typeguard = ">=2.13.3,<2.14.0"
+[[package]]
+name = "platformdirs"
+version = "3.10.0"
+description = "A small Python package for determining appropriate platform-specific dirs, e.g. a \"user data dir\"."
+category = "dev"
+optional = false
+python-versions = ">=3.7"
+files = [
+ {file = "platformdirs-3.10.0-py3-none-any.whl", hash = "sha256:d7c24979f292f916dc9cbf8648319032f551ea8c49a4c9bf2fb556a02070ec1d"},
+ {file = "platformdirs-3.10.0.tar.gz", hash = "sha256:b45696dab2d7cc691a3226759c0d3b00c47c8b6e293d96f6436f733303f77f6d"},
+]
+
+[package.extras]
+docs = ["furo (>=2023.7.26)", "proselint (>=0.13)", "sphinx (>=7.1.1)", "sphinx-autodoc-typehints (>=1.24)"]
+test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.4)", "pytest-cov (>=4.1)", "pytest-mock (>=3.11.1)"]
+
[[package]]
name = "pluggy"
version = "1.3.0"
@@ -848,59 +893,6 @@ files = [
{file = "pycparser-2.21.tar.gz", hash = "sha256:e644fdec12f7872f86c58ff790da456218b10f863970249516d60a5eaca77206"},
]
-[[package]]
-name = "pydantic"
-version = "1.10.12"
-description = "Data validation and settings management using python type hints"
-category = "dev"
-optional = false
-python-versions = ">=3.7"
-files = [
- {file = "pydantic-1.10.12-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a1fcb59f2f355ec350073af41d927bf83a63b50e640f4dbaa01053a28b7a7718"},
- {file = "pydantic-1.10.12-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:b7ccf02d7eb340b216ec33e53a3a629856afe1c6e0ef91d84a4e6f2fb2ca70fe"},
- {file = "pydantic-1.10.12-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8fb2aa3ab3728d950bcc885a2e9eff6c8fc40bc0b7bb434e555c215491bcf48b"},
- {file = "pydantic-1.10.12-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:771735dc43cf8383959dc9b90aa281f0b6092321ca98677c5fb6125a6f56d58d"},
- {file = "pydantic-1.10.12-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:ca48477862372ac3770969b9d75f1bf66131d386dba79506c46d75e6b48c1e09"},
- {file = "pydantic-1.10.12-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:a5e7add47a5b5a40c49b3036d464e3c7802f8ae0d1e66035ea16aa5b7a3923ed"},
- {file = "pydantic-1.10.12-cp310-cp310-win_amd64.whl", hash = "sha256:e4129b528c6baa99a429f97ce733fff478ec955513630e61b49804b6cf9b224a"},
- {file = "pydantic-1.10.12-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:b0d191db0f92dfcb1dec210ca244fdae5cbe918c6050b342d619c09d31eea0cc"},
- {file = "pydantic-1.10.12-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:795e34e6cc065f8f498c89b894a3c6da294a936ee71e644e4bd44de048af1405"},
- {file = "pydantic-1.10.12-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:69328e15cfda2c392da4e713443c7dbffa1505bc9d566e71e55abe14c97ddc62"},
- {file = "pydantic-1.10.12-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2031de0967c279df0d8a1c72b4ffc411ecd06bac607a212892757db7462fc494"},
- {file = "pydantic-1.10.12-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:ba5b2e6fe6ca2b7e013398bc7d7b170e21cce322d266ffcd57cca313e54fb246"},
- {file = "pydantic-1.10.12-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:2a7bac939fa326db1ab741c9d7f44c565a1d1e80908b3797f7f81a4f86bc8d33"},
- {file = "pydantic-1.10.12-cp311-cp311-win_amd64.whl", hash = "sha256:87afda5539d5140cb8ba9e8b8c8865cb5b1463924d38490d73d3ccfd80896b3f"},
- {file = "pydantic-1.10.12-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:549a8e3d81df0a85226963611950b12d2d334f214436a19537b2efed61b7639a"},
- {file = "pydantic-1.10.12-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:598da88dfa127b666852bef6d0d796573a8cf5009ffd62104094a4fe39599565"},
- {file = "pydantic-1.10.12-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ba5c4a8552bff16c61882db58544116d021d0b31ee7c66958d14cf386a5b5350"},
- {file = "pydantic-1.10.12-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:c79e6a11a07da7374f46970410b41d5e266f7f38f6a17a9c4823db80dadf4303"},
- {file = "pydantic-1.10.12-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:ab26038b8375581dc832a63c948f261ae0aa21f1d34c1293469f135fa92972a5"},
- {file = "pydantic-1.10.12-cp37-cp37m-win_amd64.whl", hash = "sha256:e0a16d274b588767602b7646fa05af2782576a6cf1022f4ba74cbb4db66f6ca8"},
- {file = "pydantic-1.10.12-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:6a9dfa722316f4acf4460afdf5d41d5246a80e249c7ff475c43a3a1e9d75cf62"},
- {file = "pydantic-1.10.12-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:a73f489aebd0c2121ed974054cb2759af8a9f747de120acd2c3394cf84176ccb"},
- {file = "pydantic-1.10.12-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6b30bcb8cbfccfcf02acb8f1a261143fab622831d9c0989707e0e659f77a18e0"},
- {file = "pydantic-1.10.12-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2fcfb5296d7877af406ba1547dfde9943b1256d8928732267e2653c26938cd9c"},
- {file = "pydantic-1.10.12-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:2f9a6fab5f82ada41d56b0602606a5506aab165ca54e52bc4545028382ef1c5d"},
- {file = "pydantic-1.10.12-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:dea7adcc33d5d105896401a1f37d56b47d443a2b2605ff8a969a0ed5543f7e33"},
- {file = "pydantic-1.10.12-cp38-cp38-win_amd64.whl", hash = "sha256:1eb2085c13bce1612da8537b2d90f549c8cbb05c67e8f22854e201bde5d98a47"},
- {file = "pydantic-1.10.12-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:ef6c96b2baa2100ec91a4b428f80d8f28a3c9e53568219b6c298c1125572ebc6"},
- {file = "pydantic-1.10.12-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:6c076be61cd0177a8433c0adcb03475baf4ee91edf5a4e550161ad57fc90f523"},
- {file = "pydantic-1.10.12-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2d5a58feb9a39f481eda4d5ca220aa8b9d4f21a41274760b9bc66bfd72595b86"},
- {file = "pydantic-1.10.12-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e5f805d2d5d0a41633651a73fa4ecdd0b3d7a49de4ec3fadf062fe16501ddbf1"},
- {file = "pydantic-1.10.12-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:1289c180abd4bd4555bb927c42ee42abc3aee02b0fb2d1223fb7c6e5bef87dbe"},
- {file = "pydantic-1.10.12-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5d1197e462e0364906cbc19681605cb7c036f2475c899b6f296104ad42b9f5fb"},
- {file = "pydantic-1.10.12-cp39-cp39-win_amd64.whl", hash = "sha256:fdbdd1d630195689f325c9ef1a12900524dceb503b00a987663ff4f58669b93d"},
- {file = "pydantic-1.10.12-py3-none-any.whl", hash = "sha256:b749a43aa51e32839c9d71dc67eb1e4221bb04af1033a32e3923d46f9effa942"},
- {file = "pydantic-1.10.12.tar.gz", hash = "sha256:0fe8a415cea8f340e7a9af9c54fc71a649b43e8ca3cc732986116b3cb135d303"},
-]
-
-[package.dependencies]
-typing-extensions = ">=4.2.0"
-
-[package.extras]
-dotenv = ["python-dotenv (>=0.10.4)"]
-email = ["email-validator (>=1.0.3)"]
-
[[package]]
name = "pytest"
version = "7.4.2"
@@ -1177,91 +1169,6 @@ MarkupSafe = ">=2.1.1"
[package.extras]
watchdog = ["watchdog (>=2.3)"]
-[[package]]
-name = "wrapt"
-version = "1.15.0"
-description = "Module for decorators, wrappers and monkey patching."
-category = "dev"
-optional = false
-python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7"
-files = [
- {file = "wrapt-1.15.0-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:ca1cccf838cd28d5a0883b342474c630ac48cac5df0ee6eacc9c7290f76b11c1"},
- {file = "wrapt-1.15.0-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:e826aadda3cae59295b95343db8f3d965fb31059da7de01ee8d1c40a60398b29"},
- {file = "wrapt-1.15.0-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:5fc8e02f5984a55d2c653f5fea93531e9836abbd84342c1d1e17abc4a15084c2"},
- {file = "wrapt-1.15.0-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:96e25c8603a155559231c19c0349245eeb4ac0096fe3c1d0be5c47e075bd4f46"},
- {file = "wrapt-1.15.0-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:40737a081d7497efea35ab9304b829b857f21558acfc7b3272f908d33b0d9d4c"},
- {file = "wrapt-1.15.0-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:f87ec75864c37c4c6cb908d282e1969e79763e0d9becdfe9fe5473b7bb1e5f09"},
- {file = "wrapt-1.15.0-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:1286eb30261894e4c70d124d44b7fd07825340869945c79d05bda53a40caa079"},
- {file = "wrapt-1.15.0-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:493d389a2b63c88ad56cdc35d0fa5752daac56ca755805b1b0c530f785767d5e"},
- {file = "wrapt-1.15.0-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:58d7a75d731e8c63614222bcb21dd992b4ab01a399f1f09dd82af17bbfc2368a"},
- {file = "wrapt-1.15.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:21f6d9a0d5b3a207cdf7acf8e58d7d13d463e639f0c7e01d82cdb671e6cb7923"},
- {file = "wrapt-1.15.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ce42618f67741d4697684e501ef02f29e758a123aa2d669e2d964ff734ee00ee"},
- {file = "wrapt-1.15.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:41d07d029dd4157ae27beab04d22b8e261eddfc6ecd64ff7000b10dc8b3a5727"},
- {file = "wrapt-1.15.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:54accd4b8bc202966bafafd16e69da9d5640ff92389d33d28555c5fd4f25ccb7"},
- {file = "wrapt-1.15.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2fbfbca668dd15b744418265a9607baa970c347eefd0db6a518aaf0cfbd153c0"},
- {file = "wrapt-1.15.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:76e9c727a874b4856d11a32fb0b389afc61ce8aaf281ada613713ddeadd1cfec"},
- {file = "wrapt-1.15.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:e20076a211cd6f9b44a6be58f7eeafa7ab5720eb796975d0c03f05b47d89eb90"},
- {file = "wrapt-1.15.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:a74d56552ddbde46c246b5b89199cb3fd182f9c346c784e1a93e4dc3f5ec9975"},
- {file = "wrapt-1.15.0-cp310-cp310-win32.whl", hash = "sha256:26458da5653aa5b3d8dc8b24192f574a58984c749401f98fff994d41d3f08da1"},
- {file = "wrapt-1.15.0-cp310-cp310-win_amd64.whl", hash = "sha256:75760a47c06b5974aa5e01949bf7e66d2af4d08cb8c1d6516af5e39595397f5e"},
- {file = "wrapt-1.15.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:ba1711cda2d30634a7e452fc79eabcadaffedf241ff206db2ee93dd2c89a60e7"},
- {file = "wrapt-1.15.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:56374914b132c702aa9aa9959c550004b8847148f95e1b824772d453ac204a72"},
- {file = "wrapt-1.15.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a89ce3fd220ff144bd9d54da333ec0de0399b52c9ac3d2ce34b569cf1a5748fb"},
- {file = "wrapt-1.15.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3bbe623731d03b186b3d6b0d6f51865bf598587c38d6f7b0be2e27414f7f214e"},
- {file = "wrapt-1.15.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3abbe948c3cbde2689370a262a8d04e32ec2dd4f27103669a45c6929bcdbfe7c"},
- {file = "wrapt-1.15.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:b67b819628e3b748fd3c2192c15fb951f549d0f47c0449af0764d7647302fda3"},
- {file = "wrapt-1.15.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:7eebcdbe3677e58dd4c0e03b4f2cfa346ed4049687d839adad68cc38bb559c92"},
- {file = "wrapt-1.15.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:74934ebd71950e3db69960a7da29204f89624dde411afbfb3b4858c1409b1e98"},
- {file = "wrapt-1.15.0-cp311-cp311-win32.whl", hash = "sha256:bd84395aab8e4d36263cd1b9308cd504f6cf713b7d6d3ce25ea55670baec5416"},
- {file = "wrapt-1.15.0-cp311-cp311-win_amd64.whl", hash = "sha256:a487f72a25904e2b4bbc0817ce7a8de94363bd7e79890510174da9d901c38705"},
- {file = "wrapt-1.15.0-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:4ff0d20f2e670800d3ed2b220d40984162089a6e2c9646fdb09b85e6f9a8fc29"},
- {file = "wrapt-1.15.0-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:9ed6aa0726b9b60911f4aed8ec5b8dd7bf3491476015819f56473ffaef8959bd"},
- {file = "wrapt-1.15.0-cp35-cp35m-manylinux2010_i686.whl", hash = "sha256:896689fddba4f23ef7c718279e42f8834041a21342d95e56922e1c10c0cc7afb"},
- {file = "wrapt-1.15.0-cp35-cp35m-manylinux2010_x86_64.whl", hash = "sha256:75669d77bb2c071333417617a235324a1618dba66f82a750362eccbe5b61d248"},
- {file = "wrapt-1.15.0-cp35-cp35m-win32.whl", hash = "sha256:fbec11614dba0424ca72f4e8ba3c420dba07b4a7c206c8c8e4e73f2e98f4c559"},
- {file = "wrapt-1.15.0-cp35-cp35m-win_amd64.whl", hash = "sha256:fd69666217b62fa5d7c6aa88e507493a34dec4fa20c5bd925e4bc12fce586639"},
- {file = "wrapt-1.15.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:b0724f05c396b0a4c36a3226c31648385deb6a65d8992644c12a4963c70326ba"},
- {file = "wrapt-1.15.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bbeccb1aa40ab88cd29e6c7d8585582c99548f55f9b2581dfc5ba68c59a85752"},
- {file = "wrapt-1.15.0-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:38adf7198f8f154502883242f9fe7333ab05a5b02de7d83aa2d88ea621f13364"},
- {file = "wrapt-1.15.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:578383d740457fa790fdf85e6d346fda1416a40549fe8db08e5e9bd281c6a475"},
- {file = "wrapt-1.15.0-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:a4cbb9ff5795cd66f0066bdf5947f170f5d63a9274f99bdbca02fd973adcf2a8"},
- {file = "wrapt-1.15.0-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:af5bd9ccb188f6a5fdda9f1f09d9f4c86cc8a539bd48a0bfdc97723970348418"},
- {file = "wrapt-1.15.0-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:b56d5519e470d3f2fe4aa7585f0632b060d532d0696c5bdfb5e8319e1d0f69a2"},
- {file = "wrapt-1.15.0-cp36-cp36m-win32.whl", hash = "sha256:77d4c1b881076c3ba173484dfa53d3582c1c8ff1f914c6461ab70c8428b796c1"},
- {file = "wrapt-1.15.0-cp36-cp36m-win_amd64.whl", hash = "sha256:077ff0d1f9d9e4ce6476c1a924a3332452c1406e59d90a2cf24aeb29eeac9420"},
- {file = "wrapt-1.15.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:5c5aa28df055697d7c37d2099a7bc09f559d5053c3349b1ad0c39000e611d317"},
- {file = "wrapt-1.15.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3a8564f283394634a7a7054b7983e47dbf39c07712d7b177b37e03f2467a024e"},
- {file = "wrapt-1.15.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:780c82a41dc493b62fc5884fb1d3a3b81106642c5c5c78d6a0d4cbe96d62ba7e"},
- {file = "wrapt-1.15.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e169e957c33576f47e21864cf3fc9ff47c223a4ebca8960079b8bd36cb014fd0"},
- {file = "wrapt-1.15.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:b02f21c1e2074943312d03d243ac4388319f2456576b2c6023041c4d57cd7019"},
- {file = "wrapt-1.15.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:f2e69b3ed24544b0d3dbe2c5c0ba5153ce50dcebb576fdc4696d52aa22db6034"},
- {file = "wrapt-1.15.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:d787272ed958a05b2c86311d3a4135d3c2aeea4fc655705f074130aa57d71653"},
- {file = "wrapt-1.15.0-cp37-cp37m-win32.whl", hash = "sha256:02fce1852f755f44f95af51f69d22e45080102e9d00258053b79367d07af39c0"},
- {file = "wrapt-1.15.0-cp37-cp37m-win_amd64.whl", hash = "sha256:abd52a09d03adf9c763d706df707c343293d5d106aea53483e0ec8d9e310ad5e"},
- {file = "wrapt-1.15.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:cdb4f085756c96a3af04e6eca7f08b1345e94b53af8921b25c72f096e704e145"},
- {file = "wrapt-1.15.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:230ae493696a371f1dbffaad3dafbb742a4d27a0afd2b1aecebe52b740167e7f"},
- {file = "wrapt-1.15.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:63424c681923b9f3bfbc5e3205aafe790904053d42ddcc08542181a30a7a51bd"},
- {file = "wrapt-1.15.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d6bcbfc99f55655c3d93feb7ef3800bd5bbe963a755687cbf1f490a71fb7794b"},
- {file = "wrapt-1.15.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c99f4309f5145b93eca6e35ac1a988f0dc0a7ccf9ccdcd78d3c0adf57224e62f"},
- {file = "wrapt-1.15.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:b130fe77361d6771ecf5a219d8e0817d61b236b7d8b37cc045172e574ed219e6"},
- {file = "wrapt-1.15.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:96177eb5645b1c6985f5c11d03fc2dbda9ad24ec0f3a46dcce91445747e15094"},
- {file = "wrapt-1.15.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d5fe3e099cf07d0fb5a1e23d399e5d4d1ca3e6dfcbe5c8570ccff3e9208274f7"},
- {file = "wrapt-1.15.0-cp38-cp38-win32.whl", hash = "sha256:abd8f36c99512755b8456047b7be10372fca271bf1467a1caa88db991e7c421b"},
- {file = "wrapt-1.15.0-cp38-cp38-win_amd64.whl", hash = "sha256:b06fa97478a5f478fb05e1980980a7cdf2712015493b44d0c87606c1513ed5b1"},
- {file = "wrapt-1.15.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:2e51de54d4fb8fb50d6ee8327f9828306a959ae394d3e01a1ba8b2f937747d86"},
- {file = "wrapt-1.15.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:0970ddb69bba00670e58955f8019bec4a42d1785db3faa043c33d81de2bf843c"},
- {file = "wrapt-1.15.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:76407ab327158c510f44ded207e2f76b657303e17cb7a572ffe2f5a8a48aa04d"},
- {file = "wrapt-1.15.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cd525e0e52a5ff16653a3fc9e3dd827981917d34996600bbc34c05d048ca35cc"},
- {file = "wrapt-1.15.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9d37ac69edc5614b90516807de32d08cb8e7b12260a285ee330955604ed9dd29"},
- {file = "wrapt-1.15.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:078e2a1a86544e644a68422f881c48b84fef6d18f8c7a957ffd3f2e0a74a0d4a"},
- {file = "wrapt-1.15.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:2cf56d0e237280baed46f0b5316661da892565ff58309d4d2ed7dba763d984b8"},
- {file = "wrapt-1.15.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:7dc0713bf81287a00516ef43137273b23ee414fe41a3c14be10dd95ed98a2df9"},
- {file = "wrapt-1.15.0-cp39-cp39-win32.whl", hash = "sha256:46ed616d5fb42f98630ed70c3529541408166c22cdfd4540b88d5f21006b0eff"},
- {file = "wrapt-1.15.0-cp39-cp39-win_amd64.whl", hash = "sha256:eef4d64c650f33347c1f9266fa5ae001440b232ad9b98f1f43dfe7a79435c0a6"},
- {file = "wrapt-1.15.0-py3-none-any.whl", hash = "sha256:64b1df0f83706b4ef4cfb4fb0e4c2669100fd7ecacfb59e091fad300d4e04640"},
- {file = "wrapt-1.15.0.tar.gz", hash = "sha256:d06730c6aed78cee4126234cf2d071e01b44b915e725a6cb439a879ec9754a3a"},
-]
-
[[package]]
name = "xmltodict"
version = "0.13.0"
@@ -1293,4 +1200,4 @@ testing = ["big-O", "jaraco.functools", "jaraco.itertools", "more-itertools", "p
[metadata]
lock-version = "2.0"
python-versions = "^3.9"
-content-hash = "865881a9886b3af42b10e3f8da3059301d63e2e24b84937ea4bc1204314c304c"
+content-hash = "3f12c87063ebe3f7c8e2b1f4c5ab3fb67b0449dd0e88d3fdf8583f2295950512"
diff --git a/pyproject.toml b/pyproject.toml
index 122af40..18b48ec 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -13,13 +13,13 @@ constructs = ">=10.0.0,<11.0.0"
pepperize-cdk-organizations = "^0.7.680"
[tool.poetry.group.dev.dependencies]
-aws-lambda-powertools = {extras = ["all"], version = "^2.16.2"}
-boto3 = "^1.26.153"
poethepoet = "^0.20.0"
+black = "^23.9.1"
pytest = "^7.3.2"
pytest-mock = "^3.11.1"
coverage = "^7.2.7"
moto = "^4.1.11"
+boto3 = "^1.26.153"
[tool.pytest.ini_options]
minversion = "6.0"
@@ -33,9 +33,9 @@ build-backend = "poetry.core.masonry.api"
[tool.poe.tasks]
test-unit = ["_test_unit", "_coverage_html"]
-test-unit-cdk = ["_test_unit_cdk", "_coverage_html"]
+black-format = "black ."
+black-check = "black . --check --diff -v"
_test_unit = "coverage run -m pytest tests/unit"
-_test_unit_cdk = "coverage run -m pytest tests/unit/cdk"
_coverage_html = "coverage html"
[tool.coverage.run]
diff --git a/tests/unit/test_synth_success.py b/tests/unit/test_synth_success.py
new file mode 100644
index 0000000..cb2af79
--- /dev/null
+++ b/tests/unit/test_synth_success.py
@@ -0,0 +1,29 @@
+from aws_cdk import aws_sns as sns
+import aws_cdk as cdk
+from aws_cdk.assertions import Template
+
+from cdk.stacks.cdk_organization import OrganizationStack
+
+
+def test_synthesizes_properly():
+ app = cdk.App()
+
+ # Create the TestOrganizationStack with sample params
+ deployment_env = "prod"
+ main_resources_name = "test-organization"
+ state_machine_stack = OrganizationStack(
+ app,
+ main_resources_name,
+ deployment_env,
+ )
+
+ # Prepare the stack for assertions.
+ template = Template.from_stack(state_machine_stack)
+
+ template.has_output(
+ "DeploymentEnvironment",
+ {
+ "Description": "Deployment environment",
+ "Value": deployment_env,
+ },
+ )