2. Create Real Life AWS Diagrams

Note

In this section we’ll put PlantUML to the test by seeing if we can recreate some real diagrams from the AWSArchitectureBlog.

We’ll show the original image from the AWSArchitectureBlog, and the PlantUML version for comparison.

We’re aiming for architectural equivalence (not image reproduction).

We take the 3 most recent entries that show architecture diagrams on the front page of AWSArchitectureBlog as at May 2020.

  1. BBVA: Helping Global Remote Working with Amazon AppStream 2.0 https://aws.amazon.com/blogs/architecture/bbva-helping-global-remote-working-with-amazon-appstream-2-0/

  2. Building a Scalable Document Pre-Processing Pipeline https://aws.amazon.com/blogs/architecture/building-a-scalable-document-pre-processing-pipeline/

  3. Serving Billions of Ads in Just 100 ms Using Amazon Elasticache for Redis https://aws.amazon.com/blogs/architecture/serving-billions-of-ads-with-amazon-elasticache-for-redis/

This sample of 3 diagrams is quite varied in complexity and features.

We’ll approach them in order of complexity.

2.1. AWSArchitectureBlogSample1

2.1.2. PlantUML Equivalent

playbutton_aws0 Press to play around with this diagram source online.

@startuml
!include <awslib/AWSCommon>
!include <awslib/AWSSimplified.puml>
!include <awslib/Compute/all.puml>
!include <awslib/mobile/all.puml>
!include <awslib/general/all.puml>
!include <awslib/GroupIcons/all.puml>

 skinparam linetype polyline
' skinparam linetype ortho

package "AWS Cloud" {
EC2(Smadex, "Smadex Service", " ")
}

Users(Users, "Users", " ")
TraditionalServer(AdExchange, "Ad Exchange", " ")
Mobile(Mobile, "Publisher app or web", " ")

Users -down-> Mobile: 1. Visits
Mobile -right-> AdExchange: 2. Start auction
AdExchange -right-> Smadex: 3. Bid request / response
Smadex -left-> Mobile: 4. Show Ad
Users -right-> Smadex: 5. Impression / click / install / event {request id}
@enduml

2.1.2.1. Source

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
@startuml
!include <awslib/AWSCommon>
!include <awslib/AWSSimplified.puml>
!include <awslib/Compute/all.puml>
!include <awslib/mobile/all.puml>
!include <awslib/general/all.puml>
!include <awslib/GroupIcons/all.puml>

 skinparam linetype polyline
' skinparam linetype ortho

package "AWS Cloud" {
EC2(Smadex, "Smadex Service", " ")
}

Users(Users, "Users", " ")
TraditionalServer(AdExchange, "Ad Exchange", " ")
Mobile(Mobile, "Publisher app or web", " ")

Users -down-> Mobile: 1. Visits
Mobile -right-> AdExchange: 2. Start auction
AdExchange -right-> Smadex: 3. Bid request / response
Smadex -left-> Mobile: 4. Show Ad
Users -right-> Smadex: 5. Impression / click / install / event {request id}
@enduml

2.1.3. Select an icon library

These are recent diagrams (April, May 2020) so use the newer AWS icon set from AWS i.e.

ref: https://github.com/awslabs/aws-icons-for-plantuml

We can see all the icons here: https://github.com/awslabs/aws-icons-for-plantuml/blob/master/AWSSymbols.md

2.1.4. Find Icons

@startuml
!include <awslib/AWSCommon>
!include <awslib/Compute/all.puml>
!include <awslib/mobile/all.puml>
!include <awslib/general/all.puml>

listsprites
@enduml

2.1.4.1. Play

playbutton_aws1 Press to play around with this diagram source online.

2.1.4.2. Source

1
2
3
4
5
6
7
8
@startuml
!include <awslib/AWSCommon>
!include <awslib/Compute/all.puml>
!include <awslib/mobile/all.puml>
!include <awslib/general/all.puml>

listsprites
@enduml

2.1.5. Gather the icons we need

  • For the EC2 icon on right of the diagram; for AWS icons, Orange is AWS Compute so we look at the compute icons.

  • Use our github trick to find “users”; they are in General.

  • The green box isn’t an AWS service - it’s showing a mobile/laptop client.

  • We need “Traditional Server” for “Ad Exchange”

  • For the box we’ll use a Deployment Diagram shape; `package` or `cloud`

Note

`autonumber` does not work in these diagrams. So we will manually number the arrows.

@startuml
!include <awslib/AWSCommon>
!include <awslib/Compute/all.puml>
!include <awslib/mobile/all.puml>
!include <awslib/general/all.puml>

EC2(EC2, "label", "tech")
Users(Users, "label", "tech")
TraditionalServer(TraditionalServer, "label", "tech")
Mobile(Mobile, "label", "tech")

@enduml

2.1.5.1. Play

playbutton_aws2 Press to play around with this diagram source online.

2.1.5.2. Source

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
@startuml
!include <awslib/AWSCommon>
!include <awslib/Compute/all.puml>
!include <awslib/mobile/all.puml>
!include <awslib/general/all.puml>

EC2(EC2, "label", "tech")
Users(Users, "label", "tech")
TraditionalServer(TraditionalServer, "label", "tech")
Mobile(Mobile, "label", "tech")

@enduml

2.1.6. Add Text To Icons

@startuml
!include <awslib/AWSCommon>
!include <awslib/Compute/all.puml>
!include <awslib/mobile/all.puml>
!include <awslib/general/all.puml>

EC2(EC2, "Smadex Service", " ")
Users(Users, "Users", " ")
TraditionalServer(TraditionalServer, "Ad Exchange", " ")
Mobile(Mobile, "Publisher app or web", " ")

@enduml

2.1.6.1. Play

playbutton_aws3 Press to play around with this diagram source online.

2.1.6.2. Source

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
@startuml
!include <awslib/AWSCommon>
!include <awslib/Compute/all.puml>
!include <awslib/mobile/all.puml>
!include <awslib/general/all.puml>

EC2(EC2, "Smadex Service", " ")
Users(Users, "Users", " ")
TraditionalServer(TraditionalServer, "Ad Exchange", " ")
Mobile(Mobile, "Publisher app or web", " ")

@enduml

2.1.7. Simplify The Icons

@startuml
!include <awslib/AWSCommon>
!include <awslib/AWSSimplified.puml>
!include <awslib/Compute/all.puml>
!include <awslib/mobile/all.puml>
!include <awslib/general/all.puml>

EC2(EC2, "Smadex Service", " ")
Users(Users, "Users", " ")
TraditionalServer(TraditionalServer, "Ad Exchange", " ")
Mobile(Mobile, "Publisher app or web", " ")

@enduml

2.1.7.1. Play

playbutton_aws4 Press to play around with this diagram source online.

2.1.7.2. Source

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
@startuml
!include <awslib/AWSCommon>
!include <awslib/AWSSimplified.puml>
!include <awslib/Compute/all.puml>
!include <awslib/mobile/all.puml>
!include <awslib/general/all.puml>

EC2(EC2, "Smadex Service", " ")
Users(Users, "Users", " ")
TraditionalServer(TraditionalServer, "Ad Exchange", " ")
Mobile(Mobile, "Publisher app or web", " ")

@enduml

2.1.8. Connect The Icons

@startuml
!include <awslib/AWSCommon>
!include <awslib/AWSSimplified.puml>
!include <awslib/Compute/all.puml>
!include <awslib/mobile/all.puml>
!include <awslib/general/all.puml>

EC2(Smadex, "Smadex Service", " ")
Users(Users, "Users", " ")
TraditionalServer(AdExchange, "Ad Exchange", " ")
Mobile(Mobile, "Publisher app or web", " ")

Users -down-> Mobile: 1. Visits
Mobile -right-> AdExchange: 2. Start auction
AdExchange -right-> Smadex: 3. Bid request / response
Smadex -left-> Mobile: 4. Show Ad
Users -right-> Smadex: 5. Impression / click / install / event {request id}
@enduml

2.1.8.1. Play

playbutton_aws5 Press to play around with this diagram source online.

2.1.8.2. Source

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
@startuml
!include <awslib/AWSCommon>
!include <awslib/AWSSimplified.puml>
!include <awslib/Compute/all.puml>
!include <awslib/mobile/all.puml>
!include <awslib/general/all.puml>

EC2(Smadex, "Smadex Service", " ")
Users(Users, "Users", " ")
TraditionalServer(AdExchange, "Ad Exchange", " ")
Mobile(Mobile, "Publisher app or web", " ")

Users -down-> Mobile: 1. Visits
Mobile -right-> AdExchange: 2. Start auction
AdExchange -right-> Smadex: 3. Bid request / response
Smadex -left-> Mobile: 4. Show Ad
Users -right-> Smadex: 5. Impression / click / install / event {request id}
@enduml

