Architecture diagram as code

illustrations illustrations illustrations illustrations illustrations illustrations illustrations

Architecture diagram as code

Published on May 07, 2024 by Malys

For many years, I use Plantuml to create architecture and other kind of diagram. I will the reason of this.

Pros and Cons

Pros:

  • Plantuml is a DSL (Domain Specific Language) for diagrams that means that you can manage your diagrams as a code:
    • using GIT for versioning and sharing
    • creating automation to generate easily diagrams (see my project KRepresentation to describe graphically Keycloak configuration)
    • creating snippets
    • reuse of code
  • Plantuml supports many kind of diagrams (C4, uml, components, mindmap …)
  • VSCode extension is very fine
  • Large community to share and find example of use
    • to create library (aws, GCP, …) of components

Cons:

  • Plantuml diagrams look like 80’s even if you customize it (see skinparams) but for me, the most important is to communicate easily with my team and not to be pretty.
  • Plantuml layout is sometimes very tricky
  • Syntaxes between different kind of diagrams and external libraries are not the same and It’s very to learn them and keep them in mind because I use often plantuml but not every day
  • VSCode extension doesn’t support intellisense, autocomplete
  • Language Server Protocol is not available for plantuml

For these last three points, it’s very difficult for me to be productive using it.

Productivity

To solve my problem, I have created some snippets, templates and ium files to reuse some configuration anor d components. But it was not enough, because of new releases of plantuml or stdlib break syntaxes and my snippets were not compatible. Many times , community documentation was outdated.

To my mind, the unique reference is source code of plantuml with its documentation. That ’s why I decided to parse documentation to generate static autocompletion.

Plantuml Helpers associated with VSCode and vscode-complete-from-file extension helps users to import more easily ‘include’ and provides autocompletion for plantuml files and many official snippets.

In Action

It’s not perfect but helpful and updated every week from official documentation.

GCP Diagram in the real world

GCP’s stdlib for is not so rich as AWS stdlib that ’s why is a use a mix of both (GCP components with AWS grouping)

Step by step processus

I have create iuml file to import easily my global configuration.

@startuml
    !include <awslib14/AWSCommon>
    !include <awslib14/Groups/all>
    !include <gcp/GCPCommon>

    skinparam linetype ortho
    skinparam nodesep 230
@enduml

After that, I have created my final plantuml file

@startuml(id=terraEarth)
title Terra Earth
    !include _deps-gcp.iuml

    !include <gcp/API_Management/Apigee_API_Platform>
    !include <gcp/Compute/Kubernetes_Engine>
    !include <gcp/Compute/Cloud_Run>
    !include <gcp/Networking/Cloud_Load_Balancing>

    map Contraints #LightCoral {
    Architecture => HA-DR, Hybrid
    Components => IOT, BigData, Analytics, Monitoring
    Security => Key, Secret, Identity, Remote Access
    }
    map Features #LightGreen{
    ML => Predict Malfunction
    API => public, internal portal
    Cost => limited
    }

    !include cicd-gcp.puml
    !include iot-gcp.puml

    device -[hidden]-> dev

    GenericGroup(gcp,"Google Cloud Platform") #LightBlue{
        Cloud_Load_Balancing(lb,"Load Balancer","Global Load Balancer")

        VPCGroup(vpc,"VPC"){
            Apigee_API_Platform(apigee,"API Management","APIGee")
            lb --> apigee
            Kubernetes_Engine(kub,"Orchestrator","Kubernetes","cluster auto-pilot")
            apigee --> kub
            Cloud_Run(run,"Managed Orchestrator","Cloud Run")
            apigee --> run
        }

    }
@enduml


@startmindmap
    !include mm-security-gcp.puml
    !include mm-monitoring-gcp.puml
    !include mm-keys-gcp.puml
    !include mm-cost-gcp.puml
@endmindmap

GCP Use Cases examples



