Search code examples
architectureplantuml

Position objects or entities as relationships


I am trying to draw some diagrams mimicking examples at awslabs/aws-icons-for-plantuml . There are two issues I am facing (please excuse the loose terminologies):

  • How to add objects on top of another object/entity?

  • How to add objects/entities between entities in place of notes or comments?

In the diagram below,

a) I would like to add Role1 on top of vpc or ec2 instance or any boundary to highlight that only r1 can access this resource.

b) I would like to add Role2 entity between EC2 and Queue Service. This is to highlight that r2 has access to SNS message between (not shown).

Code:

@startuml VPC
!define AWSPuml https://raw.githubusercontent.com/awslabs/aws-icons-for-plantuml/v13.1/dist
!include AWSPuml/AWSCommon.puml
!include AWSPuml/AWSSimplified.puml
!include AWSPuml/Compute/EC2.puml
!include AWSPuml/Compute/EC2Instance.puml
!include AWSPuml/Groups/AWSCloud.puml
!include AWSPuml/Groups/VPC.puml
!include AWSPuml/Groups/AvailabilityZone.puml
!include AWSPuml/Groups/PublicSubnet.puml
!include AWSPuml/Groups/PrivateSubnet.puml
!include AWSPuml/NetworkingContentDelivery/VPCNATGateway.puml
!include AWSPuml/SecurityIdentityCompliance/IdentityAccessManagementRole.puml
!include AWSPuml/ApplicationIntegration/SimpleQueueService.puml

hide stereotype
skinparam linetype ortho
AWSCloudGroup(cloud) {

  VPCGroup(vpc) {

    AvailabilityZoneGroup(az_1, "\tAvailability Zone 1\t") {
      PublicSubnetGroup(az_1_public, "Public subnet") {
        VPCNATGateway(az_1_nat_gateway, "NAT gateway", "") #Transparent
      }
      PrivateSubnetGroup(az_1_private, "Private subnet") {
        EC2Instance(az_1_ec2_1, "Instance", "") #Transparent
      }

  IdentityAccessManagementRole("r1", "Role1", " ")
  IdentityAccessManagementRole("r2", "Role2", " ")

  SimpleQueueService("sqs", "Queue Service", " ")

    az_1_ec2_1 .u.> az_1_nat_gateway
    az_1_ec2_1 --> sqs:[$r1]
    }

  }
}
@enduml


Corresponding diagram:

enter image description here

I would like the roles to be placed at positions shown by arrowhead: enter image description here


Solution

  • The strategy is to use the <img:...> inside of labels or names of elements. I found some insight to make your role icons smaller in an issue on the aws-icons-for-plantuml repo. You may feel like adjusting the {scale=..} values.

    To position Role2, I made a hidden rectangle above az_1 whose name is the image wrapped with the role name in bold. Because it's a rectangle name, the font is bigger than the label used on an association (as in Role1). These are "hacks" and so as you can see they're far from perfect.

    @startuml VPC
    !define AWSPuml https://raw.githubusercontent.com/awslabs/aws-icons-for-plantuml/v13.1/dist
    !include AWSPuml/AWSCommon.puml
    !include AWSPuml/AWSSimplified.puml
    !include AWSPuml/Compute/EC2.puml
    !include AWSPuml/Compute/EC2Instance.puml
    !include AWSPuml/Groups/AWSCloud.puml
    !include AWSPuml/Groups/VPC.puml
    !include AWSPuml/Groups/AvailabilityZone.puml
    !include AWSPuml/Groups/PublicSubnet.puml
    !include AWSPuml/Groups/PrivateSubnet.puml
    !include AWSPuml/NetworkingContentDelivery/VPCNATGateway.puml
    !include AWSPuml/SecurityIdentityCompliance/IdentityAccessManagementRole.puml
    !include AWSPuml/ApplicationIntegration/SimpleQueueService.puml
    
    skinparam Rectangle<<hidden>> {
        BackgroundColor transparent
        BorderColor transparent
    }
    
    hide stereotype
    skinparam linetype ortho
    AWSCloudGroup(cloud) {
    
      VPCGroup(vpc) {
    
        'IdentityAccessManagementRole("r1", "Role1", " ")
        rectangle "<img:AWSPuml/SecurityIdentityCompliance/IdentityAccessManagementRole.png{scale=0.4}>\n<b>Role1</b>" as r1  <<hidden>>
        AvailabilityZoneGroup(az_1, "\tAvailability Zone 1\t") {
            PublicSubnetGroup(az_1_public, "Public subnet") {
                VPCNATGateway(az_1_nat_gateway, "NAT gateway", "") #Transparent
            }
            PrivateSubnetGroup(az_1_private, "Private subnet") {
                EC2Instance(az_1_ec2_1, "Instance", "") #Transparent
            }
    
            SimpleQueueService("sqs", "Queue Service", " ")
    
            az_1_ec2_1 .u.> az_1_nat_gateway
            'IdentityAccessManagementRole("r1", "Role1", " ")
            az_1_ec2_1 --> sqs:"<img:AWSPuml/SecurityIdentityCompliance/IdentityAccessManagementRole.png{scale=0.4}>  \n<b>Role2  </b>"
        }
    
        az_1 -[hidden]up- r1 
    
      }
    }
    @enduml
    

    Here's a PNG of that:

    PNG