2.1.9. Change the Layout: ortho

@startuml
!include <awslib/AWSCommon>
!include <awslib/AWSSimplified.puml>
!include <awslib/Compute/all.puml>
!include <awslib/mobile/all.puml>
!include <awslib/general/all.puml>

' skinparam linetype polyline
 skinparam linetype ortho

EC2(Smadex, "Smadex Service", " ")
Users(Users, "Users", " ")
TraditionalServer(AdExchange, "Ad Exchange", " ")
Mobile(Mobile, "Publisher app or web", " ")

Users -down-> Mobile: 1. Visits
Mobile -right-> AdExchange: 2. Start auction
AdExchange -right-> Smadex: 3. Bid request / response
Smadex -left-> Mobile: 4. Show Ad
Users -right-> Smadex: 5. Impression / click / install / event {request id}
@enduml

2.1.9.1. Play

playbutton_aws6 Press to play around with this diagram source online.

2.1.9.2. Source

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
@startuml
!include <awslib/AWSCommon>
!include <awslib/AWSSimplified.puml>
!include <awslib/Compute/all.puml>
!include <awslib/mobile/all.puml>
!include <awslib/general/all.puml>

' skinparam linetype polyline
 skinparam linetype ortho

EC2(Smadex, "Smadex Service", " ")
Users(Users, "Users", " ")
TraditionalServer(AdExchange, "Ad Exchange", " ")
Mobile(Mobile, "Publisher app or web", " ")

Users -down-> Mobile: 1. Visits
Mobile -right-> AdExchange: 2. Start auction
AdExchange -right-> Smadex: 3. Bid request / response
Smadex -left-> Mobile: 4. Show Ad
Users -right-> Smadex: 5. Impression / click / install / event {request id}
@enduml

2.1.10. Change the Layout: polyline

@startuml
!include <awslib/AWSCommon>
!include <awslib/AWSSimplified.puml>
!include <awslib/Compute/all.puml>
!include <awslib/mobile/all.puml>
!include <awslib/general/all.puml>

skinparam linetype polyline
' skinparam linetype ortho

EC2(Smadex, "Smadex Service", " ")
Users(Users, "Users", " ")
TraditionalServer(AdExchange, "Ad Exchange", " ")
Mobile(Mobile, "Publisher app or web", " ")

Users -down-> Mobile: 1. Visits
Mobile -right-> AdExchange: 2. Start auction
AdExchange -right-> Smadex: 3. Bid request / response
Smadex -left-> Mobile: 4. Show Ad
Users -right-> Smadex: 5. Impression / click / install / event {request id}
@enduml

2.1.10.1. Play

playbutton_aws7 Press to play around with this diagram source online.

2.1.10.2. Source

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
@startuml
!include <awslib/AWSCommon>
!include <awslib/AWSSimplified.puml>
!include <awslib/Compute/all.puml>
!include <awslib/mobile/all.puml>
!include <awslib/general/all.puml>

skinparam linetype polyline
' skinparam linetype ortho

EC2(Smadex, "Smadex Service", " ")
Users(Users, "Users", " ")
TraditionalServer(AdExchange, "Ad Exchange", " ")
Mobile(Mobile, "Publisher app or web", " ")

Users -down-> Mobile: 1. Visits
Mobile -right-> AdExchange: 2. Start auction
AdExchange -right-> Smadex: 3. Bid request / response
Smadex -left-> Mobile: 4. Show Ad
Users -right-> Smadex: 5. Impression / click / install / event {request id}
@enduml

2.1.11. Add A Box: package

@startuml
!include <awslib/AWSCommon>
!include <awslib/AWSSimplified.puml>
!include <awslib/Compute/all.puml>
!include <awslib/mobile/all.puml>
!include <awslib/general/all.puml>
!include <awslib/GroupIcons/all.puml>

 skinparam linetype polyline
' skinparam linetype ortho

package "AWS Cloud" {
EC2(Smadex, "Smadex Service", " ")
}

Users(Users, "Users", " ")
TraditionalServer(AdExchange, "Ad Exchange", " ")
Mobile(Mobile, "Publisher app or web", " ")

Users -down-> Mobile: 1. Visits
Mobile -right-> AdExchange: 2. Start auction
AdExchange -right-> Smadex: 3. Bid request / response
Smadex -left-> Mobile: 4. Show Ad
Users -right-> Smadex: 5. Impression / click / install / event {request id}
@enduml

2.1.11.1. Play

playbutton_aws8 Press to play around with this diagram source online.

2.1.11.2. Source

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
@startuml
!include <awslib/AWSCommon>
!include <awslib/AWSSimplified.puml>
!include <awslib/Compute/all.puml>
!include <awslib/mobile/all.puml>
!include <awslib/general/all.puml>
!include <awslib/GroupIcons/all.puml>

 skinparam linetype polyline
' skinparam linetype ortho

package "AWS Cloud" {
EC2(Smadex, "Smadex Service", " ")
}

Users(Users, "Users", " ")
TraditionalServer(AdExchange, "Ad Exchange", " ")
Mobile(Mobile, "Publisher app or web", " ")

Users -down-> Mobile: 1. Visits
Mobile -right-> AdExchange: 2. Start auction
AdExchange -right-> Smadex: 3. Bid request / response
Smadex -left-> Mobile: 4. Show Ad
Users -right-> Smadex: 5. Impression / click / install / event {request id}
@enduml

2.2. AWSArchitectureBlogSample2

2.2.2. PlantUML Equivalent

playbutton_aws2_0 Press to play around with this diagram source online.

@startuml
!include <awslib/AWSCommon>
!include <awslib/AWSSimplified.puml>
!include <awslib/Compute/all.puml>
!include <awslib/mobile/all.puml>
!include <awslib/general/all.puml>
!include <awslib/GroupIcons/all.puml>
!include <awslib/Storage/all.puml>
!include <awslib/ManagementAndGovernance/all.puml>
!include <awslib/CustomerEngagement/all.puml>
!include <awslib/MachineLearning/all.puml>
!include <awslib/NetworkingAndContentDelivery/all.puml>
!include <awslib/Database/all.puml>
!include <awslib/ApplicationIntegration/all.puml>





'Compute/General
'Storage/SimpleStorageServiceS3.png
'ApplicationIntegration/SQS.png
'Compute/Lambda.png
'Compute/EC2
'ManagementAndGovernance/CloudWatch.png
'CustomerEngagement/SESEmail.png
'MachineLearning/SageMaker.png
''Mobile/APIGateway.png
'NetworkingAndContentDelivery/APIGateway2.png
'Database/Aurora.png
'ApplicationIntegration/SQSQueue.png


skinparam linetype polyline
' skinparam linetype ortho

'top left section 
'-------------------------------------------------------------
package EC2_Instance {
General(IngestionApp, "Ingestion App", " ")
General(ChunkingApp, "Chunking Orchestration App", " ")
}

SimpleStorageServiceS3(S3Staging, "Amazon S3 Staging Bucket", " ")
SQS(SQSIngest, "Amazon SQS Ingest Queue", " ")

Lambda(LambdaTrigger, "AWS Lambda Trigger Function", " ")

LambdaTrigger -up-> IngestionApp
IngestionApp -up-> SQSIngest
SQSIngest -down-> ChunkingApp
S3Staging <-down-> EC2_Instance

'top right section 
'-------------------------------------------------------------
together {
SQS(SQSLargeFileQueue, "Amazon SQS Large File Queue", " ")
SQS(SQSSmallFileQueue, "Amazon SQS Small File Queue", " ")
SQS(SQSSingleFileQueue, "Amazon SQS Single File Queue", " ")

EC2(LargeFileChunkingAppEC2, "Large File Chunking App on EC2", " ")
Lambda(LambdaSmallFileChunking, "Small File Chunking Lambda", " ")
Lambda(ImageConversionLambdaFunction, "Image Conversion Lambda Function", " ")
}
'todo dashed line boundary
package DLQ {
SQSQueue(DLQ1, "DLQ", " ")
SQSQueue(DLQ2, "DLQ", " ")
SQSQueue(DLQ3, "DLQ", " ")
}

ChunkingApp -right-> SQSLargeFileQueue
ChunkingApp -right-> SQSSmallFileQueue
ChunkingApp -right-> SQSSingleFileQueue

SQSLargeFileQueue -right-> LargeFileChunkingAppEC2
LargeFileChunkingAppEC2 -down-> SQSSmallFileQueue
SQSSmallFileQueue -right-> LambdaSmallFileChunking
LambdaSmallFileChunking -down-> SQSSingleFileQueue
SQSSingleFileQueue -right-> ImageConversionLambdaFunction