@startuml(id=BeyondCorp)
title Beyond Corp
    !include _deps-gcp.iuml

    !include <office/Users/mobile_user>
    !include <gcp/Networking/Cloud_Load_Balancing>
    !include <gcp/Management_Tools/Cloud_APIs>
    !include <gcp/Security/Cloud_IAM>
    !include <material/lock>
    !include <office/Services/3rd_party_service>
    !include <office/Security/active_directory>
    !include <office/Services/access_services>

    Entity(user,"Employee","person","cloud service consumer",GCP_COLOR,mobile_user,"person")
    
    GenericGroup(gcp,"Google Cloud Platform") #LightBlue{
        Cloud_Load_Balancing(lb,"Load Balancer","Global Load Balancer")
        user --> lb

        VPCGroup(vpc,"VPC"){
            Entity(iap,"Proxy","Identity Aware Proxy","",GCP_COLOR,lock,"IAP")
            lb --> iap
            
            Cloud_IAM(iam,"IAM","Cloud IAM")
            iap ..> iam
            Entity(ad,"Directory","Active Directory","",GCP_COLOR,active_directory,"AD")
            iap ..> ad
            
            Entity(acm,"Perimeter Management","Access Context Manager","",GCP_COLOR,access_services,"ACM")
            iap ..> acm

            Cloud_APIs(apis,"GCP services","gcp")
            iap --> apis
            Cloud_APIs(internalapis,"Extranet service","extranet")
            iap --> internalapis

            Entity(iappremise,"Proxy","Identity Aware Proxy","on premise proxy",GCP_COLOR,lock,"IAP Connector")
            lb --> iappremise
        }
        lb -[hidden]d-> vpc
    }

    GenericGroup(premise,"On premise")#LightCoral{
        vpc <--> premise : Cloud Connect
        Entity(servicepremise,"Service","API","extranet",GCP_COLOR,3rd_party_service,"API")
        iappremise --> servicepremise
    }

@enduml



@startuml(id=chatbotWithDLP)
skinparam titleBorderRoundCorner 15
skinparam titleBorderThickness 2
skinparam titleBorderColor LightGray
skinparam titleBackgroundColor SkyBlue
skinparam titleFontColor WhiteSmoke
title Chatbot with Data Loss Prevention
!include _deps-gcp.iuml

!include <gcp/Data_Analytics/Cloud_Dataflow>
!include <gcp/AI_and_Machine_Learning/Dialog_Flow_Enterprise_Edition>
!include <gcp/Compute/Cloud_Functions>
!include <gcp/Data_Analytics/BigQuery>
!include <gcp/Management_Tools/Cloud_APIs>
!include <gcp/Management_Tools/Logging>
!include <tupadr3/font-awesome/mobile_phone>

Entity(mobile,"Chatbot","phone","",GCP_COLOR, mobile_phone,phone)

GenericGroup(gcp,"Google Cloud Platform") #LightBlue{
    Dialog_Flow_Enterprise_Edition(dialogflow,"Charbot Service","DialogFlow")
    Cloud_Functions(ft,"Function","Cloud Function", "Technical")
    Cloud_Functions(fb,"Function","Cloud Function", "Business")
    Logging(log,"Logging","Cloud Logging","Secure centralization of logs")
    BigQuery(bq,"Data WareHouse","Big Query")
    Cloud_APIs(dlp,"Anonymization","DLP API","Mask sensitive data")

    dialogflow -D-> ft
    ft -L-> fb
    fb -U-> dlp
    dlp -U-> bq

    dialogflow ..> log
    ft ..> log
    fb ..> log
    dlp ..> log

}

mobile -L-> dialogflow
@enduml
@startuml(id=cicd)
    !include _deps-gcp.iuml

    !include <gcp/Developer_Tools/Cloud_Source_Repositories>
    !include <gcp/Developer_Tools/Cloud_Build>
    !include <gcp/Developer_Tools/Container_Registry>
    !include <gcp/Management_Tools/Cloud_Deployment_Manager>
    !include <logos/google-developers>

    Entity(dev,"Developper","Person","",GCP_COLOR,google-developers,"Person")

    GenericGroup(gcp,"Google Cloud Platform") #LightBlue{
        dev -[hidden]R-> gcp
        Cloud_Source_Repositories(src,"Source code repository","GIT")
        note top of src: IAM
        dev -R-> src : Push source

        Cloud_Build(build,"Builder","Cloud build")
        note top of build: Dynamic/Static Analysis + Tests\nSign Artifact
        src -R-> build: Build source

        Container_Registry(artifact,"Registry","Artifact registry")
        note top of artifact: IAM
        build -R-> artifact : Push artifact

        Cloud_Deployment_Manager(deploy,"Deployment manager","Cloud deploy")
        artifact -R-> deploy: Deploy artifact
        note top of deploy: Authorization Binary
    }


