from diagrams.aws.network import ELB from diagrams.aws.database import Redshift from diagrams.aws.integration import SQS from diagrams.aws.storage import S3 from diagrams.aws.security import WAF from diagrams.aws.database import Aurora with Diagram("Infra as <Code> - Sistemas em paralelo", show=True): with Cluster("Infra as <Code> - Sistemas em paralelo"): with Cluster("Front-end"): front_end = [ EC2("Front-end-01"), EC2("Front-end-02"), EC2("Front-end-03") ] with Cluster("Back-end"): back_end = [ EC2("Back-end-01"), EC2("Back-end-02"), EC2("Back-end-03") ] waf = WAF("WAF") db = Aurora("DB") fe_lb = ELB("Front-end-LB") be_lb = ELB("Back-end-LB") waf >> fe_lb >> front_end >> be_lb >> back_end >> db
with Diagram("Static Website on Amazon S3 ", filename="diagram", show=False, graph_attr=graph_attr): users = Users() with Cluster("AWS"): security = Cognito("Cognito") gateway = APIGateway("Gateway") route = Route53("Route53") db = DDB("DynamoDB") email_service = SES("SES") monitoring = Cloudwatch("AWS CloudWatch ") firewall = WAF("AWS WAF") identity = IAM("AWS IAM") with Cluster("CDN"): cdn = S3("S3") >> CF("CloudFront CDN") with Cluster("Functions") as xyz: func_send_mail = Lambda("Send Email") func_store_data = Lambda("Store Data") functions = [func_send_mail, func_store_data] gateway >> Edge() << functions functions >> Edge() << identity func_send_mail >> Edge() >> email_service >> users func_store_data - Edge() - db
# diagram.py # Needs diagrams from pip and graphwiz installed from diagrams import Diagram, Cluster from diagrams.aws.security import WAF with Diagram("waf-regional", show=False): WAF("Regional")
# diagram.py # Needs diagrams from pip and graphwiz installed from diagrams import Diagram, Cluster from diagrams.aws.security import WAF with Diagram("waf-global", show=False): WAF("Global")
def build_arch_diag(self, account_dict, account_refs_dict): with Diagram(account_dict['account_alias'], show=True, direction="TB"): ## TIER 1: EXTERNAL TO AWS CLUSTERLESS ## Contains: Users, DNS, WAF, CloudFront, Cross Account VPC Peering (happens out of order) ## ------------------------------------------------------------------------------- ## Users users = Users('Actors') self.ingress.append(users) ## DNS if account_dict['dns']['name'] == 'Route53': dns = Route53('Route53') else: dns = TradicionalServer('External DNS') self.ingress.append(dns) ## WAF try: if account_dict['waf']['cloudfront']: waf = WAF('WAF - CloudFront') except KeyError: waf = None ## CloudFront if self.check_key(account_dict, 'cf'): cloudfront = CloudFront('CloudFront') self.ingress.append(cloudfront) cf_check = True ## CAVP cross_accounts = self.check_cross_account_refs(account_dict) ## TIER 2: ACCOUNT CLUSTER ## Contains: CAVP Accounts, Account ID, Account Alias, Global S3 Buckets ## ------------------------------------------------------------------------------- ## CAVP Accounts for x_account in cross_accounts: ## Since x_account is the key value for the account dict - xaccount_dict = cross_accounts['{}'.format(x_account)] ## Next with Accepter Accounts/VPC's/Nodes try: if xaccount_dict['xacc_account']: alias = self.get_account_refs( xaccount_dict['xacc_account'], account_refs_dict) with Cluster('Account: {}'.format(alias), graph_attr={ 'margin': '50', 'bgcolor': 'white', 'penwidth': '5' }): ## Make the cross account VPC with Cluster(xaccount_dict['xacc_vpc'], graph_attr={'bgcolor': 'white'}): ## Create the accuester node and add it to the dictionary with the ## Connection ID for diagram connection later. xacc_node = VPCPeering( 'VPC Peering - Accepter') cross_accounts['{}'.format( x_account)]['xacc_node'] = xacc_node except KeyError: try: if xaccount_dict['xreq_account']: alias = self.get_account_refs( xaccount_dict['xreq_account'], account_refs_dict) with Cluster('Account: {}'.format(alias), graph_attr={ 'margin': '50', 'bgcolor': 'white', 'penwidth': '5' }): ## Make the cross account VPC with Cluster(xaccount_dict['xreq_vpc'], graph_attr={'bgcolor': 'white'}): ## Create the Requester node and add it to the dictionary with the ## Connection ID for diagram connection later. xreq_node = VPCPeering( 'VPC Peering - Requester') cross_accounts['{}'.format( x_account)]['xreq_node'] = xreq_node except KeyError: continue ## Account ID and Alias with Cluster('Account: {}'.format(account_dict['account_alias']), graph_attr={ 'margin': '150', 'bgcolor': 'white', 'penwidth': '5' }): ## Global S3 Buckets s3_overflow = {} ## Diagram S3's in alternate Regions for s3 in account_dict['s3']: if s3['region'] == None: s3_node = SimpleStorageServiceS3(s3['Name']) else: ## If the S3 bucket isn't in one of our known AZ's, ## append to a list for the new region if s3['region'] in s3_overflow.keys(): s3_overflow[s3['region']].append(s3) else: ## If the S3 in a region that doesn't have an existing AZ, ## create a new key for the region and put the nodes in it for az in account_dict['az']: if az['RegionName'] != s3['region']: s3_overflow[s3['region']] = [] s3_overflow[s3['region']].append(s3) ## Create new cluster for each region in s3_overflow for region in account_dict['regions']: if region in s3_overflow.keys(): with Cluster(region, graph_attr={ 'bgcolor': 'white', 'style': 'dashed', 'pencolor': 'blue' }): for s3 in s3_overflow[region]: s3_node = SimpleStorageServiceS3(s3['Name']) ## TIER 3: VPC CLUSTER ## Contains: VPC, CAVP, VPC Peering, Internet Gateways, Load balancers, S3 buckets ## ------------------------------------------------------------------------------- ## VPC for v in range(len(account_dict['vpc'])): ## Dynamically add contents of VPC Cluster with Cluster(account_dict['vpc'][v]['VpcId'], graph_attr={'bgcolor': 'white'}): ## CAVP and VPC Peering account_dict['vpc'][v]['RequestNodes'] = [] account_dict['vpc'][v]['AcceptNodes'] = [] ## Create VPC Peering nodes, but connections can only be made once ## all Requester and Accepter nodes have been created. Store the nodes ## in a list for later reference, as dynamically created nodes can't be ## referred to uniquely and will need to be iterated upon later. for req in account_dict['vpc'][v]['PeerRequest']: if req['RequesterVpcInfo'][ 'OwnerId'] == account_dict['account_id']: req_node = VPCPeering( 'VPC Peering - Requester') cross_accounts[req['VpcPeeringConnectionId']][ 'req_node'] = req_node for acc in account_dict['vpc'][v]['PeerAccept']: if acc['AccepterVpcInfo'][ 'OwnerId'] == account_dict['account_id']: acc_node = VPCPeering('VPC Peering - Accepter') cross_accounts[acc['VpcPeeringConnectionId']][ 'acc_node'] = acc_node ## Internet Gateway try: ## Check if Internet Gateway exists if account_dict['igw']: for igw in account_dict['igw']: for attach in igw['Attachments']: ## If the IGW is attached to the VPC and available ## add it to igws list, which we will attach the ## previous ingress point to if attach['VpcId'] == account_dict[ 'vpc'][v]['VpcId'] and attach[ 'State'] == 'attached': internet_gw = InternetGateway( igw['InternetGatewayId']) igws.append(internet_gw) ig_check = True if len(igws) > 0: ## Append igws list to ingress list as the next connection point self.ingress.append(igws) except KeyError: ig_check = False ## Load Balancer try: for elb in account_dict['elb']: ## Check if a WAF is associated with the Load Balancer #waf_check = check_key(elb) elastic_lb = ElasticLoadBalancing( '{} ({})'.format(elb['DNSName'], elb['Scheme'])) for az in elb['AvailabilityZones']: elb_tuple = elastic_lb, az['SubnetId'] self.elb_subnets.append(elb_tuple) if elb['Scheme'] == 'internet-facing' and elb[ 'State'] == 'active': ## If the Load Balancer is internet-facing, a WAF should be put in place self.ingress.append(elastic_lb) elb_check = True except KeyError: elb_check = False ## TIER 4: REGION CLUSTER ## Contains: S3 buckets, WAF Regional, DynamoDB ## ------------------------------------------------------------------------------- region_list = self.kill_dupes(account_dict['regions']) for r in range(len(region_list)): for a in range(len(account_dict['az'])): if account_dict['az'][a][ 'RegionName'] == region_list[r]: with Cluster(region_list[r], graph_attr=self.region_sheet): for s3 in account_dict['s3']: if s3['region'] == region_list[r]: s3_node = SimpleStorageServiceS3( s3['Name']) ## WAF Regional ## PLACEHOLDER ## DynamoDB for ddb in account_dict['ddb']: ddb_region = account_dict['ddb'][ ddb]['TableArn'].split(':')[3] if ddb_region == region_list[r]: ddb_node = Dynamodb( account_dict['ddb'][ddb] ['TableName']) ## TIER 5: AVAILABILITY ZONE (AZ) CLUSTER ## Contains: RDS ## ------------------------------------------------------------------------------- with Cluster(account_dict['az'][a] ['ZoneName'], graph_attr={ 'bgcolor': 'white', 'style': 'dashed', 'pencolor': 'orange' }): ## Dynamically add RDS for rds in account_dict['rds']: if rds['AvailabilityZone'] == account_dict[ 'az'][a]['ZoneName']: rds_node = RDS( rds['DBName']) ## TIER 6: SUBNET CLUSTER ## Contains: Security Groups, EC2 Instances ## ------------------------------------------------------------------------------- for s in range( len(account_dict['az'][a] ['Subnets'])): with Cluster(account_dict['az'] [a]['Subnets'][s] ['SubnetId']): for rezzie in account_dict[ 'az'][a][ 'Subnets'][s][ 'ec2']: for instance in rezzie[ 'Instances']: ec2_name = self.get_name_tag( instance, 'EC2') ec2_instance = EC2( '{} ({})'. format( ec2_name, instance[ 'InstanceType'] )) self.ec2_instances.append( ec2_instance) ## If there is a load balancer, and the load balancer connects ## to the subnet of the EC2 instance, connect the ELB to the ## EC2 instance in the diagram for elb_tuple in self.elb_subnets: if account_dict['az'][ a]['Subnets'][ s]['SubnetId'] == elb_tuple[ 1]: self.ingress[ -1] >> elb_tuple[ 0] >> ec2_instance for i in range(len(self.ingress)): try: self.ingress[i] >> self.ingress[i + 1] except IndexError: error = "Dead end, baby." for conn in cross_accounts: try: req_node = cross_accounts[conn]['xreq_node'] acc_node = cross_accounts[conn]['acc_node'] req_node >> acc_node except KeyError: continue
from diagrams.aws.security import WAF from diagrams.aws.storage import S3 from diagrams.custom import Custom from diagrams.generic.network import Switch, VPN azure_url = "https://cdn.wccftech.com/wp-content/uploads/2016/05/Azure_.png" azure_icon = "azure.png" urlretrieve(azure_url, azure_icon) with Diagram(""): azure = Custom("Azure", azure_icon) dns = Route53("dns") office = Switch("office") with Cluster("odhk-data-vpc"): cf = CloudFront("odhk-data-cf") waf = WAF("odhk-data-waf") s3 = S3("odhk-data-s3") rt = RouteTable("odhk-data-rt") natrt = RouteTable("odhk-data-nat-rt") igw = InternetGateway("odhk-data-igw") with Cluster("odhk-data-gw-subnet"): natgw = NATGateway("odhk-data-nat-gw") with Cluster("data-public-subnet"): elb = ELB("data-pipeline-elb") with Cluster("data-pg-sg"): ppg = RDS("pipeline-pg") wpg = RDS("warehouse-pg") with Cluster("data-pipeline-subnet"): eks = EKS("data-pipeline-eks") with Cluster("data-pipelie-eks-ng"): ng = EC2("data-pipelie-eks-node")