'todo dashed line
SQSLargeFileQueue -down-> DLQ1
SQSSmallFileQueue -down-> DLQ2
SQSSingleFileQueue -down-> DLQ3


'bottom right section 
'-------------------------------------------------------------

SimpleStorageServiceS3(S3Images, "Amazon S3 Images Bucket", " ")
EC2(EC2DLQFailsafeApp, "DLQ Failsafe App on EC2", " ")
SQS(SQSConvertedImageQueue, "Amazon SQS Converted Image Queue", " ")
Lambda(LambdaInferenceInvocation, "Inference Invocation Lambda Function", " ")
Aurora(Aurora, "Amazon Aurora", " ")
APIGateway(AmazonAPIGateway, "Amazon API Gateway", "")
SageMaker(AmazonSageMaker, "Amazon SageMaker Endpoint", "")

DLQ1 -down-> EC2DLQFailsafeApp
DLQ2 -down-> EC2DLQFailsafeApp
DLQ3 -down-> EC2DLQFailsafeApp

EC2DLQFailsafeApp -right-> S3Images

ImageConversionLambdaFunction -down-> S3Images
S3Images -down-> SQSConvertedImageQueue
SQSConvertedImageQueue -left-> LambdaInferenceInvocation
LambdaInferenceInvocation -down-> Aurora
LambdaInferenceInvocation <-left-> AmazonAPIGateway
AmazonAPIGateway <-left-> AmazonSageMaker


'bottom left section 
'-------------------------------------------------------------

CloudWatch(CloudWatch, "Amazon Cloudwatch", " ")
SNS(SNS1, "Amazon SNS", "")
SESEmail(SESEmail, "Email Notification", "")

CloudWatch -right-> DLQ
CloudWatch -left-> SNS1
SNS1 -left-> SESEmail

footer %filename() rendered with PlantUML version %version()\nThe Hitchhiker’s Guide to PlantUML
@enduml

Tip

In general, I recommend starting a diagram without forcing the arrow directions to let PlantUML optimise the layout; then tweak the result.

Because we are trying to compare to an existing complex diagram, I will force the layout to match the original - but only up to a point that allows clarity and comparison.

Tip

Because there are a lot of parts to this diagram, I built it step-by-step in sections to validate as I went - which makes it easier to fix a typo, or get feedback as we go. Not all steps are shown here - only the final ones - but the PlantUML source code files for each step are in the directory with the source and documentation.

2.2.3. First Pass

@startuml
!include <awslib/AWSCommon>
!include <awslib/AWSSimplified.puml>
!include <awslib/Compute/all.puml>
!include <awslib/mobile/all.puml>
!include <awslib/general/all.puml>
!include <awslib/GroupIcons/all.puml>
!include <awslib/Storage/all.puml>
!include <awslib/ManagementAndGovernance/all.puml>
!include <awslib/CustomerEngagement/all.puml>
!include <awslib/MachineLearning/all.puml>
!include <awslib/NetworkingAndContentDelivery/all.puml>
!include <awslib/Database/all.puml>
!include <awslib/ApplicationIntegration/all.puml>
!include <awslib/ApplicationIntegration/SNS.puml>
!include <awslib/CustomerEngagement/SESEmail.puml>



'Compute/General
'Storage/SimpleStorageServiceS3.png
'ApplicationIntegration/SQS.png
'Compute/Lambda.png
'Compute/EC2
'ManagementAndGovernance/CloudWatch.png
'CustomerEngagement/SESEmail.png
'MachineLearning/SageMaker.png
''Mobile/APIGateway.png
'NetworkingAndContentDelivery/APIGateway2.png
'Database/Aurora.png
'ApplicationIntegration/SQSQueue.png


skinparam linetype polyline
' skinparam linetype ortho

'top left section 
'-------------------------------------------------------------
package EC2_Instance {
General(IngestionApp, "Ingestion App", " ")
General(ChunkingApp, "Chunking Orchestration App", " ")
}

SimpleStorageServiceS3(S3Staging, "Amazon S3 Staging Bucket", " ")
SQS(SQSIngest, "Amazon SQS Ingest Queue", " ")

Lambda(LambdaTrigger, "AWS Lambda Trigger Function", " ")

LambdaTrigger -up-> IngestionApp
IngestionApp -up-> SQSIngest
SQSIngest -down-> ChunkingApp
S3Staging -down-> EC2_Instance

'top right section 
'-------------------------------------------------------------
SQS(SQSLargeFileQueue, "Amazon SQS Large File Queue", " ")
SQS(SQSSmallFileQueue, "Amazon SQS Small File Queue", " ")
SQS(SQSSingleFileQueue, "Amazon SQS Single File Queue", " ")

EC2(LargeFileChunkingAppEC2, "Large File Chunking App on EC2", " ")
Lambda(LambdaSmallFileChunking, "Small File Chunking Lambda", " ")
Lambda(ImageConversionLambdaFunction, "Image Conversion Lambda Function", " ")

'todo dashed line boundary
package DLQ {
SQSQueue(DLQ1, "DLQ", " ")
SQSQueue(DLQ2, "DLQ", " ")
SQSQueue(DLQ3, "DLQ", " ")
}

ChunkingApp -right-> SQSLargeFileQueue
ChunkingApp -right-> SQSSmallFileQueue
ChunkingApp -right-> SQSSingleFileQueue

SQSLargeFileQueue -right-> LargeFileChunkingAppEC2
LargeFileChunkingAppEC2 -down-> SQSSmallFileQueue
SQSSmallFileQueue -right-> LambdaSmallFileChunking
LambdaSmallFileChunking -down-> SQSSingleFileQueue
SQSSingleFileQueue -right-> ImageConversionLambdaFunction

'todo dashed line
SQSLargeFileQueue -down-> DLQ1
SQSSmallFileQueue -down-> DLQ2
SQSSingleFileQueue -down-> DLQ3


'bottom right section 
'-------------------------------------------------------------

SimpleStorageServiceS3(S3Images, "Amazon S3 Images Bucket", " ")
EC2(EC2DLQFailsafeApp, "DLQ Failsafe App on EC2", " ")
SQS(SQSConvertedImageQueue, "Amazon SQS Converted Image Queue", " ")
Lambda(LambdaInferenceInvocation, "Inference Invocation Lambda Function", " ")
Aurora(Aurora, "Amazon Aurora", " ")
APIGateway(AmazonAPIGateway, "Amazon API Gateway", "")
SageMaker(AmazonSageMaker, "Amazon SageMaker Endpoint", "")

DLQ1 -down-> EC2DLQFailsafeApp
DLQ2 -down-> EC2DLQFailsafeApp
DLQ3 -down-> EC2DLQFailsafeApp

EC2DLQFailsafeApp -right-> S3Images

ImageConversionLambdaFunction -down-> S3Images
S3Images -down-> SQSConvertedImageQueue
SQSConvertedImageQueue -left-> LambdaInferenceInvocation
LambdaInferenceInvocation -down-> Aurora
'LambdaInferenceInvocation -left-> APIGateway
'APIGateway -left-> SageMaker


'bottom left section 
'-------------------------------------------------------------

CloudWatch(CloudWatch, "Amazon Cloudwatch", " ")
SNS(SNS1, "Amazon SNS", "")
SESEmail(SESEmail, "Email Notification", "")

CloudWatch --> DLQ
CloudWatch -down-> SNS1
SNS1 -down-> SESEmail
@enduml

2.2.3.1. Play

playbutton_aws2_1 Press to play around with this diagram source online.

2.2.3.2. Source

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
@startuml
!include <awslib/AWSCommon>
!include <awslib/AWSSimplified.puml>
!include <awslib/Compute/all.puml>
!include <awslib/mobile/all.puml>
!include <awslib/general/all.puml>
!include <awslib/GroupIcons/all.puml>
!include <awslib/Storage/all.puml>
!include <awslib/ManagementAndGovernance/all.puml>
!include <awslib/CustomerEngagement/all.puml>
!include <awslib/MachineLearning/all.puml>
!include <awslib/NetworkingAndContentDelivery/all.puml>
!include <awslib/Database/all.puml>
!include <awslib/ApplicationIntegration/all.puml>
!include <awslib/ApplicationIntegration/SNS.puml>
!include <awslib/CustomerEngagement/SESEmail.puml>



'Compute/General
'Storage/SimpleStorageServiceS3.png
'ApplicationIntegration/SQS.png
'Compute/Lambda.png
'Compute/EC2
'ManagementAndGovernance/CloudWatch.png
'CustomerEngagement/SESEmail.png
'MachineLearning/SageMaker.png
''Mobile/APIGateway.png
'NetworkingAndContentDelivery/APIGateway2.png
'Database/Aurora.png
'ApplicationIntegration/SQSQueue.png