@enduml

@startuml(id=DataLake)
title Data Lake
    !include _deps-gcp.iuml

    !include <tupadr3/font-awesome-5/truck_loading>
    !include <gcp/Data_Analytics/Cloud_PubSub>
    !include <gcp/Data_Analytics/Cloud_Dataflow>
    !include <gcp/Databases/Cloud_Bigtable>
    !include <gcp/Compute/Compute_Engine>
    !include <office/Servers/application_server>
    !include <tupadr3/material/storage>
    !include <gcp/Migration/Transfer_Appliance>
    !include <office/Services/3rd_party_service>
    !include <awslib14/DeveloperTools/CommandLineInterface>
    !include <gcp/Storage/Cloud_Storage>
    !include <gcp/Data_Analytics/BigQuery>
    !include <gcp/Data_Analytics/Cloud_Dataprep>
    !include <gcp/Data_Analytics/Cloud_Dataproc>
    !include <gcp/Databases/Cloud_Spanner>
    !include <gcp/AI_and_Machine_Learning/Cloud_AutoML>

    together{
        GenericGroup(iot,"IOT")#LightGreen{
            Entity(sensor,"Mobile device","trucks","Fleet",GCP_COLOR,truck_loading,"sensor")
        }

        GenericGroup(onprem,"On premise")#LightCoral{
            Entity(server,"Server","VM","Business service",GCP_COLOR ,application_server,"application")
            Entity(storage,"Storage","disk","Users activities",GCP_COLOR ,storage,"local")
        }
        iot -[hidden]R-> onprem
    }
    GenericGroup(gcp,"Google Cloud Platform") #LightBlue{
        onprem -R-> gcp: "Cloud Connect"

        Cloud_PubSub(broker,"Broker","PubSub") #LightGreen
        sensor =[#red]R=> broker: "Realtime"
        Cloud_Dataflow(df,"Data Processing","Cloud Dataflow")  #LightGreen
        broker -[#red]-> df
        Cloud_Bigtable(bt,"Database","NoSQL Key/Value")  #LightGreen
        df -[#red]-> bt

        Transfer_Appliance(txapp,"Transfer","Transfer appliance","huge amount of data")
        Entity(txservice,"Transfer","Transfer service","small amount of data",GCP_COLOR ,3rd_party_service,"service")
        Entity(gsutil,"Transfer","gsutil","sample of data",GCP_COLOR,CommandLineInterface,"cli")
        storage --> txapp
        storage --> txservice
        storage --> gsutil

        Cloud_Storage(gcs,"Storage","Cloud Storage","data lake") #LightYellow
        txapp --> gcs
        txservice --> gcs
        gsutil --> gcs

        BigQuery(bq,"Data warehouse","BigQuery")
        gcs --> bq: "Analyse"
        Cloud_Dataprep(dprep,"Data Visualization","Cloud DataPrep")
        gcs --> dprep: "Visualize"
        Cloud_Spanner(spanner,"Database","Cloud Spanner")
        gcs --> spanner: "Prediction"
        Cloud_Dataproc(dproc,"Massive Processor","Cloud DataProc")
        gcs --> dproc: "Bulk massive processing"
        Cloud_AutoML(automl,"AI","Cloud AutoML")
        gcs --> automl: "Mining"
    }

@enduml

@startuml(id=hybridArchitecture)
skinparam titleBorderRoundCorner 15
skinparam titleBorderThickness 2
skinparam titleBorderColor LightGray
skinparam titleBackgroundColor SkyBlue
skinparam titleFontColor WhiteSmoke
title Hybrid architecture
!include _deps-gcp.iuml

!include <gcp/Compute/Cloud_Functions>
!include <gcp/Networking/Cloud_Firewall_Rules>
!include <gcp/Compute/Compute_Engine>
!include <gcp/Storage/Cloud_Storage>
!include <gcp/Compute/Kubernetes_Engine>
!include <tupadr3/material/computer>
!include <office/Servers/database_server>
!include <gcp/Networking/Cloud_Load_Balancing>
!include <awslib14/General/Internet>


Internet(internet,"Internet","WAN")

GenericGroup(gcp,"Google Cloud Platform")#LightBlue{

    Cloud_Load_Balancing(lb,"Load Balancer","Global Load Balancer")

    VPCGroup(vpc,"VPC"){
        Compute_Engine(ce,"VMs","GCE")
        Kubernetes_Engine(ke,"Kubernetes","GKE")
    }
    lb -[hidden]d-> vpc
}

GenericGroup(premise,"On premise")#LightCoral{
    PublicSubnetGroup(public,"Public Subnet"){
        Entity(vm,"VMs","Virtualization",WhiteSmoke,"",$computer)
    }
    PrivateSubnetGroup(private,"Private Subnet"){
        Entity(db,"Database","DBMS",WhiteSmoke,"",$database_server)
    }

    public -[hidden]L-> private

}
internet -D-> lb
vpc <======R====>premise : "Cloud\nInterconnect"
lb -> ce
lb -> ke
lb -> vm
ce -> db
vm -> db
@enduml

