diff --git a/.gitignore b/.gitignore index 53fe4cf..d2eab15 100644 --- a/.gitignore +++ b/.gitignore @@ -155,3 +155,5 @@ Thumbs.db # pycharm .idea .venv + +.env \ No newline at end of file diff --git a/Makefile b/Makefile index 58a7516..14d22ed 100644 --- a/Makefile +++ b/Makefile @@ -28,5 +28,8 @@ lint: up: @$(ACTIVATE) AWS_PROFILE=$(PROFILE) pulumi up --stack juno +down: + @$(ACTIVATE) AWS_PROFILE=$(PROFILE) pulumi destroy --stack juno + refresh: @$(ACTIVATE) PULUMI_K8S_DELETE_UNREACHABLE=true AWS_PROFILE=$(PROFILE) pulumi refresh --stack juno diff --git a/__main__.py b/__main__.py index b92ca95..33ed021 100644 --- a/__main__.py +++ b/__main__.py @@ -1,6 +1,8 @@ """ Juno Innovations - EKS Infrastructure for Orion """ +from dotenv import load_dotenv +load_dotenv() # local from src import JunoAccount, JunoRegion, Cluster, set_repositories, set_profile, set_session @@ -39,6 +41,48 @@ ]) + + + +# account in standalone in personal setup +# Steps to create a role with the option to select a trusted entity (current account or remote account): +# +# 1. Navigate to the IAM Console: +# Open the AWS Management Console, go to the IAM (Identity and Access Management) service, +# and select "Roles" from the left-hand navigation pane. Click on the "Create role" button +# to start the role creation process. +# +# 2. Select Trusted Entity: +# Choose the type of trusted entity for the role. You can select "AWS account" to specify +# either the current account or a remote account. If you choose "Another AWS account," you +# will need to enter the Account ID of the remote account. +# +# 3. Define Permissions: +# Attach the necessary permissions policies to the role. These policies define what actions +# the role can perform. Make sure that the define role can create VPC , Nodegroup , EKS , internet gateway Security group and IAM roles with the account +# +# 4. Configure Role Settings: +# Provide a name and description for the role, and review the trust policy. The trust policy +# specifies which entities (accounts) are allowed to assume the role + + + +# Those value are necessary on user account without organization role +# But is usefull for standolone practice of when someone grant an assume role to their account +assume_role_name = "JunoAdmin" + + +# Stand Alone Example For personal account not link to an organization +#with JunoAccount("deployment_account_name" , admin_role=assume_role_name ): # this is the account that will be used to deploy the clusters and also the the role it will assume at creation +# with JunoRegion("us-east-1", ecr_master=True , admin_role=assume_role_name ): # this is the region that the clusters will be deployed to it need the assume role name to follow along an do impersonation +# pass + +# Stand Alone Example with permission to assume another oganization roles +#with JunoAccount("deployment_account_name" , account_id="changemetospecificaccountid" , admin_role=assume_role_name ): # this is the account that will be used to deploy the clusters and also the the role it will assume at creation +# with JunoRegion("us-east-1", ecr_master=True , admin_role=assume_role_name ): # this is the region that the clusters will be deployed to it need the assume role name to follow along an do impersonation +# pass + + # account and regional deployments with JunoAccount("deployment_account_name"): # this is the account that will be used to deploy the clusters with JunoRegion("us-east-1", ecr_master=True): # this is the region that the clusters will be deployed to @@ -50,8 +94,8 @@ # name="service", # instances=["c6a.xlarge", "t3.xlarge"], # capacity_type=cluster.CapacityType.SPOT, - # minimum=1, - # size=1, + # minimum=2, + # size=2, # maximum=5, # labels={ # "juno-innovations.com/service": "true" diff --git a/requirements.txt b/requirements.txt index cc0bc18..fdb692e 100644 --- a/requirements.txt +++ b/requirements.txt @@ -19,3 +19,5 @@ ruff==0.3.5 semver==2.13.0 six==1.16.0 urllib3==2.2.1 +boto3 +python-dotenv \ No newline at end of file diff --git a/src/context/account.py b/src/context/account.py index e4dcd76..e8ae442 100644 --- a/src/context/account.py +++ b/src/context/account.py @@ -3,8 +3,8 @@ """ # 3rd -from pulumi_aws.iam import User, UserPolicyAttachment, AccessKey -from pulumi import get_stack, InvokeOptions, ResourceOptions +import boto3 +from pulumi import get_stack, InvokeOptions import pulumi_aws as aws # local @@ -13,7 +13,11 @@ from .session import get_session # Juno org -organization = aws.organizations.get_organization() + +# Get The Account ID for the organization +def get_current_account_id(): + org = aws.organizations.get_organization() + return org.master_account_id # account hooks # these are functions that will be called when the account is initialized @@ -31,16 +35,17 @@ class JunoAccount: def set_root_account(account): JunoAccount.ROOT_ACCOUNT = account - def __init__(self, account: str): + def __init__(self, account: str, admin_role: str = "OrganizationAccountAccessRole", account_id: str = None): # instance variables self.account = "root" if account == JunoAccount.ROOT_ACCOUNT else account - self.account_object = [acct for acct in organization.accounts if acct.name == account][0] - self.account_id = self.account_object.id - + + # Get user ID if account not specified + self.account_id = account_id if account_id else get_current_account_id() + args = dict(allowed_account_ids=[self.account_id]) if self.account != "root": args["assume_role"] = aws.ProviderAssumeRoleArgs( - role_arn=f"arn:aws:iam::{self.account_id}:role/OrganizationAccountAccessRole", + role_arn=f"arn:aws:iam::{self.account_id}:role/{admin_role}", session_name=get_session(), ) diff --git a/src/context/region.py b/src/context/region.py index e398a83..1653916 100644 --- a/src/context/region.py +++ b/src/context/region.py @@ -3,6 +3,7 @@ """ # 3rd +import boto3 from pulumi import ResourceOptions, get_stack import pulumi_aws as aws @@ -22,7 +23,7 @@ class JunoRegion: - def __init__(self, region: str, ecr_master: bool = False, ecr_sync: bool = False): + def __init__(self, region: str, ecr_master: bool = False, ecr_sync: bool = False , admin_role: str = "OrganizationAccountAccessRole"): account = get_account() # instance variables @@ -32,7 +33,7 @@ def __init__(self, region: str, ecr_master: bool = False, ecr_sync: bool = False self.account = account.account self.context_only = False self.account_id = account.account_id - self.role_arn = f"arn:aws:iam::{self.account_id}:role/OrganizationAccountAccessRole" + self.role_arn = f"arn:aws:iam::{self.account_id}:role/{admin_role}" args = dict(profile=get_profile(), allowed_account_ids=[self.account_id], region=region) if self.account != "root":