skinparam linetype polyline
' skinparam linetype ortho

'top left section 
'-------------------------------------------------------------
package EC2_Instance {
General(IngestionApp, "Ingestion App", " ")
General(ChunkingApp, "Chunking Orchestration App", " ")
}

SimpleStorageServiceS3(S3Staging, "Amazon S3 Staging Bucket", " ")
SQS(SQSIngest, "Amazon SQS Ingest Queue", " ")

Lambda(LambdaTrigger, "AWS Lambda Trigger Function", " ")

LambdaTrigger -up-> IngestionApp
IngestionApp -up-> SQSIngest
SQSIngest -down-> ChunkingApp
S3Staging -down-> EC2_Instance

'top right section 
'-------------------------------------------------------------
SQS(SQSLargeFileQueue, "Amazon SQS Large File Queue", " ")
SQS(SQSSmallFileQueue, "Amazon SQS Small File Queue", " ")
SQS(SQSSingleFileQueue, "Amazon SQS Single File Queue", " ")

EC2(LargeFileChunkingAppEC2, "Large File Chunking App on EC2", " ")
Lambda(LambdaSmallFileChunking, "Small File Chunking Lambda", " ")
Lambda(ImageConversionLambdaFunction, "Image Conversion Lambda Function", " ")

'todo dashed line boundary
package DLQ {
SQSQueue(DLQ1, "DLQ", " ")
SQSQueue(DLQ2, "DLQ", " ")
SQSQueue(DLQ3, "DLQ", " ")
}

ChunkingApp -right-> SQSLargeFileQueue
ChunkingApp -right-> SQSSmallFileQueue
ChunkingApp -right-> SQSSingleFileQueue

SQSLargeFileQueue -right-> LargeFileChunkingAppEC2
LargeFileChunkingAppEC2 -down-> SQSSmallFileQueue
SQSSmallFileQueue -right-> LambdaSmallFileChunking
LambdaSmallFileChunking -down-> SQSSingleFileQueue
SQSSingleFileQueue -right-> ImageConversionLambdaFunction

'todo dashed line
SQSLargeFileQueue -down-> DLQ1
SQSSmallFileQueue -down-> DLQ2
SQSSingleFileQueue -down-> DLQ3


'bottom right section 
'-------------------------------------------------------------

SimpleStorageServiceS3(S3Images, "Amazon S3 Images Bucket", " ")
EC2(EC2DLQFailsafeApp, "DLQ Failsafe App on EC2", " ")
SQS(SQSConvertedImageQueue, "Amazon SQS Converted Image Queue", " ")
Lambda(LambdaInferenceInvocation, "Inference Invocation Lambda Function", " ")
Aurora(Aurora, "Amazon Aurora", " ")
APIGateway(AmazonAPIGateway, "Amazon API Gateway", "")
SageMaker(AmazonSageMaker, "Amazon SageMaker Endpoint", "")

DLQ1 -down-> EC2DLQFailsafeApp
DLQ2 -down-> EC2DLQFailsafeApp
DLQ3 -down-> EC2DLQFailsafeApp

EC2DLQFailsafeApp -right-> S3Images

ImageConversionLambdaFunction -down-> S3Images
S3Images -down-> SQSConvertedImageQueue
SQSConvertedImageQueue -left-> LambdaInferenceInvocation
LambdaInferenceInvocation -down-> Aurora
'LambdaInferenceInvocation -left-> APIGateway
'APIGateway -left-> SageMaker


'bottom left section 
'-------------------------------------------------------------

CloudWatch(CloudWatch, "Amazon Cloudwatch", " ")
SNS(SNS1, "Amazon SNS", "")
SESEmail(SESEmail, "Email Notification", "")

CloudWatch --> DLQ
CloudWatch -down-> SNS1
SNS1 -down-> SESEmail
@enduml

2.2.4. Second Pass: Tweak

  1. For clarity, force the cloudwatch branch to go horizontal and connect from left to DLQ.

  2. Use `together` to group the SQS and File processing icons.

  3. I did not change the boxes line style or colour.

@startuml
!include <awslib/AWSCommon>
!include <awslib/AWSSimplified.puml>
!include <awslib/Compute/all.puml>
!include <awslib/mobile/all.puml>
!include <awslib/general/all.puml>
!include <awslib/GroupIcons/all.puml>
!include <awslib/Storage/all.puml>
!include <awslib/ManagementAndGovernance/all.puml>
!include <awslib/CustomerEngagement/all.puml>
!include <awslib/MachineLearning/all.puml>
!include <awslib/NetworkingAndContentDelivery/all.puml>
!include <awslib/Database/all.puml>
!include <awslib/ApplicationIntegration/all.puml>





'Compute/General
'Storage/SimpleStorageServiceS3.png
'ApplicationIntegration/SQS.png
'Compute/Lambda.png
'Compute/EC2
'ManagementAndGovernance/CloudWatch.png
'CustomerEngagement/SESEmail.png
'MachineLearning/SageMaker.png
''Mobile/APIGateway.png
'NetworkingAndContentDelivery/APIGateway2.png
'Database/Aurora.png
'ApplicationIntegration/SQSQueue.png


skinparam linetype polyline
' skinparam linetype ortho

'top left section 
'-------------------------------------------------------------
package EC2_Instance {
General(IngestionApp, "Ingestion App", " ")
General(ChunkingApp, "Chunking Orchestration App", " ")
}

SimpleStorageServiceS3(S3Staging, "Amazon S3 Staging Bucket", " ")
SQS(SQSIngest, "Amazon SQS Ingest Queue", " ")

Lambda(LambdaTrigger, "AWS Lambda Trigger Function", " ")

LambdaTrigger -up-> IngestionApp
IngestionApp -up-> SQSIngest
SQSIngest -down-> ChunkingApp
S3Staging <-down-> EC2_Instance

'top right section 
'-------------------------------------------------------------
together {
SQS(SQSLargeFileQueue, "Amazon SQS Large File Queue", " ")
SQS(SQSSmallFileQueue, "Amazon SQS Small File Queue", " ")
SQS(SQSSingleFileQueue, "Amazon SQS Single File Queue", " ")

EC2(LargeFileChunkingAppEC2, "Large File Chunking App on EC2", " ")
Lambda(LambdaSmallFileChunking, "Small File Chunking Lambda", " ")
Lambda(ImageConversionLambdaFunction, "Image Conversion Lambda Function", " ")
}
'todo dashed line boundary
package DLQ {
SQSQueue(DLQ1, "DLQ", " ")
SQSQueue(DLQ2, "DLQ", " ")
SQSQueue(DLQ3, "DLQ", " ")
}

ChunkingApp -right-> SQSLargeFileQueue
ChunkingApp -right-> SQSSmallFileQueue
ChunkingApp -right-> SQSSingleFileQueue

SQSLargeFileQueue -right-> LargeFileChunkingAppEC2
LargeFileChunkingAppEC2 -down-> SQSSmallFileQueue
SQSSmallFileQueue -right-> LambdaSmallFileChunking
LambdaSmallFileChunking -down-> SQSSingleFileQueue
SQSSingleFileQueue -right-> ImageConversionLambdaFunction

'todo dashed line
SQSLargeFileQueue -down-> DLQ1
SQSSmallFileQueue -down-> DLQ2
SQSSingleFileQueue -down-> DLQ3


'bottom right section 
'-------------------------------------------------------------

SimpleStorageServiceS3(S3Images, "Amazon S3 Images Bucket", " ")
EC2(EC2DLQFailsafeApp, "DLQ Failsafe App on EC2", " ")
SQS(SQSConvertedImageQueue, "Amazon SQS Converted Image Queue", " ")
Lambda(LambdaInferenceInvocation, "Inference Invocation Lambda Function", " ")
Aurora(Aurora, "Amazon Aurora", " ")
APIGateway(AmazonAPIGateway, "Amazon API Gateway", "")
SageMaker(AmazonSageMaker, "Amazon SageMaker Endpoint", "")

DLQ1 -down-> EC2DLQFailsafeApp
DLQ2 -down-> EC2DLQFailsafeApp
DLQ3 -down-> EC2DLQFailsafeApp

EC2DLQFailsafeApp -right-> S3Images

ImageConversionLambdaFunction -down-> S3Images
S3Images -down-> SQSConvertedImageQueue
SQSConvertedImageQueue -left-> LambdaInferenceInvocation
LambdaInferenceInvocation -down-> Aurora
LambdaInferenceInvocation <-left-> AmazonAPIGateway
AmazonAPIGateway <-left-> AmazonSageMaker


'bottom left section 
'-------------------------------------------------------------