@startuml(id=IoT)
    !include _deps-gcp.iuml

    !include <gcp/Internet_of_Things/Cloud_IoT_Core>
    !include <gcp/Data_Analytics/Cloud_PubSub>
    !include <office/Devices/cell_phone_generic>
    !include <gcp/Databases/Cloud_Bigtable>
    !include <gcp/Data_Analytics/BigQuery>
    !include <gcp/Data_Analytics/Cloud_Dataflow>
    !include <office/Servers/monitoring_sql_reporting_services>
    !include <gcp/AI_and_Machine_Learning/AI_Platform>
    !include <gcp/Compute/Cloud_Functions>


    Entity(device,"Device","IoT","iot device",GCP_COLOR,cell_phone_generic,"iot device")

    GenericGroup(gcp,"Google Cloud Platform") #LightBlue{
        device -[hidden]R-> gcp 
        Cloud_IoT_Core(iotcore,"IoT Management","IoT","Data & Configuration") #LightYellow
        device -[#red]-> iotcore : Data
        iotcore -[#green]-> device : Configuration

        Cloud_PubSub(pubsub,"Broker","Cloud PubSub")
        iotcore -[#red]R-> pubsub : Data

        Cloud_Dataflow(df,"Data transformation","Dataflow")
        pubsub -[#red]R-> df

        BigQuery(bq,"Data Warehouse","BigQuery")
        df -[#red]R-> bq: Analyse

        AI_Platform(ai,"AI processing","AI Platform")
        bq -[#red]R-> ai: Mining

        Entity(report,"Reporting","Data Studio","",GCP_COLOR,monitoring_sql_reporting_services,"Data Studio")
        ai -[#red]R-> report: Visual reporting

        Cloud_Bigtable(bt,"Database","NoSQL Key/Value")
        df -[#red]R-> bt: Store\nhuge amount\nof data

        ai -[#blue]-> df: AI results
        df -[#blue]-> iotcore

        Cloud_Functions(func,"Apps","Cloud Functions","Configuration management")
        func -[#green]-> iotcore: Update configuration
    }
@enduml

@startuml(id=MigrateDatabasetoCloudSpanner)
skinparam titleBorderRoundCorner 15
skinparam titleBorderThickness 2
skinparam titleBorderColor LightGray
skinparam titleBackgroundColor SkyBlue
skinparam titleFontColor WhiteSmoke
title Migrate Database to Cloud Spanner
    !include _deps-gcp.iuml

    !include <gcp/Databases/Cloud_SQL>
    !include <gcp/Storage/Cloud_Storage>
    !include <gcp/Data_Analytics/Cloud_Dataflow>
    !include <gcp/Databases/Cloud_Spanner>

    GenericGroup(gcp,"Google Cloud Platform") #LightBlue{
        Cloud_SQL(db,"Database","RDBMS")
        Cloud_Storage(storage,"Storage","Cloud storage")
        Cloud_Dataflow(dataflow,"Convertor","Cloud DataFlow")
        Cloud_Spanner(spanner,"Cloud Spanner","NoSQL")
        db -> storage : "Export"
        storage -> dataflow: "Convert"
        dataflow -> spanner: "Import"
        
        note right of spanner #LightCoral: Manage errors and replay
    }
@enduml

@startmindmap
*[#LightCoral] Cost
** GCE
*** Commitment
*** Spot nodes
** Cost Calculator
** Cloud storage
*** Lifecycle
@endmindmap

@startmindmap
*[#LightCoral] Key Management System
** Customer Managed Encryption Key
** Customer Supplied Encryption Key
*** Cloud Storage
*** GCE
** Cloud HSM
** External Key Management
*** some partner products (double encryptions)
@endmindmap

@startmindmap
*[#LightCoral] Monitoring
** Cloud Logging
*** Security Information and Event Management:SIEM
**** Chronicle
** VPC Flow Logs
*** Subnet
** Network Intelligence center
** VPC Service Control
*** Context Manager
** Data Loss Prevention
** Packet Mirroring
*** Intrusion Detection System PaloAlto
@endmindmap

@startmindmap
*[#LightCoral] Security Center
** WebSecurity scanner
** Container Threat scanner
** Organization policy
** VPC Service Control
** Data Loss Prevention
** Firewall Insight
@endmindmap
@startuml(id=SRE)
skinparam titleBorderRoundCorner 15
skinparam titleBorderThickness 2
skinparam titleBorderColor LightGray
skinparam titleBackgroundColor SkyBlue
skinparam titleFontColor WhiteSmoke
title  Site Reliability Engineering - SRE

state "Product" as P #Blue 
state "Development" as D #Green 
state "Capacity Planning" as C #LimeGreen 
state "Testing/Release Procedure" as T #GreenYellow
state "Post Mortem/Root cause" as R #gold
state "Incident Response" as I #orange
state "Monitoring" as M #red 

P --> D
D --> C
C --> T
T --> R
R --> I
I --> M
@enduml

@startuml(id=cardholder)
title: full GCP 
!include _deps-gcp.iuml

!include <gcp/Networking/Cloud_Load_Balancing>
!include <gcp/Networking/Cloud_Armor>
!include <gcp/Compute/Compute_Engine>
!include <gcp/Compute/Kubernetes_Engine>
!include <gcp/API_Management/Apigee_API_Platform>
!include <awslib14/General/Client>
!include <gcp/Developer_Tools/IDE_Plugins>
!include <gcp/Security/Key_Management_Service>

Client(client,"Customer","HTTP","Business API consummer") #LightSlateGrey

GenericGroup(gcp,"GCP") #MOTIVATION{

    Cloud_Armor(waf,"WAF","Cloud Armor","Public Web protection")
    Cloud_Load_Balancing(globallb,"Loadbalancer","HTTP loadbalancer","external")
    waf <.d.> globallb

    GenericGroup(pcidss,"PCIDSS scope") #LightCoral{
        package "Project: Cardholder"#Snow{
            RegionGroup(euWS,"Region: Europe West") #Lavender {
                Apigee_API_Platform(apigeeW,"API Gateway","apigee","regional")
                IDE_Plugins(dlpW,"Tokenizator","Data Loss Prevention","APIGee extension")
            }

            Key_Management_Service(kms,"Key Manager","KMS with HSM","Multiregional")
            note left #LightSalmon
            The same DEK in multregional area to be able to decrypt reversible token
            Generated token is a cypher of sensitive data. <i>Quid PCIDSS?</i>
            Use <b>CMKS</b> to to manage key lifecycle 
            end note

            RegionGroup(euES,"Region: Europe East") #MistyRose {
                Apigee_API_Platform(apigeeE,"API Gateway","apigee","regional")
                IDE_Plugins(dlpE,"Tokenizator","Data Loss Prevention","APIGee extension")
            }

            euWS -[hidden]d--> euES

            kms <-d- dlpE:"Unwrap DEK"
            kms <-u- dlpW:"Unwrap DEK"
            dlpE .d.> apigeeE
            dlpW .u.> apigeeW
        }
    }

    GenericGroup(nopcidss,"Not PCIDSS scope") #LightSkyBlue{
        package "Project: Business"#Snow{
            RegionGroup(euW,"Region: Europe West") #Lavender {
                PrivateSubnetGroup(euSubW,"Private Subnet"){
                    Cloud_Load_Balancing(euwlb,"LoadBalancer ","HTTP loadbalancer","internal")
                    AutoScalingGroupGroup(migEuW,"Managed Instance Group"){
                        Compute_Engine(bizEuW,"Business logic","Virtual Machine","Business services")
                    }
                }
            }

            RegionGroup(euE,"Region: Europe East") #MistyRose {
                PrivateSubnetGroup(euSubE,"Private Subnet"){
                    Kubernetes_Engine(gke,"Orchestrator","Kubernetes cluster","private")
                }
            }
            euW -[hidden]d--> euE
        }
    }
    
    
}

client -R->  globallb

pcidss <--R--> nopcidss #Red:"VPC Service Connect"
globallb -R-> apigeeE
globallb -R-> apigeeW
apigeeW -R-> euwlb
apigeeE -R-> gke

euwlb -R-> migEuW
@enduml

@startuml datavault like

!include _deps-gcp.iuml

!include <awslib14/AWSCommon>
!include <awslib14/Groups/all>
!include <gcp/GCPCommon>
!include <gcp/Networking/Cloud_Load_Balancing>
!include <gcp/Networking/Cloud_Armor>
!include <gcp/Compute/Compute_Engine>
!include <gcp/Compute/Kubernetes_Engine>
!include <gcp/API_Management/Apigee_API_Platform>
!include <awslib14/General/Client>
!include <gcp/Developer_Tools/IDE_Plugins>
!include <gcp/Security/Key_Management_Service>
!include <gcp/Compute/Cloud_Run>
!include <gcp/Databases/Cloud_Spanner>

Client(client,"Customer","HTTP","Business API consummer") #LightSlateGrey

GenericGroup(gcp,"GCP") #MOTIVATION{

    Cloud_Armor(waf,"WAF","Cloud Armor","Public Web protection")
    Cloud_Load_Balancing(globallb,"Loadbalancer","HTTP loadbalancer","external")
    waf <.d.> globallb
    client -R->  globallb

    GenericGroup(pcidss,"PCIDSS scope") #LightCoral{
        package "Project: Cardholder"#Snow{

            RegionGroup(euWS,"Region: Europe West") #Lavender {
                Apigee_API_Platform(apigeeW,"API Gateway","apigee","regional")
                Cloud_Run(dtvtW,"Tokenizator","DataVault","Java microservice")
                note right #LightSalmon
                Create UUID/card number unique pair
                end note
            }

            together {
                Key_Management_Service(kms,"Key Manager","KMS","Multiregional")
                note right #LightSalmon
                The same DEK in multregional area to be able to decrypt reversible token
                Use <b>CMKS</b> to to manage key lifecycle 
                end note

                Cloud_Spanner(db,"Database","Cloud Spanner","multiregional")
            }

            RegionGroup(euES,"Region: Europe East") #MistyRose {
                Apigee_API_Platform(apigeeE,"API Gateway","apigee","regional")
                Cloud_Run(dtvtE,"Tokenizator","DataVault","Java microservice")
            }

            euWS -[hidden]d--> euES
            db -[hidden]r--> kms

            kms <-d- dtvtE:"Unwrap DEK"
            kms <-u- dtvtW:"Unwrap DEK"
            dtvtE <-d- apigeeE:"un/tokenize service"
            dtvtW <-u- apigeeW:"un/tokenize service"

            db <-d-> dtvtE 
            db <-u-> dtvtW 
        }
    }

    GenericGroup(nopcidss,"Not PCIDSS scope") #LightSkyBlue{
        package "Project: Business"#Snow{
            RegionGroup(euW,"Region: Europe West") #Lavender {
                PrivateSubnetGroup(euSubW,"Private Subnet"){
                    Cloud_Load_Balancing(euwlb,"LoadBalancer ","HTTP loadbalancer","internal")
                    AutoScalingGroupGroup(migEuW,"Managed Instance Group"){
                        Compute_Engine(bizEuW,"Business logic","Virtual Machine","Business services")
                    }
                }
            }

            RegionGroup(euE,"Region: Europe East") #MistyRose {
                PrivateSubnetGroup(euSubE,"Private Subnet"){
                    Kubernetes_Engine(gke,"Orchestrator","Kubernetes cluster","private")
                }
            }
            euW -[hidden]d--> euE
        }
    }
}


pcidss <--R--> nopcidss #Red:"VPC Service Connect"
globallb -R-> apigeeE
globallb -R-> apigeeW
apigeeW -R-> euwlb:"business service"
apigeeE -R-> gke:"business service"

euwlb -R-> migEuW
@enduml
@startuml(id=healthCare)
title Health Care

    map Contraints #LightCoral {
    Architecture => HA-DR, Hybrid
    Components => IOT, BigData, Analytics, Monitoring
    Security => Key, Secret, Identity, Remote Access
    }
    map Features #LightGreen{
    ML => Predict Malfunction
    API => public, internal portal
    Cost => limited
    }

    !include cicd-gcp.puml
    !include iot-gcp.puml

    device -[hidden]-> dev

@enduml



@startmindmap
    !include mm-security-gcp.puml
    !include mm-monitoring-gcp.puml
    !include mm-keys-gcp.puml
    !include mm-cost-gcp.puml
@endmindmap
@startuml(id=terraEarth)
title Terra Earth
    !include _deps-gcp.iuml

    !include <gcp/API_Management/Apigee_API_Platform>
    !include <gcp/Compute/Kubernetes_Engine>
    !include <gcp/Compute/Cloud_Run>
    !include <gcp/Networking/Cloud_Load_Balancing>

    map Contraints #LightCoral {
    Architecture => HA-DR, Hybrid
    Components => IOT, BigData, Analytics, Monitoring
    Security => Key, Secret, Identity, Remote Access
    }
    map Features #LightGreen{
    ML => Predict Malfunction
    API => public, internal portal
    Cost => limited
    }

    !include cicd-gcp.puml
    !include iot-gcp.puml

    device -[hidden]-> dev

    GenericGroup(gcp,"Google Cloud Platform") #LightBlue{
        Cloud_Load_Balancing(lb,"Load Balancer","Global Load Balancer")

        VPCGroup(vpc,"VPC"){
            Apigee_API_Platform(apigee,"API Management","APIGee")
            lb --> apigee
            Kubernetes_Engine(kub,"Orchestrator","Kubernetes","cluster auto-pilot")
            apigee --> kub
            Cloud_Run(run,"Managed Orchestrator","Cloud Run")
            apigee --> run
        }

    }