CloudWatch(CloudWatch, "Amazon Cloudwatch", " ")
SNS(SNS1, "Amazon SNS", "")
SESEmail(SESEmail, "Email Notification", "")

CloudWatch -right-> DLQ
CloudWatch -left-> SNS1
SNS1 -left-> SESEmail

footer %filename() rendered with PlantUML version %version()\nThe Hitchhiker’s Guide to PlantUML
@enduml

2.2.4.1. Play

playbutton_aws2_2 Press to play around with this diagram source online.

2.2.4.2. Source

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
@startuml
!include <awslib/AWSCommon>
!include <awslib/AWSSimplified.puml>
!include <awslib/Compute/all.puml>
!include <awslib/mobile/all.puml>
!include <awslib/general/all.puml>
!include <awslib/GroupIcons/all.puml>
!include <awslib/Storage/all.puml>
!include <awslib/ManagementAndGovernance/all.puml>
!include <awslib/CustomerEngagement/all.puml>
!include <awslib/MachineLearning/all.puml>
!include <awslib/NetworkingAndContentDelivery/all.puml>
!include <awslib/Database/all.puml>
!include <awslib/ApplicationIntegration/all.puml>





'Compute/General
'Storage/SimpleStorageServiceS3.png
'ApplicationIntegration/SQS.png
'Compute/Lambda.png
'Compute/EC2
'ManagementAndGovernance/CloudWatch.png
'CustomerEngagement/SESEmail.png
'MachineLearning/SageMaker.png
''Mobile/APIGateway.png
'NetworkingAndContentDelivery/APIGateway2.png
'Database/Aurora.png
'ApplicationIntegration/SQSQueue.png


skinparam linetype polyline
' skinparam linetype ortho

'top left section 
'-------------------------------------------------------------
package EC2_Instance {
General(IngestionApp, "Ingestion App", " ")
General(ChunkingApp, "Chunking Orchestration App", " ")
}

SimpleStorageServiceS3(S3Staging, "Amazon S3 Staging Bucket", " ")
SQS(SQSIngest, "Amazon SQS Ingest Queue", " ")

Lambda(LambdaTrigger, "AWS Lambda Trigger Function", " ")

LambdaTrigger -up-> IngestionApp
IngestionApp -up-> SQSIngest
SQSIngest -down-> ChunkingApp
S3Staging <-down-> EC2_Instance

'top right section 
'-------------------------------------------------------------
together {
SQS(SQSLargeFileQueue, "Amazon SQS Large File Queue", " ")
SQS(SQSSmallFileQueue, "Amazon SQS Small File Queue", " ")
SQS(SQSSingleFileQueue, "Amazon SQS Single File Queue", " ")

EC2(LargeFileChunkingAppEC2, "Large File Chunking App on EC2", " ")
Lambda(LambdaSmallFileChunking, "Small File Chunking Lambda", " ")
Lambda(ImageConversionLambdaFunction, "Image Conversion Lambda Function", " ")
}
'todo dashed line boundary
package DLQ {
SQSQueue(DLQ1, "DLQ", " ")
SQSQueue(DLQ2, "DLQ", " ")
SQSQueue(DLQ3, "DLQ", " ")
}

ChunkingApp -right-> SQSLargeFileQueue
ChunkingApp -right-> SQSSmallFileQueue
ChunkingApp -right-> SQSSingleFileQueue

SQSLargeFileQueue -right-> LargeFileChunkingAppEC2
LargeFileChunkingAppEC2 -down-> SQSSmallFileQueue
SQSSmallFileQueue -right-> LambdaSmallFileChunking
LambdaSmallFileChunking -down-> SQSSingleFileQueue
SQSSingleFileQueue -right-> ImageConversionLambdaFunction

'todo dashed line
SQSLargeFileQueue -down-> DLQ1
SQSSmallFileQueue -down-> DLQ2
SQSSingleFileQueue -down-> DLQ3


'bottom right section 
'-------------------------------------------------------------

SimpleStorageServiceS3(S3Images, "Amazon S3 Images Bucket", " ")
EC2(EC2DLQFailsafeApp, "DLQ Failsafe App on EC2", " ")
SQS(SQSConvertedImageQueue, "Amazon SQS Converted Image Queue", " ")
Lambda(LambdaInferenceInvocation, "Inference Invocation Lambda Function", " ")
Aurora(Aurora, "Amazon Aurora", " ")
APIGateway(AmazonAPIGateway, "Amazon API Gateway", "")
SageMaker(AmazonSageMaker, "Amazon SageMaker Endpoint", "")

DLQ1 -down-> EC2DLQFailsafeApp
DLQ2 -down-> EC2DLQFailsafeApp
DLQ3 -down-> EC2DLQFailsafeApp

EC2DLQFailsafeApp -right-> S3Images

ImageConversionLambdaFunction -down-> S3Images
S3Images -down-> SQSConvertedImageQueue
SQSConvertedImageQueue -left-> LambdaInferenceInvocation
LambdaInferenceInvocation -down-> Aurora
LambdaInferenceInvocation <-left-> AmazonAPIGateway
AmazonAPIGateway <-left-> AmazonSageMaker


'bottom left section 
'-------------------------------------------------------------

CloudWatch(CloudWatch, "Amazon Cloudwatch", " ")
SNS(SNS1, "Amazon SNS", "")
SESEmail(SESEmail, "Email Notification", "")

CloudWatch -right-> DLQ
CloudWatch -left-> SNS1
SNS1 -left-> SESEmail

footer %filename() rendered with PlantUML version %version()\nThe Hitchhiker’s Guide to PlantUML
@enduml

2.3. AWSArchitectureBlogSample3

2.3.1. PlantUML Equivalent

playbutton_aws30 Press to play around with this diagram source online.

@startuml
!include <awslib/AWSCommon>
!include <awslib/AWSSimplified.puml>
!include <awslib/Compute/all.puml>
!include <awslib/mobile/all.puml>
!include <awslib/general/all.puml>
!include <awslib/GroupIcons/all.puml>
!include <awslib/CustomerEngagement/all.puml>
!include <awslib/NetworkingAndContentDelivery/all.puml>
!include <awslib/EndUserComputing/all.puml>
!include <awslib/ApplicationIntegration/all.puml>

'skinparam linetype polyline


!unquoted procedure $PublicSubnet($MySprite, $alias, $description="", $label="", $technology="", $scale=1, $colour="blue", $shape="", $textsize="18")

    skinparam rectangle {
        backgroundColor<<$alias>> e6ffef
        borderColor<<$alias>> e6ffef
        shadowing<<$alias>> true
    }
    rectangle $alias <<$alias>> as "
        <color:3F8624><$VPCSubnetPublic*.4> Public Subnet</color>\n
        <color:$colour><$MySprite></color>\n$label" 

!endprocedure

!unquoted procedure $PrivateSubnet($MySprite, $alias, $description="", $label="", $technology="", $scale=1, $colour="blue", $shape="", $textsize="18")

    skinparam rectangle {
        backgroundColor<<$alias>> e6fbff
        borderColor<<$alias>> e6fbff
        shadowing<<$alias>> true
    }
    
    rectangle $alias <<$alias>> as "
        <color:3B48CC><$VPCSubnetPrivate*.4> Private Subnet</color>\n
        <color:$colour><$MySprite></color>\n$label" 

!endprocedure


!unquoted procedure $VPCNet($MySprite, $alias, $description="", $label="", $technology="", $scale=1, $colour="blue", $shape="", $textsize="18")

    skinparam rectangle {
        backgroundColor<<$alias>> white
        borderColor<<$alias>> e6fbff
        shadowing<<$alias>> true
    }
    
    rectangle $alias <<$alias>> as "
        <color:3F8624><$VPC*.4></color> <color:grey>$label</color>\n
        <color:$colour><$MySprite></color>\n$description" 

!endprocedure

'note the "=" denotes heading 1
skinparam rectangle {
        backgroundColor<<BBVA>> white
        borderColor<<BBVA>> white
        shadowing<<$alias>> false
    }
rectangle  BBVA <<BBVA>> as "
        =<color:blue>BBVA</color>\n
        \nAuthentication Service" 



AutoScalingGroup(AutoScalingGroup1, "Auto Scaling Group", "")
ELBNetworkLoadBalancer(ELBNetworkLoadBalancer, "Network Load Balancer", " ")
VPCInternetGateway(VPCInternetGateway, "Internet Gateway", " ")
InternetAlt1(InternetAlt1, "Internet", " ")
'VPCElasticNetworkInterface(VPCElasticNetworkInterface, " ", " ")

VPCInternetGateway -u-> InternetAlt1
VPCVPNConnection(VPCVPNConnection, "VPN\nConnection", " ")
DirectConnect(DirectConnect, "Direct\nConnect", " ")
TransitGateway(S3TransitGatewayStaging, "TransitGateway", " ")