@enduml


@startmindmap
    !include mm-security-gcp.puml
    !include mm-monitoring-gcp.puml
    !include mm-keys-gcp.puml
    !include mm-cost-gcp.puml
@endmindmap

@startuml(id=ServerlessVideoProcessing)
title Serverless video processing
    !include _deps-gcp.iuml

    !include <office/Servers/application_server>
    !include <awslib14/General/Client>
    !include <gcp/Data_Analytics/Cloud_PubSub>
    !include <gcp/Storage/Cloud_Storage>
    !include <gcp/Compute/Cloud_Functions>
    !include <gcp/AI_and_Machine_Learning/Cloud_Vision_API>
    !include <gcp/Management_Tools/Cloud_APIs>
    !include <gcp/AI_and_Machine_Learning/Cloud_Video_Intelligence_API>
    !include <gcp/Data_Analytics/BigQuery>
    !include <office/Servers/monitoring_sql_reporting_services>

    together{
        Entity(videoinlive,"Video Acquisition","camera","inlive acquisition",GCP_COLOR,application_server,"source")
        Client(videopreprocessed,"Video Acquisition","camera","offline acquisition")
        videoinlive -[hidden]U-> videopreprocessed
    }

    GenericGroup(gcp,"Google Cloud Platform") #LightBlue{
        together{
            Cloud_PubSub(pubsub,"Broker","Cloud Pub Sub")
            videoinlive -[#red]R-> pubsub: streaming
            Cloud_Storage(storage,"Storage","Cloud Storage")
            videopreprocessed --> storage: copying

            pubsub -[hidden]U-> storage
        }

        Cloud_Functions(func,"Function","Cloud Function")
        pubsub -R-> func: Trigger
        storage -R-> func: Trigger
        together{
            Cloud_Vision_API(visionapi,"Image Processing","Cloud Vision API")
            func .D.-> visionapi : image processing

            Cloud_APIs(dlp,"Sensitive Data","Data Loss Prevention")
            func .D.-> dlp : sensitive data masking

            Cloud_Video_Intelligence_API(videoapi,"Video Processing","Cloud Video Intelligence API")
            func .D.-> videoapi : image processing
        }
        BigQuery(bq,"Data Warehouse","BigQuery")
        func -R-> bq: analysing

        Entity(report,"Reporting","Data Studio","",GCP_COLOR,monitoring_sql_reporting_services,"Data Studio")
        bq -R-> report

    }