VPCCustomerGateway(VPCCustomerGateway, " ", " ")
'Appstream2_0(Appstream2_0, " ", " ")
Cloudalt(Cloudalt, " ", " ")
User(User, "BBVA Employee", " ")


'package "BBVA VPC 2"
'{

    'package "Availability Zone 1"
    '{

        $PublicSubnet($EC2Instance, EC2Instance1, $label="Proxy Instance",  $colour="D86613")

        $PrivateSubnet($ELBNetworkLoadBalancer, ELBNetworkLoadBalancer1, $colour="D86613")

        EC2Instance1 --[hidden]> ELBNetworkLoadBalancer1

    '}


    'package "Availability Zone 2"
    '{

        $PublicSubnet($EC2Instance, EC2Instance2, $label="Proxy Instance",  $colour="D86613")

        $PrivateSubnet($ELBNetworkLoadBalancer, ELBNetworkLoadBalancer2, $colour="D86613")

        EC2Instance2 --[hidden]> ELBNetworkLoadBalancer2

    '}
'}


$VPCNet($VPCElasticNetworkInterface, VPCElasticNetworkInterface2, $label="BBVA VPC 1", $colour="purple")
$VPCNet($Appstream2_0, Appstream2_02, $label="Appstream 2.0 VPC", $description="Appstream 2.0", $colour="purple")
'$MyOnPrem($VPCCustomerGateway, $label="Customer Gateway")

EC2Instance1 -r-> AutoScalingGroup1
AutoScalingGroup1 -r-> EC2Instance2

ELBNetworkLoadBalancer1 -r-> ELBNetworkLoadBalancer
ELBNetworkLoadBalancer -r->ELBNetworkLoadBalancer2

S3TransitGatewayStaging -u-> DirectConnect
S3TransitGatewayStaging -u-> VPCVPNConnection
S3TransitGatewayStaging -> EC2Instance1
DirectConnect -u-> VPCCustomerGateway
VPCVPNConnection -u-> VPCCustomerGateway

Appstream2_02 -d-> VPCElasticNetworkInterface2 
VPCElasticNetworkInterface2 -> S3TransitGatewayStaging


User -d-> BBVA 
BBVA -d-> Appstream2_02


@enduml

2.3.1.1. Source

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
@startuml
!include <awslib/AWSCommon>
!include <awslib/AWSSimplified.puml>
!include <awslib/Compute/all.puml>
!include <awslib/mobile/all.puml>
!include <awslib/general/all.puml>
!include <awslib/GroupIcons/all.puml>
!include <awslib/CustomerEngagement/all.puml>
!include <awslib/NetworkingAndContentDelivery/all.puml>
!include <awslib/EndUserComputing/all.puml>
!include <awslib/ApplicationIntegration/all.puml>

'skinparam linetype polyline


!unquoted procedure $PublicSubnet($MySprite, $alias, $description="", $label="", $technology="", $scale=1, $colour="blue", $shape="", $textsize="18")

    skinparam rectangle {
        backgroundColor<<$alias>> e6ffef
        borderColor<<$alias>> e6ffef
        shadowing<<$alias>> true
    }
    rectangle $alias <<$alias>> as "
        <color:3F8624><$VPCSubnetPublic*.4> Public Subnet</color>\n
        <color:$colour><$MySprite></color>\n$label" 

!endprocedure

!unquoted procedure $PrivateSubnet($MySprite, $alias, $description="", $label="", $technology="", $scale=1, $colour="blue", $shape="", $textsize="18")

    skinparam rectangle {
        backgroundColor<<$alias>> e6fbff
        borderColor<<$alias>> e6fbff
        shadowing<<$alias>> true
    }
    
    rectangle $alias <<$alias>> as "
        <color:3B48CC><$VPCSubnetPrivate*.4> Private Subnet</color>\n
        <color:$colour><$MySprite></color>\n$label" 

!endprocedure


!unquoted procedure $VPCNet($MySprite, $alias, $description="", $label="", $technology="", $scale=1, $colour="blue", $shape="", $textsize="18")

    skinparam rectangle {
        backgroundColor<<$alias>> white
        borderColor<<$alias>> e6fbff
        shadowing<<$alias>> true
    }
    
    rectangle $alias <<$alias>> as "
        <color:3F8624><$VPC*.4></color> <color:grey>$label</color>\n
        <color:$colour><$MySprite></color>\n$description" 

!endprocedure

'note the "=" denotes heading 1
skinparam rectangle {
        backgroundColor<<BBVA>> white
        borderColor<<BBVA>> white
        shadowing<<$alias>> false
    }
rectangle  BBVA <<BBVA>> as "
        =<color:blue>BBVA</color>\n
        \nAuthentication Service" 



AutoScalingGroup(AutoScalingGroup1, "Auto Scaling Group", "")
ELBNetworkLoadBalancer(ELBNetworkLoadBalancer, "Network Load Balancer", " ")
VPCInternetGateway(VPCInternetGateway, "Internet Gateway", " ")
InternetAlt1(InternetAlt1, "Internet", " ")
'VPCElasticNetworkInterface(VPCElasticNetworkInterface, " ", " ")

VPCInternetGateway -u-> InternetAlt1
VPCVPNConnection(VPCVPNConnection, "VPN\nConnection", " ")
DirectConnect(DirectConnect, "Direct\nConnect", " ")
TransitGateway(S3TransitGatewayStaging, "TransitGateway", " ")

VPCCustomerGateway(VPCCustomerGateway, " ", " ")
'Appstream2_0(Appstream2_0, " ", " ")
Cloudalt(Cloudalt, " ", " ")
User(User, "BBVA Employee", " ")


'package "BBVA VPC 2"
'{

    'package "Availability Zone 1"
    '{

        $PublicSubnet($EC2Instance, EC2Instance1, $label="Proxy Instance",  $colour="D86613")

        $PrivateSubnet($ELBNetworkLoadBalancer, ELBNetworkLoadBalancer1, $colour="D86613")

        EC2Instance1 --[hidden]> ELBNetworkLoadBalancer1

    '}


    'package "Availability Zone 2"
    '{

        $PublicSubnet($EC2Instance, EC2Instance2, $label="Proxy Instance",  $colour="D86613")

        $PrivateSubnet($ELBNetworkLoadBalancer, ELBNetworkLoadBalancer2, $colour="D86613")

        EC2Instance2 --[hidden]> ELBNetworkLoadBalancer2

    '}
'}


$VPCNet($VPCElasticNetworkInterface, VPCElasticNetworkInterface2, $label="BBVA VPC 1", $colour="purple")
$VPCNet($Appstream2_0, Appstream2_02, $label="Appstream 2.0 VPC", $description="Appstream 2.0", $colour="purple")
'$MyOnPrem($VPCCustomerGateway, $label="Customer Gateway")

EC2Instance1 -r-> AutoScalingGroup1
AutoScalingGroup1 -r-> EC2Instance2

ELBNetworkLoadBalancer1 -r-> ELBNetworkLoadBalancer
ELBNetworkLoadBalancer -r->ELBNetworkLoadBalancer2

S3TransitGatewayStaging -u-> DirectConnect
S3TransitGatewayStaging -u-> VPCVPNConnection
S3TransitGatewayStaging -> EC2Instance1
DirectConnect -u-> VPCCustomerGateway
VPCVPNConnection -u-> VPCCustomerGateway

Appstream2_02 -d-> VPCElasticNetworkInterface2 
VPCElasticNetworkInterface2 -> S3TransitGatewayStaging


User -d-> BBVA 
BBVA -d-> Appstream2_02


@enduml

  
    

2.3.2. Gather the icons we need

Tip

When using `listsprites` limit the number of library categories you include to make it easier to search category by category. Simplified off (by commenting out the simplified header) so we can see the icon name.

@startuml
!include <awslib/AWSCommon>
!include <awslib/AWSSimplified.puml>
'!include <awslib/Compute/all.puml>
'!include <awslib/mobile/all.puml>
'!include <awslib/general/all.puml>
!include <awslib/GroupIcons/all.puml>
!include <awslib/CustomerEngagement/all.puml>
!include <awslib/NetworkingAndContentDelivery/all.puml>
!include <awslib/EndUserComputing/all.puml>
!include <awslib/ApplicationIntegration/all.puml>

listsprites

'Appstream2_0
'AutoScalingGroup
'EC2Instance
'InternetAlt1
'DirectConnect
'VPCVPNConnection
'VPCSubnetPublic
'VPCSubnetPrivate
'VPCInternetGateway
'VPCCustomerGateway
'TransitGateway
'VPCElasticNetworkInterface
'ELBNetworkLoadBalancer

'Cloudalt

@enduml

2.3.2.1. Source

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
@startuml
!include <awslib/AWSCommon>
!include <awslib/AWSSimplified.puml>
'!include <awslib/Compute/all.puml>
'!include <awslib/mobile/all.puml>
'!include <awslib/general/all.puml>
!include <awslib/GroupIcons/all.puml>
!include <awslib/CustomerEngagement/all.puml>
!include <awslib/NetworkingAndContentDelivery/all.puml>
!include <awslib/EndUserComputing/all.puml>
!include <awslib/ApplicationIntegration/all.puml>

listsprites

'Appstream2_0
'AutoScalingGroup
'EC2Instance
'InternetAlt1
'DirectConnect
'VPCVPNConnection
'VPCSubnetPublic
'VPCSubnetPrivate
'VPCInternetGateway
'VPCCustomerGateway
'TransitGateway
'VPCElasticNetworkInterface
'ELBNetworkLoadBalancer

'Cloudalt

@enduml

2.3.3. Add Text and Simplify The Icons

@startuml
!include <awslib/AWSCommon>
!include <awslib/AWSSimplified.puml>
!include <awslib/Compute/all.puml>
!include <awslib/mobile/all.puml>
!include <awslib/general/all.puml>
!include <awslib/GroupIcons/all.puml>
!include <awslib/CustomerEngagement/all.puml>
!include <awslib/NetworkingAndContentDelivery/all.puml>
!include <awslib/EndUserComputing/all.puml>
!include <awslib/ApplicationIntegration/all.puml>


Appstream2_0(Appstream2_0, " ", " ")
AutoScalingGroup(AutoScalingGroup, " ", " ")
EC2Instance(EC2Instance, " ", " ")
InternetAlt1(InternetAlt1, " ", " ")
DirectConnect(DirectConnect, " ", " ")
VPCVPNConnection(VPCVPNConnection, " ", " ")
VPCSubnetPublic(VPCSubnetPublic, " ", " ")
VPCSubnetPrivate(VPCSubnetPrivate, " ", " ")
VPCInternetGateway(VPCInternetGateway, " ", " ")
VPCCustomerGateway(VPCCustomerGateway, " ", " ")
TransitGateway(S3TransitGatewayStaging, " ", " ")
VPCElasticNetworkInterface(VPCElasticNetworkInterface, " ", " ")
ELBNetworkLoadBalancer(ELBNetworkLoadBalancer, " ", " ")

Cloudalt(Cloudalt, " ", " ")

@enduml

2.3.3.1. Source

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
@startuml
!include <awslib/AWSCommon>
!include <awslib/AWSSimplified.puml>
!include <awslib/Compute/all.puml>
!include <awslib/mobile/all.puml>
!include <awslib/general/all.puml>
!include <awslib/GroupIcons/all.puml>
!include <awslib/CustomerEngagement/all.puml>
!include <awslib/NetworkingAndContentDelivery/all.puml>
!include <awslib/EndUserComputing/all.puml>
!include <awslib/ApplicationIntegration/all.puml>


Appstream2_0(Appstream2_0, " ", " ")
AutoScalingGroup(AutoScalingGroup, " ", " ")
EC2Instance(EC2Instance, " ", " ")
InternetAlt1(InternetAlt1, " ", " ")
DirectConnect(DirectConnect, " ", " ")
VPCVPNConnection(VPCVPNConnection, " ", " ")
VPCSubnetPublic(VPCSubnetPublic, " ", " ")
VPCSubnetPrivate(VPCSubnetPrivate, " ", " ")
VPCInternetGateway(VPCInternetGateway, " ", " ")
VPCCustomerGateway(VPCCustomerGateway, " ", " ")
TransitGateway(S3TransitGatewayStaging, " ", " ")
VPCElasticNetworkInterface(VPCElasticNetworkInterface, " ", " ")
ELBNetworkLoadBalancer(ELBNetworkLoadBalancer, " ", " ")

Cloudalt(Cloudalt, " ", " ")

@enduml

2.3.4. Draw Boxes

@startuml
!include <awslib/AWSCommon>
!include <awslib/AWSSimplified.puml>
!include <awslib/Compute/all.puml>
!include <awslib/mobile/all.puml>
!include <awslib/general/all.puml>
!include <awslib/GroupIcons/all.puml>
!include <awslib/CustomerEngagement/all.puml>
!include <awslib/NetworkingAndContentDelivery/all.puml>
!include <awslib/EndUserComputing/all.puml>
!include <awslib/ApplicationIntegration/all.puml>


skinparam rectangle {
    backgroundColor<<box1>> e6fbff
    borderColor<<$box1>> e6fbff
    shadowing<<$box1>> true
    
    backgroundColor<<box2>> e6ffef
    borderColor<<$box2>> e6ffef
    shadowing<<$box2>> true
}

package "AZ"
{

rectangle box2 <<box2>> as "<color:3F8624><$VPCSubnetPublic*.4> Public Subnet</color>\n
    <color:D86613><$EC2Instance></color>\nProxy Instance" 

rectangle box1 <<box1>> as "<color:3B48CC><$VPCSubnetPrivate*.4> Private Subnet</color>\n
    <color:D86613><$ELBNetworkLoadBalancer></color>\n" 
}
@enduml

2.3.4.1. Source

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
@startuml
!include <awslib/AWSCommon>
!include <awslib/AWSSimplified.puml>
!include <awslib/Compute/all.puml>
!include <awslib/mobile/all.puml>
!include <awslib/general/all.puml>
!include <awslib/GroupIcons/all.puml>
!include <awslib/CustomerEngagement/all.puml>
!include <awslib/NetworkingAndContentDelivery/all.puml>
!include <awslib/EndUserComputing/all.puml>
!include <awslib/ApplicationIntegration/all.puml>


skinparam rectangle {
    backgroundColor<<box1>> e6fbff
    borderColor<<$box1>> e6fbff
    shadowing<<$box1>> true
    
    backgroundColor<<box2>> e6ffef
    borderColor<<$box2>> e6ffef
    shadowing<<$box2>> true
}

package "AZ"
{

rectangle box2 <<box2>> as "<color:3F8624><$VPCSubnetPublic*.4> Public Subnet</color>\n
    <color:D86613><$EC2Instance></color>\nProxy Instance" 

rectangle box1 <<box1>> as "<color:3B48CC><$VPCSubnetPrivate*.4> Private Subnet</color>\n
    <color:D86613><$ELBNetworkLoadBalancer></color>\n" 
}
@enduml

2.3.5. Draw Boxes with Procedures

In this case, we create everything we need ourselves like VPC compound components. It is informative to see how to do it.

In the future, this functionality could be part of stdlib so we don’t have to.

@startuml
!include <awslib/AWSCommon>
!include <awslib/AWSSimplified.puml>
!include <awslib/Compute/all.puml>
!include <awslib/mobile/all.puml>
!include <awslib/general/all.puml>
!include <awslib/GroupIcons/all.puml>
!include <awslib/CustomerEngagement/all.puml>
!include <awslib/NetworkingAndContentDelivery/all.puml>
!include <awslib/EndUserComputing/all.puml>
!include <awslib/ApplicationIntegration/all.puml>

'skinparam linetype polyline


!unquoted procedure $PublicSubnet($MySprite, $alias, $description="", $label="", $technology="", $scale=1, $colour="blue", $shape="", $textsize="18")

    skinparam rectangle {
        backgroundColor<<$alias>> e6ffef
        borderColor<<$alias>> e6ffef
        shadowing<<$alias>> true
    }
    rectangle $alias <<$alias>> as "
        <color:3F8624><$VPCSubnetPublic*.4> Public Subnet</color>\n
        <color:$colour><$MySprite></color>\n$label" 

!endprocedure

!unquoted procedure $PrivateSubnet($MySprite, $alias, $description="", $label="", $technology="", $scale=1, $colour="blue", $shape="", $textsize="18")

    skinparam rectangle {
        backgroundColor<<$alias>> e6fbff
        borderColor<<$alias>> e6fbff
        shadowing<<$alias>> true
    }
    
    rectangle $alias <<$alias>> as "
        <color:3B48CC><$VPCSubnetPrivate*.4> Private Subnet</color>\n
        <color:$colour><$MySprite></color>\n$label" 

!endprocedure


!unquoted procedure $VPCNet($MySprite, $alias, $description="", $label="", $technology="", $scale=1, $colour="blue", $shape="", $textsize="18")

    skinparam rectangle {
        backgroundColor<<$alias>> white
        borderColor<<$alias>> e6fbff
        shadowing<<$alias>> true
    }
    
    rectangle $alias <<$alias>> as "
        <color:3F8624><$VPC*.4></color> <color:grey>$label</color>\n
        <color:$colour><$MySprite></color>\n$description" 