@enduml
@startuml(id=Website)
skinparam titleBorderRoundCorner 15
skinparam titleBorderThickness 2
skinparam titleBorderColor LightGray
skinparam titleBackgroundColor SkyBlue
skinparam titleFontColor WhiteSmoke
title Website
    !include _deps-gcp.iuml

    !include <awslib14/General/Mobileclient>
    !include <gcp/Networking/Cloud_Load_Balancing>
    !include <gcp/Networking/Cloud_Armor>
    !include <gcp/Compute/App_Engine>
    !include <gcp/Networking/Cloud_CDN>
    !include <gcp/Storage/Cloud_Storage>
    !include <gcp/Compute/Compute_Engine>
    !include <gcp/Databases/Cloud_SQL>
    !include <gcp/Databases/Cloud_Firestore>
    !include <awslib14/GroupIcons/AutoScalingGroup>
    !include <awslib14/Groups/VPC>

    Mobileclient(client,"Client","browser")

    GenericGroup(gcp,"Google Cloud Platform") #LightBlue{

        together{
            Cloud_Load_Balancing(glb,"Load Balancer","Global Load Balancer")
            client -R-> glb
            Cloud_Armor(waf,"WAF","Cloud Armor")
            Cloud_CDN(cdn,"Local CDN","CDNs")
            
        }

        glb .U.> waf
        glb .D.> cdn
        
        VPCGroup(vpc,"VPC")#SkyBlue{
            Cloud_Storage(static,"Statics","Cloud Storage")
            glb --> static

            Cloud_Load_Balancing(ilb,"Internal Load Balancer","Regional Load Balancer")
            glb -R-> ilb
            together{
                GenericGroup(mig,"MIG") #AliceBlue{
                    Compute_Engine(gce,"Server Web","VMs")
                }
                App_Engine(gae,"Server Web","Google App Engine")

                mig -[hidden]U-> gae
            }

            ilb -R-> gae
            ilb -R-> mig

            together{
                Cloud_SQL(rdbms,"Database","SQL")
                Cloud_Firestore(nosql,"Database","NoSQL")
                rdbms -[hidden]L-> nosql
            }
            mig --> rdbms
            gae --> rdbms
            gae --> nosql
            mig --> nosql
        }
    }

@enduml