!endprocedure

'note the "=" denotes heading 1
skinparam rectangle {
        backgroundColor<<BBVA>> white
        borderColor<<BBVA>> white
        shadowing<<$alias>> false
    }
rectangle  BBVA <<BBVA>> as "
        =<color:blue>BBVA</color>\n
        \nAuthentication Service" 



AutoScalingGroup(AutoScalingGroup1, "Auto Scaling Group", "")
ELBNetworkLoadBalancer(ELBNetworkLoadBalancer, "Network Load Balancer", " ")
VPCInternetGateway(VPCInternetGateway, "Internet Gateway", " ")
InternetAlt1(InternetAlt1, "Internet", " ")
'VPCElasticNetworkInterface(VPCElasticNetworkInterface, " ", " ")

VPCInternetGateway -u-> InternetAlt1
VPCVPNConnection(VPCVPNConnection, "VPN\nConnection", " ")
DirectConnect(DirectConnect, "Direct\nConnect", " ")
TransitGateway(S3TransitGatewayStaging, "TransitGateway", " ")

VPCCustomerGateway(VPCCustomerGateway, " ", " ")
'Appstream2_0(Appstream2_0, " ", " ")
Cloudalt(Cloudalt, " ", " ")
User(User, "BBVA Employee", " ")


'package "BBVA VPC 2"
'{

    'package "Availability Zone 1"
    '{

        $PublicSubnet($EC2Instance, EC2Instance1, $label="Proxy Instance",  $colour="D86613")

        $PrivateSubnet($ELBNetworkLoadBalancer, ELBNetworkLoadBalancer1, $colour="D86613")

        EC2Instance1 --[hidden]> ELBNetworkLoadBalancer1

    '}


    'package "Availability Zone 2"
    '{

        $PublicSubnet($EC2Instance, EC2Instance2, $label="Proxy Instance",  $colour="D86613")

        $PrivateSubnet($ELBNetworkLoadBalancer, ELBNetworkLoadBalancer2, $colour="D86613")

        EC2Instance2 --[hidden]> ELBNetworkLoadBalancer2

    '}
'}


$VPCNet($VPCElasticNetworkInterface, VPCElasticNetworkInterface2, $label="BBVA VPC 1", $colour="purple")
$VPCNet($Appstream2_0, Appstream2_02, $label="Appstream 2.0 VPC", $description="Appstream 2.0", $colour="purple")
'$MyOnPrem($VPCCustomerGateway, $label="Customer Gateway")

EC2Instance1 -r-> AutoScalingGroup1
AutoScalingGroup1 -r-> EC2Instance2

ELBNetworkLoadBalancer1 -r-> ELBNetworkLoadBalancer
ELBNetworkLoadBalancer -r->ELBNetworkLoadBalancer2

S3TransitGatewayStaging -u-> DirectConnect
S3TransitGatewayStaging -u-> VPCVPNConnection
S3TransitGatewayStaging -> EC2Instance1
DirectConnect -u-> VPCCustomerGateway
VPCVPNConnection -u-> VPCCustomerGateway

Appstream2_02 -d-> VPCElasticNetworkInterface2 
VPCElasticNetworkInterface2 -> S3TransitGatewayStaging


User -d-> BBVA 
BBVA -d-> Appstream2_02


@enduml

2.3.5.1. Source

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
@startuml
!include <awslib/AWSCommon>
!include <awslib/AWSSimplified.puml>
!include <awslib/Compute/all.puml>
!include <awslib/mobile/all.puml>
!include <awslib/general/all.puml>
!include <awslib/GroupIcons/all.puml>
!include <awslib/CustomerEngagement/all.puml>
!include <awslib/NetworkingAndContentDelivery/all.puml>
!include <awslib/EndUserComputing/all.puml>
!include <awslib/ApplicationIntegration/all.puml>

'skinparam linetype polyline


!unquoted procedure $PublicSubnet($MySprite, $alias, $description="", $label="", $technology="", $scale=1, $colour="blue", $shape="", $textsize="18")

    skinparam rectangle {
        backgroundColor<<$alias>> e6ffef
        borderColor<<$alias>> e6ffef
        shadowing<<$alias>> true
    }
    rectangle $alias <<$alias>> as "
        <color:3F8624><$VPCSubnetPublic*.4> Public Subnet</color>\n
        <color:$colour><$MySprite></color>\n$label" 

!endprocedure

!unquoted procedure $PrivateSubnet($MySprite, $alias, $description="", $label="", $technology="", $scale=1, $colour="blue", $shape="", $textsize="18")

    skinparam rectangle {
        backgroundColor<<$alias>> e6fbff
        borderColor<<$alias>> e6fbff
        shadowing<<$alias>> true
    }
    
    rectangle $alias <<$alias>> as "
        <color:3B48CC><$VPCSubnetPrivate*.4> Private Subnet</color>\n
        <color:$colour><$MySprite></color>\n$label" 

!endprocedure


!unquoted procedure $VPCNet($MySprite, $alias, $description="", $label="", $technology="", $scale=1, $colour="blue", $shape="", $textsize="18")

    skinparam rectangle {
        backgroundColor<<$alias>> white
        borderColor<<$alias>> e6fbff
        shadowing<<$alias>> true
    }
    
    rectangle $alias <<$alias>> as "
        <color:3F8624><$VPC*.4></color> <color:grey>$label</color>\n
        <color:$colour><$MySprite></color>\n$description" 

!endprocedure

'note the "=" denotes heading 1
skinparam rectangle {
        backgroundColor<<BBVA>> white
        borderColor<<BBVA>> white
        shadowing<<$alias>> false
    }
rectangle  BBVA <<BBVA>> as "
        =<color:blue>BBVA</color>\n
        \nAuthentication Service" 



AutoScalingGroup(AutoScalingGroup1, "Auto Scaling Group", "")
ELBNetworkLoadBalancer(ELBNetworkLoadBalancer, "Network Load Balancer", " ")
VPCInternetGateway(VPCInternetGateway, "Internet Gateway", " ")
InternetAlt1(InternetAlt1, "Internet", " ")
'VPCElasticNetworkInterface(VPCElasticNetworkInterface, " ", " ")

VPCInternetGateway -u-> InternetAlt1
VPCVPNConnection(VPCVPNConnection, "VPN\nConnection", " ")
DirectConnect(DirectConnect, "Direct\nConnect", " ")
TransitGateway(S3TransitGatewayStaging, "TransitGateway", " ")

VPCCustomerGateway(VPCCustomerGateway, " ", " ")
'Appstream2_0(Appstream2_0, " ", " ")
Cloudalt(Cloudalt, " ", " ")
User(User, "BBVA Employee", " ")


'package "BBVA VPC 2"
'{

    'package "Availability Zone 1"
    '{

        $PublicSubnet($EC2Instance, EC2Instance1, $label="Proxy Instance",  $colour="D86613")

        $PrivateSubnet($ELBNetworkLoadBalancer, ELBNetworkLoadBalancer1, $colour="D86613")

        EC2Instance1 --[hidden]> ELBNetworkLoadBalancer1

    '}


    'package "Availability Zone 2"
    '{

        $PublicSubnet($EC2Instance, EC2Instance2, $label="Proxy Instance",  $colour="D86613")

        $PrivateSubnet($ELBNetworkLoadBalancer, ELBNetworkLoadBalancer2, $colour="D86613")

        EC2Instance2 --[hidden]> ELBNetworkLoadBalancer2

    '}
'}


$VPCNet($VPCElasticNetworkInterface, VPCElasticNetworkInterface2, $label="BBVA VPC 1", $colour="purple")
$VPCNet($Appstream2_0, Appstream2_02, $label="Appstream 2.0 VPC", $description="Appstream 2.0", $colour="purple")
'$MyOnPrem($VPCCustomerGateway, $label="Customer Gateway")

EC2Instance1 -r-> AutoScalingGroup1
AutoScalingGroup1 -r-> EC2Instance2

ELBNetworkLoadBalancer1 -r-> ELBNetworkLoadBalancer
ELBNetworkLoadBalancer -r->ELBNetworkLoadBalancer2

S3TransitGatewayStaging -u-> DirectConnect
S3TransitGatewayStaging -u-> VPCVPNConnection
S3TransitGatewayStaging -> EC2Instance1
DirectConnect -u-> VPCCustomerGateway
VPCVPNConnection -u-> VPCCustomerGateway

Appstream2_02 -d-> VPCElasticNetworkInterface2 
VPCElasticNetworkInterface2 -> S3TransitGatewayStaging


User -d-> BBVA 
BBVA -d-> Appstream2_02


@enduml