├── 101AWS_Dynatrace_Hotday2018.pptx ├── AWSTutorial.pptx ├── LAMPCloudFormationSample ├── LAMPTemplateNODynatrace └── LAMPTemplateWITHDynatraceOneAgent ├── LICENSE ├── NodeJSBeanStalkSample ├── .ebextensions │ ├── dynatrace.config │ ├── logging.config │ └── version.config ├── NodeJSBeanStalkSample.zip ├── app.js ├── cron.yaml ├── index.html ├── launch.bat └── package.json ├── README.md ├── TestingScripts ├── nodejsbeanstalktest.js ├── readme.md └── win_beanstalk.bat └── images ├── lab1_awsdashboard.png ├── lab1_ec2instancelist.PNG ├── lab2_ec2hostmonitor.png ├── lab2a_ec2imageselection.PNG ├── lab2a_userdatascript.PNG ├── lab3_beanstalkec2instance.png ├── lab3_beanstalkloadbalanced.png ├── lab3_createnodeapp.png ├── lab3_softwareenv.PNG ├── lab4_apacheprocessgroup.png ├── lab4_configurestack.png ├── lab4_createlampstack.png ├── lab4_lampsmartscape.png ├── lab4_mysql.png ├── lab5_endusermonitoring.png ├── lab6_bluegreen_launchconfiguration_userdata.png ├── lab8_LambdaFunctionPurePath.PNG ├── lab8_createLambdaFunction.PNG ├── lab8_lambdaExecutionSuccess.PNG ├── lab8_lambdaOptionsScreen.PNG ├── lab8_s3bucketURL.PNG ├── lab8_serverlessIntegration.PNG └── labintro_dynatracedeploy.png /101AWS_Dynatrace_Hotday2018.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dynatrace/AWSMonitoringTutorials/6e3d8899fb3ece7d6673af3660ca859136c14250/101AWS_Dynatrace_Hotday2018.pptx -------------------------------------------------------------------------------- /AWSTutorial.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dynatrace/AWSMonitoringTutorials/6e3d8899fb3ece7d6673af3660ca859136c14250/AWSTutorial.pptx -------------------------------------------------------------------------------- /LAMPCloudFormationSample/LAMPTemplateNODynatrace: -------------------------------------------------------------------------------- 1 | { 2 | "AWSTemplateFormatVersion": "2010-09-09", 3 | "Description": "AWS CloudFormation Sample Template LAMP_Single_Instance: Create a LAMP stack using a single EC2 instance and a local MySQL database for storage. This template demonstrates using the AWS CloudFormation bootstrap scripts to install the packages and files necessary to deploy the Apache web server, PHP and MySQL at instance launch time. **WARNING** This template creates an Amazon EC2 instance. You will be billed for the AWS resources used if you create a stack from this template.", 4 | "Parameters": { 5 | "KeyName": { 6 | "Description": "Name of an existing EC2 KeyPair to enable SSH access to the instance", 7 | "Type": "AWS::EC2::KeyPair::KeyName", 8 | "ConstraintDescription": "must be the name of an existing EC2 KeyPair." 9 | }, 10 | "DBName": { 11 | "Default": "MyDatabase", 12 | "Description": "MySQL database name", 13 | "Type": "String", 14 | "MinLength": "1", 15 | "MaxLength": "64", 16 | "AllowedPattern": "[a-zA-Z][a-zA-Z0-9]*", 17 | "ConstraintDescription": "must begin with a letter and contain only alphanumeric characters." 18 | }, 19 | "DBUser": { 20 | "NoEcho": "true", 21 | "Description": "Username for MySQL database access", 22 | "Type": "String", 23 | "MinLength": "1", 24 | "MaxLength": "16", 25 | "AllowedPattern": "[a-zA-Z][a-zA-Z0-9]*", 26 | "ConstraintDescription": "must begin with a letter and contain only alphanumeric characters." 27 | }, 28 | "DBPassword": { 29 | "NoEcho": "true", 30 | "Description": "Password for MySQL database access", 31 | "Type": "String", 32 | "MinLength": "1", 33 | "MaxLength": "41", 34 | "AllowedPattern": "[a-zA-Z0-9]*", 35 | "ConstraintDescription": "must contain only alphanumeric characters." 36 | }, 37 | "DBRootPassword": { 38 | "NoEcho": "true", 39 | "Description": "Root password for MySQL", 40 | "Type": "String", 41 | "MinLength": "1", 42 | "MaxLength": "41", 43 | "AllowedPattern": "[a-zA-Z0-9]*", 44 | "ConstraintDescription": "must contain only alphanumeric characters." 45 | }, 46 | "InstanceType": { 47 | "Description": "WebServer EC2 instance type", 48 | "Type": "String", 49 | "Default": "t2.small", 50 | "AllowedValues": [ 51 | "t1.micro", 52 | "t2.nano", 53 | "t2.micro", 54 | "t2.small", 55 | "t2.medium", 56 | "t2.large", 57 | "m1.small", 58 | "m1.medium", 59 | "m1.large", 60 | "m1.xlarge", 61 | "m2.xlarge", 62 | "m2.2xlarge", 63 | "m2.4xlarge", 64 | "m3.medium", 65 | "m3.large", 66 | "m3.xlarge", 67 | "m3.2xlarge", 68 | "m4.large", 69 | "m4.xlarge", 70 | "m4.2xlarge", 71 | "m4.4xlarge", 72 | "m4.10xlarge", 73 | "c1.medium", 74 | "c1.xlarge", 75 | "c3.large", 76 | "c3.xlarge", 77 | "c3.2xlarge", 78 | "c3.4xlarge", 79 | "c3.8xlarge", 80 | "c4.large", 81 | "c4.xlarge", 82 | "c4.2xlarge", 83 | "c4.4xlarge", 84 | "c4.8xlarge", 85 | "g2.2xlarge", 86 | "g2.8xlarge", 87 | "r3.large", 88 | "r3.xlarge", 89 | "r3.2xlarge", 90 | "r3.4xlarge", 91 | "r3.8xlarge", 92 | "i2.xlarge", 93 | "i2.2xlarge", 94 | "i2.4xlarge", 95 | "i2.8xlarge", 96 | "d2.xlarge", 97 | "d2.2xlarge", 98 | "d2.4xlarge", 99 | "d2.8xlarge", 100 | "hi1.4xlarge", 101 | "hs1.8xlarge", 102 | "cr1.8xlarge", 103 | "cc2.8xlarge", 104 | "cg1.4xlarge" 105 | ], 106 | "ConstraintDescription": "must be a valid EC2 instance type." 107 | }, 108 | "SSHLocation": { 109 | "Description": " The IP address range that can be used to SSH to the EC2 instances", 110 | "Type": "String", 111 | "MinLength": "9", 112 | "MaxLength": "18", 113 | "Default": "0.0.0.0/0", 114 | "AllowedPattern": "(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})/(\\d{1,2})", 115 | "ConstraintDescription": "must be a valid IP CIDR range of the form x.x.x.x/x." 116 | } 117 | }, 118 | "Mappings": { 119 | "AWSInstanceType2Arch": { 120 | "t1.micro": { 121 | "Arch": "PV64" 122 | }, 123 | "t2.nano": { 124 | "Arch": "HVM64" 125 | }, 126 | "t2.micro": { 127 | "Arch": "HVM64" 128 | }, 129 | "t2.small": { 130 | "Arch": "HVM64" 131 | }, 132 | "t2.medium": { 133 | "Arch": "HVM64" 134 | }, 135 | "t2.large": { 136 | "Arch": "HVM64" 137 | }, 138 | "m1.small": { 139 | "Arch": "PV64" 140 | }, 141 | "m1.medium": { 142 | "Arch": "PV64" 143 | }, 144 | "m1.large": { 145 | "Arch": "PV64" 146 | }, 147 | "m1.xlarge": { 148 | "Arch": "PV64" 149 | }, 150 | "m2.xlarge": { 151 | "Arch": "PV64" 152 | }, 153 | "m2.2xlarge": { 154 | "Arch": "PV64" 155 | }, 156 | "m2.4xlarge": { 157 | "Arch": "PV64" 158 | }, 159 | "m3.medium": { 160 | "Arch": "HVM64" 161 | }, 162 | "m3.large": { 163 | "Arch": "HVM64" 164 | }, 165 | "m3.xlarge": { 166 | "Arch": "HVM64" 167 | }, 168 | "m3.2xlarge": { 169 | "Arch": "HVM64" 170 | }, 171 | "m4.large": { 172 | "Arch": "HVM64" 173 | }, 174 | "m4.xlarge": { 175 | "Arch": "HVM64" 176 | }, 177 | "m4.2xlarge": { 178 | "Arch": "HVM64" 179 | }, 180 | "m4.4xlarge": { 181 | "Arch": "HVM64" 182 | }, 183 | "m4.10xlarge": { 184 | "Arch": "HVM64" 185 | }, 186 | "c1.medium": { 187 | "Arch": "PV64" 188 | }, 189 | "c1.xlarge": { 190 | "Arch": "PV64" 191 | }, 192 | "c3.large": { 193 | "Arch": "HVM64" 194 | }, 195 | "c3.xlarge": { 196 | "Arch": "HVM64" 197 | }, 198 | "c3.2xlarge": { 199 | "Arch": "HVM64" 200 | }, 201 | "c3.4xlarge": { 202 | "Arch": "HVM64" 203 | }, 204 | "c3.8xlarge": { 205 | "Arch": "HVM64" 206 | }, 207 | "c4.large": { 208 | "Arch": "HVM64" 209 | }, 210 | "c4.xlarge": { 211 | "Arch": "HVM64" 212 | }, 213 | "c4.2xlarge": { 214 | "Arch": "HVM64" 215 | }, 216 | "c4.4xlarge": { 217 | "Arch": "HVM64" 218 | }, 219 | "c4.8xlarge": { 220 | "Arch": "HVM64" 221 | }, 222 | "g2.2xlarge": { 223 | "Arch": "HVMG2" 224 | }, 225 | "g2.8xlarge": { 226 | "Arch": "HVMG2" 227 | }, 228 | "r3.large": { 229 | "Arch": "HVM64" 230 | }, 231 | "r3.xlarge": { 232 | "Arch": "HVM64" 233 | }, 234 | "r3.2xlarge": { 235 | "Arch": "HVM64" 236 | }, 237 | "r3.4xlarge": { 238 | "Arch": "HVM64" 239 | }, 240 | "r3.8xlarge": { 241 | "Arch": "HVM64" 242 | }, 243 | "i2.xlarge": { 244 | "Arch": "HVM64" 245 | }, 246 | "i2.2xlarge": { 247 | "Arch": "HVM64" 248 | }, 249 | "i2.4xlarge": { 250 | "Arch": "HVM64" 251 | }, 252 | "i2.8xlarge": { 253 | "Arch": "HVM64" 254 | }, 255 | "d2.xlarge": { 256 | "Arch": "HVM64" 257 | }, 258 | "d2.2xlarge": { 259 | "Arch": "HVM64" 260 | }, 261 | "d2.4xlarge": { 262 | "Arch": "HVM64" 263 | }, 264 | "d2.8xlarge": { 265 | "Arch": "HVM64" 266 | }, 267 | "hi1.4xlarge": { 268 | "Arch": "HVM64" 269 | }, 270 | "hs1.8xlarge": { 271 | "Arch": "HVM64" 272 | }, 273 | "cr1.8xlarge": { 274 | "Arch": "HVM64" 275 | }, 276 | "cc2.8xlarge": { 277 | "Arch": "HVM64" 278 | } 279 | }, 280 | "AWSInstanceType2NATArch": { 281 | "t1.micro": { 282 | "Arch": "NATPV64" 283 | }, 284 | "t2.nano": { 285 | "Arch": "NATHVM64" 286 | }, 287 | "t2.micro": { 288 | "Arch": "NATHVM64" 289 | }, 290 | "t2.small": { 291 | "Arch": "NATHVM64" 292 | }, 293 | "t2.medium": { 294 | "Arch": "NATHVM64" 295 | }, 296 | "t2.large": { 297 | "Arch": "NATHVM64" 298 | }, 299 | "m1.small": { 300 | "Arch": "NATPV64" 301 | }, 302 | "m1.medium": { 303 | "Arch": "NATPV64" 304 | }, 305 | "m1.large": { 306 | "Arch": "NATPV64" 307 | }, 308 | "m1.xlarge": { 309 | "Arch": "NATPV64" 310 | }, 311 | "m2.xlarge": { 312 | "Arch": "NATPV64" 313 | }, 314 | "m2.2xlarge": { 315 | "Arch": "NATPV64" 316 | }, 317 | "m2.4xlarge": { 318 | "Arch": "NATPV64" 319 | }, 320 | "m3.medium": { 321 | "Arch": "NATHVM64" 322 | }, 323 | "m3.large": { 324 | "Arch": "NATHVM64" 325 | }, 326 | "m3.xlarge": { 327 | "Arch": "NATHVM64" 328 | }, 329 | "m3.2xlarge": { 330 | "Arch": "NATHVM64" 331 | }, 332 | "m4.large": { 333 | "Arch": "NATHVM64" 334 | }, 335 | "m4.xlarge": { 336 | "Arch": "NATHVM64" 337 | }, 338 | "m4.2xlarge": { 339 | "Arch": "NATHVM64" 340 | }, 341 | "m4.4xlarge": { 342 | "Arch": "NATHVM64" 343 | }, 344 | "m4.10xlarge": { 345 | "Arch": "NATHVM64" 346 | }, 347 | "c1.medium": { 348 | "Arch": "NATPV64" 349 | }, 350 | "c1.xlarge": { 351 | "Arch": "NATPV64" 352 | }, 353 | "c3.large": { 354 | "Arch": "NATHVM64" 355 | }, 356 | "c3.xlarge": { 357 | "Arch": "NATHVM64" 358 | }, 359 | "c3.2xlarge": { 360 | "Arch": "NATHVM64" 361 | }, 362 | "c3.4xlarge": { 363 | "Arch": "NATHVM64" 364 | }, 365 | "c3.8xlarge": { 366 | "Arch": "NATHVM64" 367 | }, 368 | "c4.large": { 369 | "Arch": "NATHVM64" 370 | }, 371 | "c4.xlarge": { 372 | "Arch": "NATHVM64" 373 | }, 374 | "c4.2xlarge": { 375 | "Arch": "NATHVM64" 376 | }, 377 | "c4.4xlarge": { 378 | "Arch": "NATHVM64" 379 | }, 380 | "c4.8xlarge": { 381 | "Arch": "NATHVM64" 382 | }, 383 | "g2.2xlarge": { 384 | "Arch": "NATHVMG2" 385 | }, 386 | "g2.8xlarge": { 387 | "Arch": "NATHVMG2" 388 | }, 389 | "r3.large": { 390 | "Arch": "NATHVM64" 391 | }, 392 | "r3.xlarge": { 393 | "Arch": "NATHVM64" 394 | }, 395 | "r3.2xlarge": { 396 | "Arch": "NATHVM64" 397 | }, 398 | "r3.4xlarge": { 399 | "Arch": "NATHVM64" 400 | }, 401 | "r3.8xlarge": { 402 | "Arch": "NATHVM64" 403 | }, 404 | "i2.xlarge": { 405 | "Arch": "NATHVM64" 406 | }, 407 | "i2.2xlarge": { 408 | "Arch": "NATHVM64" 409 | }, 410 | "i2.4xlarge": { 411 | "Arch": "NATHVM64" 412 | }, 413 | "i2.8xlarge": { 414 | "Arch": "NATHVM64" 415 | }, 416 | "d2.xlarge": { 417 | "Arch": "NATHVM64" 418 | }, 419 | "d2.2xlarge": { 420 | "Arch": "NATHVM64" 421 | }, 422 | "d2.4xlarge": { 423 | "Arch": "NATHVM64" 424 | }, 425 | "d2.8xlarge": { 426 | "Arch": "NATHVM64" 427 | }, 428 | "hi1.4xlarge": { 429 | "Arch": "NATHVM64" 430 | }, 431 | "hs1.8xlarge": { 432 | "Arch": "NATHVM64" 433 | }, 434 | "cr1.8xlarge": { 435 | "Arch": "NATHVM64" 436 | }, 437 | "cc2.8xlarge": { 438 | "Arch": "NATHVM64" 439 | } 440 | }, 441 | "AWSRegionArch2AMI": { 442 | "us-east-1": { 443 | "PV64": "ami-2a69aa47", 444 | "HVM64": "ami-6869aa05", 445 | "HVMG2": "ami-61e27177" 446 | }, 447 | "us-west-2": { 448 | "PV64": "ami-7f77b31f", 449 | "HVM64": "ami-7172b611", 450 | "HVMG2": "ami-60aa3700" 451 | }, 452 | "us-west-1": { 453 | "PV64": "ami-a2490dc2", 454 | "HVM64": "ami-31490d51", 455 | "HVMG2": "ami-4b694d2b" 456 | }, 457 | "eu-west-1": { 458 | "PV64": "ami-4cdd453f", 459 | "HVM64": "ami-f9dd458a", 460 | "HVMG2": "ami-2955524f" 461 | }, 462 | "eu-west-2": { 463 | "PV64": "NOT_SUPPORTED", 464 | "HVM64": "ami-886369ec", 465 | "HVMG2": "NOT_SUPPORTED" 466 | }, 467 | "eu-central-1": { 468 | "PV64": "ami-6527cf0a", 469 | "HVM64": "ami-ea26ce85", 470 | "HVMG2": "ami-81ac71ee" 471 | }, 472 | "ap-northeast-1": { 473 | "PV64": "ami-3e42b65f", 474 | "HVM64": "ami-374db956", 475 | "HVMG2": "ami-46220c21" 476 | }, 477 | "ap-northeast-2": { 478 | "PV64": "NOT_SUPPORTED", 479 | "HVM64": "ami-2b408b45", 480 | "HVMG2": "NOT_SUPPORTED" 481 | }, 482 | "ap-southeast-1": { 483 | "PV64": "ami-df9e4cbc", 484 | "HVM64": "ami-a59b49c6", 485 | "HVMG2": "ami-c212aba1" 486 | }, 487 | "ap-southeast-2": { 488 | "PV64": "ami-63351d00", 489 | "HVM64": "ami-dc361ebf", 490 | "HVMG2": "ami-0ad2db69" 491 | }, 492 | "ap-south-1": { 493 | "PV64": "NOT_SUPPORTED", 494 | "HVM64": "ami-ffbdd790", 495 | "HVMG2": "ami-ca3042a5" 496 | }, 497 | "us-east-2": { 498 | "PV64": "NOT_SUPPORTED", 499 | "HVM64": "ami-f6035893", 500 | "HVMG2": "NOT_SUPPORTED" 501 | }, 502 | "ca-central-1": { 503 | "PV64": "NOT_SUPPORTED", 504 | "HVM64": "ami-730ebd17", 505 | "HVMG2": "NOT_SUPPORTED" 506 | }, 507 | "sa-east-1": { 508 | "PV64": "ami-1ad34676", 509 | "HVM64": "ami-6dd04501", 510 | "HVMG2": "NOT_SUPPORTED" 511 | }, 512 | "cn-north-1": { 513 | "PV64": "ami-77559f1a", 514 | "HVM64": "ami-8e6aa0e3", 515 | "HVMG2": "NOT_SUPPORTED" 516 | } 517 | } 518 | }, 519 | "Resources": { 520 | "WebServerInstance": { 521 | "Type": "AWS::EC2::Instance", 522 | "Metadata": { 523 | "AWS::CloudFormation::Init": { 524 | "configSets": { 525 | "InstallAndRun": [ 526 | "Install", 527 | "Configure" 528 | ] 529 | }, 530 | "Install": { 531 | "packages": { 532 | "yum": { 533 | "mysql": [], 534 | "mysql-server": [], 535 | "mysql-libs": [], 536 | "httpd": [], 537 | "php": [], 538 | "php-mysql": [] 539 | } 540 | }, 541 | "files": { 542 | "/var/www/html/index.php": { 543 | "content": { 544 | "Fn::Join": [ 545 | "", 546 | [ 547 | "\n", 548 | " \n", 549 | " AWS CloudFormation PHP Sample\n", 550 | " \n", 551 | " \n", 552 | " \n", 553 | "

Welcome to the AWS CloudFormation PHP Sample

\n", 554 | "

\n", 555 | " \";\n", 558 | " print date(\"g:i A l, F j Y.\");\n", 559 | " ?>\n", 560 | "

\n", 561 | " \";\n", 572 | " }\n", 573 | " else\n", 574 | " {\n", 575 | " print \"Server = \" . $hostname . \"
\";\n", 576 | " }\n", 577 | " // Get the instance-id of the intance from the instance metadata\n", 578 | " curl_setopt($curl_handle,CURLOPT_URL,'http://169.254.169.254/latest/meta-data/instance-id');\n", 579 | " $instanceid = curl_exec($curl_handle);\n", 580 | " if (empty($instanceid))\n", 581 | " {\n", 582 | " print \"Sorry, for some reason, we got no instance id back
\";\n", 583 | " }\n", 584 | " else\n", 585 | " {\n", 586 | " print \"EC2 instance-id = \" . $instanceid . \"
\";\n", 587 | " }\n", 588 | " $Database = \"localhost\";\n", 589 | " $DBUser = \"", 590 | { 591 | "Ref": "DBUser" 592 | }, 593 | "\";\n", 594 | " $DBPassword = \"", 595 | { 596 | "Ref": "DBPassword" 597 | }, 598 | "\";\n", 599 | " print \"Database = \" . $Database . \"
\";\n", 600 | " $dbconnection = mysql_connect($Database, $DBUser, $DBPassword)\n", 601 | " or die(\"Could not connect: \" . mysql_error());\n", 602 | " print (\"Connected to $Database successfully\");\n", 603 | " mysql_close($dbconnection);\n", 604 | " ?>\n", 605 | "

PHP Information

\n", 606 | "

\n", 607 | " \n", 610 | " \n", 611 | "\n" 612 | ] 613 | ] 614 | }, 615 | "mode": "000600", 616 | "owner": "apache", 617 | "group": "apache" 618 | }, 619 | "/tmp/setup.mysql": { 620 | "content": { 621 | "Fn::Join": [ 622 | "", 623 | [ 624 | "CREATE DATABASE ", 625 | { 626 | "Ref": "DBName" 627 | }, 628 | ";\n", 629 | "GRANT ALL ON ", 630 | { 631 | "Ref": "DBName" 632 | }, 633 | ".* TO '", 634 | { 635 | "Ref": "DBUser" 636 | }, 637 | "'@localhost IDENTIFIED BY '", 638 | { 639 | "Ref": "DBPassword" 640 | }, 641 | "';\n" 642 | ] 643 | ] 644 | }, 645 | "mode": "000400", 646 | "owner": "root", 647 | "group": "root" 648 | }, 649 | "/etc/cfn/cfn-hup.conf": { 650 | "content": { 651 | "Fn::Join": [ 652 | "", 653 | [ 654 | "[main]\n", 655 | "stack=", 656 | { 657 | "Ref": "AWS::StackId" 658 | }, 659 | "\n", 660 | "region=", 661 | { 662 | "Ref": "AWS::Region" 663 | }, 664 | "\n" 665 | ] 666 | ] 667 | }, 668 | "mode": "000400", 669 | "owner": "root", 670 | "group": "root" 671 | }, 672 | "/etc/cfn/hooks.d/cfn-auto-reloader.conf": { 673 | "content": { 674 | "Fn::Join": [ 675 | "", 676 | [ 677 | "[cfn-auto-reloader-hook]\n", 678 | "triggers=post.update\n", 679 | "path=Resources.WebServerInstance.Metadata.AWS::CloudFormation::Init\n", 680 | "action=/opt/aws/bin/cfn-init -v ", 681 | " --stack ", 682 | { 683 | "Ref": "AWS::StackName" 684 | }, 685 | " --resource WebServerInstance ", 686 | " --configsets InstallAndRun ", 687 | " --region ", 688 | { 689 | "Ref": "AWS::Region" 690 | }, 691 | "\n", 692 | "runas=root\n" 693 | ] 694 | ] 695 | } 696 | } 697 | }, 698 | "services": { 699 | "sysvinit": { 700 | "mysqld": { 701 | "enabled": "true", 702 | "ensureRunning": "true" 703 | }, 704 | "httpd": { 705 | "enabled": "true", 706 | "ensureRunning": "true" 707 | }, 708 | "cfn-hup": { 709 | "enabled": "true", 710 | "ensureRunning": "true", 711 | "files": [ 712 | "/etc/cfn/cfn-hup.conf", 713 | "/etc/cfn/hooks.d/cfn-auto-reloader.conf" 714 | ] 715 | } 716 | } 717 | } 718 | }, 719 | "Configure": { 720 | "commands": { 721 | "01_set_mysql_root_password": { 722 | "command": { 723 | "Fn::Join": [ 724 | "", 725 | [ 726 | "mysqladmin -u root password '", 727 | { 728 | "Ref": "DBRootPassword" 729 | }, 730 | "'" 731 | ] 732 | ] 733 | }, 734 | "test": { 735 | "Fn::Join": [ 736 | "", 737 | [ 738 | "$(mysql ", 739 | { 740 | "Ref": "DBName" 741 | }, 742 | " -u root --password='", 743 | { 744 | "Ref": "DBRootPassword" 745 | }, 746 | "' >/dev/null 2>&1 /dev/null 2>&1 Deploy screen in your Dynatrace SaaS/Managed console" 15 | }, 16 | "DBName": { 17 | "Default": "MyDatabase", 18 | "Description": "MySQL database name", 19 | "Type": "String", 20 | "MinLength": "1", 21 | "MaxLength": "64", 22 | "AllowedPattern": "[a-zA-Z][a-zA-Z0-9]*", 23 | "ConstraintDescription": "must begin with a letter and contain only alphanumeric characters." 24 | }, 25 | "DBUser": { 26 | "NoEcho": "true", 27 | "Description": "Username for MySQL database access", 28 | "Type": "String", 29 | "MinLength": "1", 30 | "MaxLength": "16", 31 | "AllowedPattern": "[a-zA-Z][a-zA-Z0-9]*", 32 | "ConstraintDescription": "must begin with a letter and contain only alphanumeric characters." 33 | }, 34 | "DBPassword": { 35 | "NoEcho": "true", 36 | "Description": "Password for MySQL database access", 37 | "Type": "String", 38 | "MinLength": "1", 39 | "MaxLength": "41", 40 | "AllowedPattern": "[a-zA-Z0-9]*", 41 | "ConstraintDescription": "must contain only alphanumeric characters." 42 | }, 43 | "DBRootPassword": { 44 | "NoEcho": "true", 45 | "Description": "Root password for MySQL", 46 | "Type": "String", 47 | "MinLength": "1", 48 | "MaxLength": "41", 49 | "AllowedPattern": "[a-zA-Z0-9]*", 50 | "ConstraintDescription": "must contain only alphanumeric characters." 51 | }, 52 | "InstanceType": { 53 | "Description": "WebServer EC2 instance type", 54 | "Type": "String", 55 | "Default": "t2.small", 56 | "AllowedValues": [ 57 | "t1.micro", 58 | "t2.nano", 59 | "t2.micro", 60 | "t2.small", 61 | "t2.medium", 62 | "t2.large", 63 | "m1.small", 64 | "m1.medium", 65 | "m1.large", 66 | "m1.xlarge", 67 | "m2.xlarge", 68 | "m2.2xlarge", 69 | "m2.4xlarge", 70 | "m3.medium", 71 | "m3.large", 72 | "m3.xlarge", 73 | "m3.2xlarge", 74 | "m4.large", 75 | "m4.xlarge", 76 | "m4.2xlarge", 77 | "m4.4xlarge", 78 | "m4.10xlarge", 79 | "c1.medium", 80 | "c1.xlarge", 81 | "c3.large", 82 | "c3.xlarge", 83 | "c3.2xlarge", 84 | "c3.4xlarge", 85 | "c3.8xlarge", 86 | "c4.large", 87 | "c4.xlarge", 88 | "c4.2xlarge", 89 | "c4.4xlarge", 90 | "c4.8xlarge", 91 | "g2.2xlarge", 92 | "g2.8xlarge", 93 | "r3.large", 94 | "r3.xlarge", 95 | "r3.2xlarge", 96 | "r3.4xlarge", 97 | "r3.8xlarge", 98 | "i2.xlarge", 99 | "i2.2xlarge", 100 | "i2.4xlarge", 101 | "i2.8xlarge", 102 | "d2.xlarge", 103 | "d2.2xlarge", 104 | "d2.4xlarge", 105 | "d2.8xlarge", 106 | "hi1.4xlarge", 107 | "hs1.8xlarge", 108 | "cr1.8xlarge", 109 | "cc2.8xlarge", 110 | "cg1.4xlarge" 111 | ], 112 | "ConstraintDescription": "must be a valid EC2 instance type." 113 | }, 114 | "SSHLocation": { 115 | "Description": " The IP address range that can be used to SSH to the EC2 instances", 116 | "Type": "String", 117 | "MinLength": "9", 118 | "MaxLength": "18", 119 | "Default": "0.0.0.0/0", 120 | "AllowedPattern": "(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})/(\\d{1,2})", 121 | "ConstraintDescription": "must be a valid IP CIDR range of the form x.x.x.x/x." 122 | } 123 | }, 124 | "Mappings": { 125 | "AWSInstanceType2Arch": { 126 | "t1.micro": { 127 | "Arch": "PV64" 128 | }, 129 | "t2.nano": { 130 | "Arch": "HVM64" 131 | }, 132 | "t2.micro": { 133 | "Arch": "HVM64" 134 | }, 135 | "t2.small": { 136 | "Arch": "HVM64" 137 | }, 138 | "t2.medium": { 139 | "Arch": "HVM64" 140 | }, 141 | "t2.large": { 142 | "Arch": "HVM64" 143 | }, 144 | "m1.small": { 145 | "Arch": "PV64" 146 | }, 147 | "m1.medium": { 148 | "Arch": "PV64" 149 | }, 150 | "m1.large": { 151 | "Arch": "PV64" 152 | }, 153 | "m1.xlarge": { 154 | "Arch": "PV64" 155 | }, 156 | "m2.xlarge": { 157 | "Arch": "PV64" 158 | }, 159 | "m2.2xlarge": { 160 | "Arch": "PV64" 161 | }, 162 | "m2.4xlarge": { 163 | "Arch": "PV64" 164 | }, 165 | "m3.medium": { 166 | "Arch": "HVM64" 167 | }, 168 | "m3.large": { 169 | "Arch": "HVM64" 170 | }, 171 | "m3.xlarge": { 172 | "Arch": "HVM64" 173 | }, 174 | "m3.2xlarge": { 175 | "Arch": "HVM64" 176 | }, 177 | "m4.large": { 178 | "Arch": "HVM64" 179 | }, 180 | "m4.xlarge": { 181 | "Arch": "HVM64" 182 | }, 183 | "m4.2xlarge": { 184 | "Arch": "HVM64" 185 | }, 186 | "m4.4xlarge": { 187 | "Arch": "HVM64" 188 | }, 189 | "m4.10xlarge": { 190 | "Arch": "HVM64" 191 | }, 192 | "c1.medium": { 193 | "Arch": "PV64" 194 | }, 195 | "c1.xlarge": { 196 | "Arch": "PV64" 197 | }, 198 | "c3.large": { 199 | "Arch": "HVM64" 200 | }, 201 | "c3.xlarge": { 202 | "Arch": "HVM64" 203 | }, 204 | "c3.2xlarge": { 205 | "Arch": "HVM64" 206 | }, 207 | "c3.4xlarge": { 208 | "Arch": "HVM64" 209 | }, 210 | "c3.8xlarge": { 211 | "Arch": "HVM64" 212 | }, 213 | "c4.large": { 214 | "Arch": "HVM64" 215 | }, 216 | "c4.xlarge": { 217 | "Arch": "HVM64" 218 | }, 219 | "c4.2xlarge": { 220 | "Arch": "HVM64" 221 | }, 222 | "c4.4xlarge": { 223 | "Arch": "HVM64" 224 | }, 225 | "c4.8xlarge": { 226 | "Arch": "HVM64" 227 | }, 228 | "g2.2xlarge": { 229 | "Arch": "HVMG2" 230 | }, 231 | "g2.8xlarge": { 232 | "Arch": "HVMG2" 233 | }, 234 | "r3.large": { 235 | "Arch": "HVM64" 236 | }, 237 | "r3.xlarge": { 238 | "Arch": "HVM64" 239 | }, 240 | "r3.2xlarge": { 241 | "Arch": "HVM64" 242 | }, 243 | "r3.4xlarge": { 244 | "Arch": "HVM64" 245 | }, 246 | "r3.8xlarge": { 247 | "Arch": "HVM64" 248 | }, 249 | "i2.xlarge": { 250 | "Arch": "HVM64" 251 | }, 252 | "i2.2xlarge": { 253 | "Arch": "HVM64" 254 | }, 255 | "i2.4xlarge": { 256 | "Arch": "HVM64" 257 | }, 258 | "i2.8xlarge": { 259 | "Arch": "HVM64" 260 | }, 261 | "d2.xlarge": { 262 | "Arch": "HVM64" 263 | }, 264 | "d2.2xlarge": { 265 | "Arch": "HVM64" 266 | }, 267 | "d2.4xlarge": { 268 | "Arch": "HVM64" 269 | }, 270 | "d2.8xlarge": { 271 | "Arch": "HVM64" 272 | }, 273 | "hi1.4xlarge": { 274 | "Arch": "HVM64" 275 | }, 276 | "hs1.8xlarge": { 277 | "Arch": "HVM64" 278 | }, 279 | "cr1.8xlarge": { 280 | "Arch": "HVM64" 281 | }, 282 | "cc2.8xlarge": { 283 | "Arch": "HVM64" 284 | } 285 | }, 286 | "AWSInstanceType2NATArch": { 287 | "t1.micro": { 288 | "Arch": "NATPV64" 289 | }, 290 | "t2.nano": { 291 | "Arch": "NATHVM64" 292 | }, 293 | "t2.micro": { 294 | "Arch": "NATHVM64" 295 | }, 296 | "t2.small": { 297 | "Arch": "NATHVM64" 298 | }, 299 | "t2.medium": { 300 | "Arch": "NATHVM64" 301 | }, 302 | "t2.large": { 303 | "Arch": "NATHVM64" 304 | }, 305 | "m1.small": { 306 | "Arch": "NATPV64" 307 | }, 308 | "m1.medium": { 309 | "Arch": "NATPV64" 310 | }, 311 | "m1.large": { 312 | "Arch": "NATPV64" 313 | }, 314 | "m1.xlarge": { 315 | "Arch": "NATPV64" 316 | }, 317 | "m2.xlarge": { 318 | "Arch": "NATPV64" 319 | }, 320 | "m2.2xlarge": { 321 | "Arch": "NATPV64" 322 | }, 323 | "m2.4xlarge": { 324 | "Arch": "NATPV64" 325 | }, 326 | "m3.medium": { 327 | "Arch": "NATHVM64" 328 | }, 329 | "m3.large": { 330 | "Arch": "NATHVM64" 331 | }, 332 | "m3.xlarge": { 333 | "Arch": "NATHVM64" 334 | }, 335 | "m3.2xlarge": { 336 | "Arch": "NATHVM64" 337 | }, 338 | "m4.large": { 339 | "Arch": "NATHVM64" 340 | }, 341 | "m4.xlarge": { 342 | "Arch": "NATHVM64" 343 | }, 344 | "m4.2xlarge": { 345 | "Arch": "NATHVM64" 346 | }, 347 | "m4.4xlarge": { 348 | "Arch": "NATHVM64" 349 | }, 350 | "m4.10xlarge": { 351 | "Arch": "NATHVM64" 352 | }, 353 | "c1.medium": { 354 | "Arch": "NATPV64" 355 | }, 356 | "c1.xlarge": { 357 | "Arch": "NATPV64" 358 | }, 359 | "c3.large": { 360 | "Arch": "NATHVM64" 361 | }, 362 | "c3.xlarge": { 363 | "Arch": "NATHVM64" 364 | }, 365 | "c3.2xlarge": { 366 | "Arch": "NATHVM64" 367 | }, 368 | "c3.4xlarge": { 369 | "Arch": "NATHVM64" 370 | }, 371 | "c3.8xlarge": { 372 | "Arch": "NATHVM64" 373 | }, 374 | "c4.large": { 375 | "Arch": "NATHVM64" 376 | }, 377 | "c4.xlarge": { 378 | "Arch": "NATHVM64" 379 | }, 380 | "c4.2xlarge": { 381 | "Arch": "NATHVM64" 382 | }, 383 | "c4.4xlarge": { 384 | "Arch": "NATHVM64" 385 | }, 386 | "c4.8xlarge": { 387 | "Arch": "NATHVM64" 388 | }, 389 | "g2.2xlarge": { 390 | "Arch": "NATHVMG2" 391 | }, 392 | "g2.8xlarge": { 393 | "Arch": "NATHVMG2" 394 | }, 395 | "r3.large": { 396 | "Arch": "NATHVM64" 397 | }, 398 | "r3.xlarge": { 399 | "Arch": "NATHVM64" 400 | }, 401 | "r3.2xlarge": { 402 | "Arch": "NATHVM64" 403 | }, 404 | "r3.4xlarge": { 405 | "Arch": "NATHVM64" 406 | }, 407 | "r3.8xlarge": { 408 | "Arch": "NATHVM64" 409 | }, 410 | "i2.xlarge": { 411 | "Arch": "NATHVM64" 412 | }, 413 | "i2.2xlarge": { 414 | "Arch": "NATHVM64" 415 | }, 416 | "i2.4xlarge": { 417 | "Arch": "NATHVM64" 418 | }, 419 | "i2.8xlarge": { 420 | "Arch": "NATHVM64" 421 | }, 422 | "d2.xlarge": { 423 | "Arch": "NATHVM64" 424 | }, 425 | "d2.2xlarge": { 426 | "Arch": "NATHVM64" 427 | }, 428 | "d2.4xlarge": { 429 | "Arch": "NATHVM64" 430 | }, 431 | "d2.8xlarge": { 432 | "Arch": "NATHVM64" 433 | }, 434 | "hi1.4xlarge": { 435 | "Arch": "NATHVM64" 436 | }, 437 | "hs1.8xlarge": { 438 | "Arch": "NATHVM64" 439 | }, 440 | "cr1.8xlarge": { 441 | "Arch": "NATHVM64" 442 | }, 443 | "cc2.8xlarge": { 444 | "Arch": "NATHVM64" 445 | } 446 | }, 447 | "AWSRegionArch2AMI": { 448 | "us-east-1": { 449 | "PV64": "ami-2a69aa47", 450 | "HVM64": "ami-6869aa05", 451 | "HVMG2": "ami-61e27177" 452 | }, 453 | "us-west-2": { 454 | "PV64": "ami-7f77b31f", 455 | "HVM64": "ami-7172b611", 456 | "HVMG2": "ami-60aa3700" 457 | }, 458 | "us-west-1": { 459 | "PV64": "ami-a2490dc2", 460 | "HVM64": "ami-31490d51", 461 | "HVMG2": "ami-4b694d2b" 462 | }, 463 | "eu-west-1": { 464 | "PV64": "ami-4cdd453f", 465 | "HVM64": "ami-f9dd458a", 466 | "HVMG2": "ami-2955524f" 467 | }, 468 | "eu-west-2": { 469 | "PV64": "NOT_SUPPORTED", 470 | "HVM64": "ami-886369ec", 471 | "HVMG2": "NOT_SUPPORTED" 472 | }, 473 | "eu-central-1": { 474 | "PV64": "ami-6527cf0a", 475 | "HVM64": "ami-ea26ce85", 476 | "HVMG2": "ami-81ac71ee" 477 | }, 478 | "ap-northeast-1": { 479 | "PV64": "ami-3e42b65f", 480 | "HVM64": "ami-374db956", 481 | "HVMG2": "ami-46220c21" 482 | }, 483 | "ap-northeast-2": { 484 | "PV64": "NOT_SUPPORTED", 485 | "HVM64": "ami-2b408b45", 486 | "HVMG2": "NOT_SUPPORTED" 487 | }, 488 | "ap-southeast-1": { 489 | "PV64": "ami-df9e4cbc", 490 | "HVM64": "ami-a59b49c6", 491 | "HVMG2": "ami-c212aba1" 492 | }, 493 | "ap-southeast-2": { 494 | "PV64": "ami-63351d00", 495 | "HVM64": "ami-dc361ebf", 496 | "HVMG2": "ami-0ad2db69" 497 | }, 498 | "ap-south-1": { 499 | "PV64": "NOT_SUPPORTED", 500 | "HVM64": "ami-ffbdd790", 501 | "HVMG2": "ami-ca3042a5" 502 | }, 503 | "us-east-2": { 504 | "PV64": "NOT_SUPPORTED", 505 | "HVM64": "ami-f6035893", 506 | "HVMG2": "NOT_SUPPORTED" 507 | }, 508 | "ca-central-1": { 509 | "PV64": "NOT_SUPPORTED", 510 | "HVM64": "ami-730ebd17", 511 | "HVMG2": "NOT_SUPPORTED" 512 | }, 513 | "sa-east-1": { 514 | "PV64": "ami-1ad34676", 515 | "HVM64": "ami-6dd04501", 516 | "HVMG2": "NOT_SUPPORTED" 517 | }, 518 | "cn-north-1": { 519 | "PV64": "ami-77559f1a", 520 | "HVM64": "ami-8e6aa0e3", 521 | "HVMG2": "NOT_SUPPORTED" 522 | } 523 | } 524 | }, 525 | "Resources": { 526 | "WebServerInstance": { 527 | "Type": "AWS::EC2::Instance", 528 | "Metadata": { 529 | "AWS::CloudFormation::Init": { 530 | "configSets": { 531 | "InstallAndRun": [ 532 | "Install", 533 | "Configure" 534 | ] 535 | }, 536 | "Install": { 537 | "packages": { 538 | "yum": { 539 | "mysql": [], 540 | "mysql-server": [], 541 | "mysql-libs": [], 542 | "httpd": [], 543 | "php": [], 544 | "php-mysql": [] 545 | } 546 | }, 547 | "files": { 548 | "/var/www/html/index.php": { 549 | "content": { 550 | "Fn::Join": [ 551 | "", 552 | [ 553 | "\n", 554 | " \n", 555 | " AWS CloudFormation PHP Sample\n", 556 | " \n", 557 | " \n", 558 | " \n", 559 | "

Welcome to the AWS CloudFormation PHP Sample

\n", 560 | "

\n", 561 | " \";\n", 564 | " print date(\"g:i A l, F j Y.\");\n", 565 | " ?>\n", 566 | "

\n", 567 | " \";\n", 578 | " }\n", 579 | " else\n", 580 | " {\n", 581 | " print \"Server = \" . $hostname . \"
\";\n", 582 | " }\n", 583 | " // Get the instance-id of the intance from the instance metadata\n", 584 | " curl_setopt($curl_handle,CURLOPT_URL,'http://169.254.169.254/latest/meta-data/instance-id');\n", 585 | " $instanceid = curl_exec($curl_handle);\n", 586 | " if (empty($instanceid))\n", 587 | " {\n", 588 | " print \"Sorry, for some reason, we got no instance id back
\";\n", 589 | " }\n", 590 | " else\n", 591 | " {\n", 592 | " print \"EC2 instance-id = \" . $instanceid . \"
\";\n", 593 | " }\n", 594 | " $Database = \"localhost\";\n", 595 | " $DBUser = \"", 596 | { 597 | "Ref": "DBUser" 598 | }, 599 | "\";\n", 600 | " $DBPassword = \"", 601 | { 602 | "Ref": "DBPassword" 603 | }, 604 | "\";\n", 605 | " print \"Database = \" . $Database . \"
\";\n", 606 | " $dbconnection = mysql_connect($Database, $DBUser, $DBPassword)\n", 607 | " or die(\"Could not connect: \" . mysql_error());\n", 608 | " print (\"Connected to $Database successfully\");\n", 609 | " mysql_close($dbconnection);\n", 610 | " ?>\n", 611 | "

PHP Information

\n", 612 | "

\n", 613 | " \n", 616 | " \n", 617 | "\n" 618 | ] 619 | ] 620 | }, 621 | "mode": "000600", 622 | "owner": "apache", 623 | "group": "apache" 624 | }, 625 | "/tmp/setup.mysql": { 626 | "content": { 627 | "Fn::Join": [ 628 | "", 629 | [ 630 | "CREATE DATABASE ", 631 | { 632 | "Ref": "DBName" 633 | }, 634 | ";\n", 635 | "GRANT ALL ON ", 636 | { 637 | "Ref": "DBName" 638 | }, 639 | ".* TO '", 640 | { 641 | "Ref": "DBUser" 642 | }, 643 | "'@localhost IDENTIFIED BY '", 644 | { 645 | "Ref": "DBPassword" 646 | }, 647 | "';\n" 648 | ] 649 | ] 650 | }, 651 | "mode": "000400", 652 | "owner": "root", 653 | "group": "root" 654 | }, 655 | "/etc/cfn/cfn-hup.conf": { 656 | "content": { 657 | "Fn::Join": [ 658 | "", 659 | [ 660 | "[main]\n", 661 | "stack=", 662 | { 663 | "Ref": "AWS::StackId" 664 | }, 665 | "\n", 666 | "region=", 667 | { 668 | "Ref": "AWS::Region" 669 | }, 670 | "\n" 671 | ] 672 | ] 673 | }, 674 | "mode": "000400", 675 | "owner": "root", 676 | "group": "root" 677 | }, 678 | "/etc/cfn/hooks.d/cfn-auto-reloader.conf": { 679 | "content": { 680 | "Fn::Join": [ 681 | "", 682 | [ 683 | "[cfn-auto-reloader-hook]\n", 684 | "triggers=post.update\n", 685 | "path=Resources.WebServerInstance.Metadata.AWS::CloudFormation::Init\n", 686 | "action=/opt/aws/bin/cfn-init -v ", 687 | " --stack ", 688 | { 689 | "Ref": "AWS::StackName" 690 | }, 691 | " --resource WebServerInstance ", 692 | " --configsets InstallAndRun ", 693 | " --region ", 694 | { 695 | "Ref": "AWS::Region" 696 | }, 697 | "\n", 698 | "runas=root\n" 699 | ] 700 | ] 701 | } 702 | } 703 | }, 704 | "services": { 705 | "sysvinit": { 706 | "mysqld": { 707 | "enabled": "true", 708 | "ensureRunning": "true" 709 | }, 710 | "httpd": { 711 | "enabled": "true", 712 | "ensureRunning": "true" 713 | }, 714 | "cfn-hup": { 715 | "enabled": "true", 716 | "ensureRunning": "true", 717 | "files": [ 718 | "/etc/cfn/cfn-hup.conf", 719 | "/etc/cfn/hooks.d/cfn-auto-reloader.conf" 720 | ] 721 | } 722 | } 723 | } 724 | }, 725 | "Configure": { 726 | "commands": { 727 | "01_set_mysql_root_password": { 728 | "command": { 729 | "Fn::Join": [ 730 | "", 731 | [ 732 | "mysqladmin -u root password '", 733 | { 734 | "Ref": "DBRootPassword" 735 | }, 736 | "'" 737 | ] 738 | ] 739 | }, 740 | "test": { 741 | "Fn::Join": [ 742 | "", 743 | [ 744 | "$(mysql ", 745 | { 746 | "Ref": "DBName" 747 | }, 748 | " -u root --password='", 749 | { 750 | "Ref": "DBRootPassword" 751 | }, 752 | "' >/dev/null 2>&1 /dev/null 2>&1 /dev/null; 17 | then 18 | curl_output=$(curl -L -o /tmp/Dynatrace-OneAgent-Linux.sh $DYNATRACE_ONEAGENT_DOWNLOAD) 19 | [ $? -ne 0 ] && echo \"curl failed! - $curl_output\" && remove_me && quit; 20 | elif which wget >/dev/null; 21 | then 22 | wget_output=$(wget --no-check-certificate -O /tmp/Dynatrace-OneAgent-Linux.sh $DYNATRACE_ONEAGENT_DOWNLOAD) 23 | [ $? -ne 0 ] && echo \"wget failed! - $wget_output\" && remove_me && quit; 24 | else 25 | echo \"No wget or curl found to download Dynatrace OneAgent\" 26 | remove_me 27 | quit 28 | fi 29 | echo \"Trying to install Dynatrace OneAgent...\" 30 | chmod 755 /tmp/Dynatrace-OneAgent-Linux.sh 31 | chown root:root /tmp/Dynatrace-OneAgent-Linux.sh 32 | /tmp/Dynatrace-OneAgent-Linux.sh APP_LOG_CONTENT_ACCESS=1 33 | group: root 34 | mode: "000755" 35 | owner: root -------------------------------------------------------------------------------- /NodeJSBeanStalkSample/.ebextensions/logging.config: -------------------------------------------------------------------------------- 1 | files: 2 | "/opt/elasticbeanstalk/tasks/bundlelogs.d/01-sample-app.conf": 3 | content: | 4 | /tmp/sample-app* 5 | 6 | "/opt/elasticbeanstalk/tasks/taillogs.d/01-sample-app.conf": 7 | content: | 8 | /tmp/sample-app.log 9 | -------------------------------------------------------------------------------- /NodeJSBeanStalkSample/.ebextensions/version.config: -------------------------------------------------------------------------------- 1 | option_settings: 2 | aws:elasticbeanstalk:application:environment: 3 | MYVERSION: NodeBeanstalk_Version1 4 | DT_TAGS: "Env=AWS Service=BeanStalkSample" -------------------------------------------------------------------------------- /NodeJSBeanStalkSample/NodeJSBeanStalkSample.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dynatrace/AWSMonitoringTutorials/6e3d8899fb3ece7d6673af3660ca859136c14250/NodeJSBeanStalkSample/NodeJSBeanStalkSample.zip -------------------------------------------------------------------------------- /NodeJSBeanStalkSample/app.js: -------------------------------------------------------------------------------- 1 | var port = process.env.PORT || 3000, 2 | http = require('http'), 3 | fs = require('fs'), 4 | os = require('os'), 5 | html = fs.readFileSync('index.html').toString().replace("HOSTNAME", os.hostname()); 6 | 7 | var minSleep = 500; 8 | 9 | var log = function(entry) { 10 | // console.log(entry); 11 | fs.appendFileSync('/tmp/sample-app.log', new Date().toISOString() + ' - ' + entry + '\n'); 12 | }; 13 | 14 | // ====================================================================== 15 | // Very inefficient way to "sleep" 16 | // ====================================================================== 17 | function sleep(time) { 18 | if(time < minSleep) time = minSleep; 19 | var stop = new Date().getTime(); 20 | while(new Date().getTime() < stop + time) { 21 | ; 22 | } 23 | } 24 | 25 | var server = http.createServer(function (req, res) { 26 | if (req.method === 'POST') { 27 | var body = ''; 28 | 29 | req.on('data', function(chunk) { 30 | body += chunk; 31 | }); 32 | 33 | req.on('end', function() { 34 | if (req.url === '/') { 35 | log('Received message: ' + body); 36 | } else if (req.url = '/scheduled') { 37 | log('Received task ' + req.headers['x-aws-sqsd-taskname'] + ' scheduled at ' + req.headers['x-aws-sqsd-scheduled-at']); 38 | } 39 | 40 | res.writeHead(200, 'OK', {'Content-Type': 'text/plain'}); 41 | res.end(); 42 | }); 43 | } else if (req.url.startsWith("/api")) { 44 | var url = require('url').parse(req.url, true); 45 | var closeResponse = true; 46 | 47 | // sleep a bit :-) 48 | var sleeptime = parseInt(url.query["sleep"]); 49 | if(sleeptime === 0) sleeptime = minSleep; 50 | log("Sleeptime: " + sleeptime); 51 | sleep(sleeptime); 52 | 53 | // figure out which API call they want to execute 54 | var status = "Unkown API Call"; 55 | if(url.pathname === "/api/sleeptime") { 56 | // Usage: /api/sleeptime?min=1234 57 | var sleepValue = parseInt(url.query["min"]); 58 | if(sleepValue >= 0 && sleepValue <= 10000) minSleep = sleepValue; 59 | status = "Minimum Sleep Time set to " + minSleep; 60 | } 61 | if(url.pathname === "/api/echo") { 62 | // Usage: /api/echo?text=your text to be echoed! 63 | status = "Thanks for saying: " + url.query["text"]; 64 | } 65 | if(url.pathname === "/api/login") { 66 | // Usage: /api/login?username=your user name 67 | status = "Welcome " + url.query["username"]; 68 | } 69 | if(url.pathname === "/api/invoke") { 70 | // Usage: /api/invoke?url=http://www.yourdomain.com 71 | var urlRequest = url.query["url"]; 72 | status = "Trying to invoke remote call to: " + urlRequest; 73 | 74 | var http = null; 75 | if(urlRequest.startsWith("https")) http = require("https"); 76 | else http = require("http"); 77 | closeResponse = false; 78 | var options = { 79 | host: urlRequest, 80 | path: '/' 81 | }; 82 | var result = http.get(urlRequest, function(getResponse) { 83 | log('STATUS: ' + getResponse.statusCode); 84 | log('HEADERS: ' + JSON.stringify(getResponse.headers)); 85 | 86 | // Buffer the body entirely for processing as a whole. 87 | var bodyChunks = []; 88 | getResponse.on('data', function(chunk) { 89 | bodyChunks.push(chunk); 90 | }).on('end', function() { 91 | var body = Buffer.concat(bodyChunks); 92 | log('BODY: ' + body); 93 | status = "Request to '" + url.query["url"] + "' returned with HTTP Status: " + getResponse.statusCode + " and response body length: " + body.length; 94 | res.writeHead(200, 'OK', {'Content-Type': 'text/plain'}); 95 | res.write(status); 96 | res.end(); 97 | }).on('error', function(error) { 98 | status = "Request to '" + url.query["url"] + "' returned in an error: " + error; 99 | res.writeHead(200, 'OK', {'Content-Type': 'text/plain'}); 100 | res.write(status); 101 | res.end(); 102 | }) 103 | }); 104 | } 105 | if(url.pathname === "/api/version") { 106 | // usage: /api/version 107 | // simply returns the version number as defined in the MYVERSION env-variable which is specified in the beanstalk version.conf file 108 | status = "Running on version: " + process.env.MYVERSION; 109 | } 110 | 111 | // only close response handler if we are done with work! 112 | if(closeResponse) { 113 | res.writeHead(200, 'OK', {'Content-Type': 'text/plain'}); 114 | res.write(status); 115 | res.end(); 116 | } 117 | } 118 | else 119 | { 120 | res.writeHead(200, 'OK', {'Content-Type': 'text/html'}); 121 | res.write(html); 122 | res.end(); 123 | } 124 | }); 125 | 126 | // Listen on port 3000, IP defaults to 127.0.0.1 127 | server.listen(port); 128 | 129 | // Put a friendly message on the terminal 130 | console.log('Server running at http://127.0.0.1:' + port + '/'); 131 | -------------------------------------------------------------------------------- /NodeJSBeanStalkSample/cron.yaml: -------------------------------------------------------------------------------- 1 | version: 1 2 | cron: 3 | - name: "task1" 4 | url: "/scheduled" 5 | schedule: "* * * * *" 6 | -------------------------------------------------------------------------------- /NodeJSBeanStalkSample/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Node.JS Elastic Beanstalk Tutorial with Dynatrace 4 | 5 | 74 | 75 | 76 |

77 |

Congratulations

78 | 79 |

This might be your first AWS Beanstalk App you ever deployed. 80 | The code base of this application was taken from the AWS Elastic Beanstalk Tutorial but was slightly modified for the Dynatrace AWS Tutorial that you can find here! 81 | The goal of this tutorial is to enable Full Stack Monitoring with Dynatrace on your Beanstalk Application. Following is a screenshot of Dynatrace Smartcape in case you deploy this application in a scalability group: 82 | If you want to learn more about Dynatrace visit our website and get started with your own Dynatrace SaaS Trial! 83 |

84 | This page is served from HOSTNAME! 85 |

86 |
87 |
88 |

Lets trace some code!

89 |
90 | Sleep Setting (in ms): 91 |
92 | 93 |
94 | Say Something : 95 | 96 |
97 | 98 |
99 | Invoke Server Side URL (full URL please) : 100 | 101 |
102 | 103 |
104 | Your Username (can be used for user tagging) : 105 | 106 |
107 | 108 |
109 | 110 |
111 | 112 |
113 |

Results will show up here!

114 |
115 | 116 |
117 |
118 |

External Links: To learn more about Beanstalk

119 | 128 |
129 | 130 | 176 | 177 | 178 | -------------------------------------------------------------------------------- /NodeJSBeanStalkSample/launch.bat: -------------------------------------------------------------------------------- 1 | set DT_TAGS=Env=AWS Service=BeanStalkSample 2 | node app.js -------------------------------------------------------------------------------- /NodeJSBeanStalkSample/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Elastic-Beanstalk-Sample-App", 3 | "version": "0.0.1", 4 | "private": true, 5 | "dependencies": {}, 6 | "scripts": { 7 | "start": "node app.js" 8 | } 9 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # AWS Monitoring Tutorials for Dynatrace SaaS/Managed 2 | 3 | WATCH THIS TUTORIAL on the [Dynatrace YouTube Channel](https://www.youtube.com/watch?v=R0bnDkM8k_o&t=124s&index=3&list=PLqt2rd0eew1YFx9m8dBFSiGYSBcDuWG38) 4 | 5 | In this tutorial we have different labs where we learn different use cases on how to monitor applications and services on AWS with Dynatrace SaaS. The same will also work if you have Dynatrace Managed installed On-Premise. Also remember: Dynatrace can not only monitor your AWS Environments but all your Apps deployed on premise, Azure, OpenStack, OpenShift, VMWare or anywhere else! 6 | 7 | 1. [Lab 1: Setting up AWS Monitoring through Cloud Watch Integration](#lab-1-setup-dynatrace-aws-monitoring-integration) 8 | 2. [Lab 2: Monitoring EC2 Instances with Dynatrace OneAgent](#lab-2-install-oneagent-on-ec2-instance) 9 | * [Lab 2(a): Monitoring EC2 instance with inbuilt application](#lab-2a-launch-an-ec2-instance-dynatraceoneagent-and-docker-application) 10 | 3. [Lab 3: Monitoring Node.JS deployed through AWS Beanstalk](#lab-3-monitor-nodejs-beanstalk-application) 11 | 4. [Lab 4: Monitoring LAMP Stack configured through CloudFormation](#lab-4-monitor-lamp-stack-configured-through-cloudformation) 12 | 5. [Lab 5: AWS ECS Container Monitoring](#lab-5-aws-ecs-container-monitoring) 13 | 6. [Lab 6: AWS CodeDeploy - Blue / Green Deployment](#lab-6-aws-codedeploy---blue--green-deployment) 14 | 7. [Lab 7: AWS Lambda Zombie Workshop with Manual RUM Injection](#lab-7-aws-lambda-zombie-workshop) 15 | 8. [Lab 8: Monitoring AWS Lambda Functions](#lab-8-monitoring-aws-lambda-functions) 16 | 17 | ## Pre-Requisits 18 | 1. You need an AWS account. If you dont have one [get one here](https://aws.amazon.com/) 19 | 2. You need a Dynatrace Account. Get your [Free SaaS Trial here!](http://bit.ly/dtsaastrial) 20 | 21 | ## Preparation 22 | **Amazon** 23 | 1. To remote into EC2 Instances we will need a Key Pair. Create one in preparation or once you walk through the lab 24 | 2. To learn more about Key Pairs and how to connect to EC2 Instances read [Connect to your Linux Instance](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/AccessingInstances.html) 25 | 26 | **Dynatrace OneAgent Download Instructions** 27 | 1. In your Dynatrace SaaS or Managed Portal navigate to Deploy Dynatrace -> Start Installation -> Linux 28 | 2. Copy the OneAgent Download and Installation command line (circled in red) as we will need it throughout the labs 29 | ![](./images/labintro_dynatracedeploy.png) 30 | 31 | # Lab 1 Setup Dynatrace AWS Monitoring Integration 32 | This lab will teach us how to setup the Dynatrace AWS Monitoring Integration with AWS CloudWatch. 33 | The goal is to see the Dynatrace AWS Monitoring Dashboard populuated with data pulled from both [AWS CloudWatch](https://aws.amazon.com/cloudwatch/) as well as from installed OneAgents: 34 | ![](./images/lab1_awsdashboard.png) 35 | 36 | **Step-by-Step Guide** 37 | 1. For Dynatrace SaaS please open [Dynatrace Doc: How do I start Amazon Web Service Monitoring](https://www.dynatrace.com/support/help/cloud-platforms/amazon-web-services/how-do-i-start-amazon-web-services-monitoring/). For Dynatrace Managed check out [Dynatrace Doc: How do I monitor AWS using role-based access?](https://help.dynatrace.com/dynatrace-managed/dynatrace-server/how-do-i-monitor-aws-using-role-based-access/) 38 | 2. Follow the instructions for either Role or Key-based authentication 39 | 3. Tip for Role-based: Make sure you remember the Role Name, your AWS Account ID and the External ID while creating the role. You will need it at the very last step of the configuration 40 | 4. Tip for Key-based authentication: For quick evaluation I think this is the easiest path assuming your AWS User has the [required policies attached](https://www.dynatrace.com/support/help/shortlink/aws-saas-deployment#monitoring-policy). 41 | 4. Once done Validate that Dynatrace shows data in the AWS Dashboard. Simply click on "AWS" in the Dynatrace menu and you should see a simliar screen as shown above 42 | 43 | **Costs:** AWS charges for CloudWatch API access when exceeding 1 million requests. More details can be found in the Dynatrace and CloudWatch Documentation 44 | 45 | # Lab 2 Install OneAgent On EC2 Instance 46 | This lab will teach us how to install a Dynatrace OneAgent on a Linux EC2 Instance. 47 | The goal is that the EC2 host will show up in Dynatrace and is fully monitored through a OneAgent 48 | ![](./images/lab2_ec2hostmonitor.png) 49 | 50 | There are multiple ways to install a Dynatrace OneAgent on a "bare" EC2 Instance. If configuration management tools such as Puppet, Chef, Ansible or AWS CodeDeploy are used then Dynatrace OneAgent deployment can be done through these tools. 51 | Another very convenient approach for EC2 is to specify startup scripts that automatically get executed whenever Amazon launches an EC2 instances. In EC2 this is called "User Data". 52 | 53 | **Step-by-Step Guide** 54 | 1. Logon to AWS and navigate to EC2. [This link](https://us-east-2.console.aws.amazon.com/ec2/v2/home) should also get you there! 55 | 2. Now select the option to **Launch a new Instance** 56 | 3. Select **Amazon Linux AMI** and then select the free tier eligible **t2.micro** instance type. Select Next 57 | 4. **Configure Instance:** Expand the Advanced section and specify the following User Data script (make sure you use your unique OneAgent Download URI or simply use the full two script lines that you see in the Dynatrace Deploy Agent Web UI) 58 | ``` 59 | #!/bin/bash 60 | wget -O Dynatrace-OneAgent-Linux.sh https://YOUR.FULL.DYNATRACE.ONEAGENT.DOWNLOADLINK 61 | /bin/sh Dynatrace-OneAgent-Linux.sh APP_LOG_CONTENT_ACCESS=1 62 | ``` 63 | 5. Click next and make yourself familiar with Storage options. We keep the defaults 64 | 6. **Add Tags:** on this configuration screen we add a custom tag. Key=EC2InstanceType; Value=LabExcercise. 65 | 7. Click through the rest of the steps. Review settings and click Launch 66 | 8. **Select or create** a new key pair. We will need this for remoting into EC2 67 | 9. You can observe the launch log 68 | 10. Navigate to the Dynatrace Hosts list and wait until the host shows up. Click on it and explore what is monitored 69 | 11. Expand the list of Properties and Tags. We should also find our EC2InstanceType tag with the value LabExcercise 70 | 71 | **Troubleshooting:** 72 | If something doesnt go as expected what to do? Well - Amazon provides a good way to access these EC2 instances 73 | 1. Navigate to your [EC2 Manager Console](https://us-east-2.console.aws.amazon.com/ec2/v2/home) 74 | 2. Select the EC2 instance in question 75 | 3. Explore the options such as **Connect** and follow the instructions to remote into that machine. 76 | 4. Explore **Actions -> Instance Settings -> Get System Log** to get access to the system log and verify what happened during startup 77 | ![](./images/lab1_ec2instancelist.PNG) 78 | 79 | **Useful Links** 80 | * [Running commands on your Linux Instance during Startup](http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/user-data.html) 81 | * [Running commands on your Windows Instance during Startup](http://docs.aws.amazon.com/AWSEC2/latest/WindowsGuide/UsingConfig_WinAMI.html#user-data-execution) 82 | 83 | # Lab 2a Launch an Ec2 Instance DynatraceOneAgent and docker application 84 | In this step we will Launch an EC2 instance with an inbuilt Docker application, install Dynatrace OneAgent and access the Dynatrace Web UI to view our instance being monitored. 85 | 86 | **Step by Step Guide** 87 | 1. Log into to AWS console 88 | 2. Select EC2 and Click on Launch an Instance. Make sure you are launching the EC2 instance in Oregon region (Top right menu) 89 | 3. Click on Community AMI's. In the Search box type dynatrace. Select the image **Dynatrace_Easytravel_Docker_EC2** 90 | 91 | ![](./images/lab2a_ec2imageselection.PNG) 92 | 93 | 4. Select **t2.medium** instance type and Click on **Configure Instance Details** 94 | 5. Expand the Advanced Details and specify the following User Data script (Grab the unique URL for Dynatrace OneAgent install from your Dynatrace UI) 95 | 96 | ``` 97 | #!/bin/sh 98 | wget 99 | /bin/sh 100 | chown ec2-user:ec2-user /home/ec2-user/easyTravel-Docker/docker-compose.yml 101 | /usr/local/bin/docker-compose -f /home/ec2-user/easyTravel-Docker/docker-compose.yml up -d 102 | ``` 103 | 6. Click Next, explore the options and Launch the EC2 instance. (You will have to generate or use an already existing Key to remote into the EC2 instance) 104 | 7. Now we will look into the Dynatrace UI to see monitoring data 105 | 106 | 107 | # Lab 3 Monitor-NodeJS-Beanstalk-Application 108 | This lab will teach us how to install a Dynatrace OneAgent into a Node.js application deployed with AWS Beanstalk. 109 | As a base we use the sample node.js application that AWS uses in their tutorials. For more information see ... 110 | The goal of this lab is to have full Node.js and End User monitoring enabled with Dynatrace. 111 | 112 | **Background Information on Beanstalk** 113 | 114 | Beanstalk allows you to simply upload your application code as a zip or war file to AWS. AWS Beanstalk then 115 | 1. Launches a new EC2 instance for you with the required runtime (Node.js, PHP, Java, .NET ...) 116 | 2. Extracts your ZIP/WAR file onto that machine 117 | 3. Sets Environment Variables and executes startup scripts to prepare the environment# 118 | 4. Launches the runtime environment (Node.js, PHP, Java, .NET ...) 119 | 120 | *Installing OneAgent on Beanstalk* 121 | One way to install a Dynatrace OneAgent on such a Beantstalk EC2 instance is to leverage the "Elastic Beanstalk Extensions" concept. Beanstalk allows you to put additonal configuraton and script instructions into a subfolder called .ebextensions. Files with the ending .config will then be analyzed and executed during the startup phase of an instance. In our example you will find the following files in the .ebextension directory: 122 | * dynatrace.config: Defines one Configuration Option (DYNATRACE_ONEAGENT_DOWNLOAD). It also comes with a special beanstalk installation script that gets put into a special directory which will be executed by Beanstalk as part of the instance launch process. This script references the DYNATRACE_ONEAGENT_DOWNLOAD option. You could either set the option value in the .config file before uploading it to AWS or you can set the value later when configuring the launch parameters. We will do THE LATTER. 123 | * version.config: This config files specifies additional environment variables that are set to the EC2 instance. It can be used to demonstrate custom process group tagging with Dynatrace 124 | 125 | **Prerequisit** 126 | 1. Download the NodeJSBeanStalkSample from this GitHub Repo 127 | 2. Explore the .ebextensions directory as explained above 128 | 3. Create a ZIP file of the full NodeJSBeanStalkSample including .ebextension directory. ATTENTION MAC USERS: Please make sure to create the zip from your terminal. Otherwise you may end up with the __MACOSX subfolder which can become a problem later on 129 | 130 | **Step-by-Step-Guide** 131 | 1. Logon to AWS and Navigate to Elastic Beanstalk. [This link](https://us-east-2.console.aws.amazon.com/elasticbeanstalk/home) should also get you there 132 | 2. **Create a new application** 133 | 3. Give it a name. Select **Node.js** as the platform and **upload your zip** file. Then click on **Configure more options** 134 | ![](./images/lab3_createnodeapp.png) 135 | 4. Click on Software Options and add DYNATRACE_ONEAGENT_DOWNLOAD with the full download URL for your OneAgent. Click on Save 136 | ![](./images/lab3_softwareenv.PNG) 137 | 5. Now its time to launch the environment 138 | 6. Once the environment is up and running we can access the website. It is a very simply one page website that is delivered by Node.js. Dynatrace OneAgent will automatically inject the JavaScript Tag for Real User Monitoring. You can verify that. 139 | ![](./images/lab3_beanstalkec2instance.png) 140 | 141 | **Additional Step: Process Group Identification** 142 | Dynatrace automatically detects process groups and by default does a pretty good job in detecting the logical application deployed by looking at different environment variables or application server configuration files. If you want to override that process you can configure a custom Process Group Detection Rule. In our version.config file we specify a custom environment variable called MYVERSION. In this additional step we simply configure dynatrace to detect the Process Group Name based on that value in case this environment variable is set. 143 | 1. In Dynatrace go to Settings -> Monitoring -> Process group detection 144 | 2. Add a new rule for Node.js and specify MYVERSION as the environment variable to look at 145 | 3. Next time you launch your application you will see Dynatrace will capture that value of our MYVERSION Environment Variable 146 | 147 | **Additional Step: Load Balancing** 148 | 1. Go to your Beanstalk Environment in AWS Console 149 | 2. Click on Configuration - Scaling 150 | 3. Change the environment type to "Load balancing, auto scale" 151 | 4. Apply the changes and let Beanstalk restart 152 | 5. Go back to the same settings after restart and change auto scale to minimum instances of 2 153 | 6. Apply changes and validate that Dynatrace detects both instances 154 | 155 | **Additional Step: Real User Monitoring** 156 | There are some additional RUM configurations we can define to better leverage Dynatrace Real User Monitoring 157 | 1. Enable jQuery support for our Beanstalk Application. You can configure this through the Web Application Settings! 158 | 2. Configure Cookie Support for elasticbeanstalk.com domains: If you host your app on the default domain given by AWS you have to go into the Advanced Settings for your Application and specify your full domain name, e.g: custom-env.ub2cp9hmpy.us-west-2.elasticbeanstalk.com in the field **Domain to be used for cookie placement**. Otherwise your browser will reject the Dynatrace Cookies necessary for end user tagging. This step IS NOT necessary if you host your app on a "normal" domain! 159 | 3. [Configure User Tagging](https://www.dynatrace.com/blog/automatic-identification-users-based-page-metadata/). The Application has a login button which will then set the Username to an HTML Element with the ID #loggedinusername. Please configure User Tagging by picking up that value through CSS Selectors 160 | Now you should be able to find your user by looking for the user name and see every single interaction with any button. 161 | *REMEMBER:* User Visits right now will show up once the Visits are completed which means after the 30 minutes timeout! 162 | 163 | **Additional Step: Request Tagging** 164 | Dynatrace provides a great way to dynamically tag web requests based on information passed to each web request. In our sample app we have calls to /api/version, /api/invoke, ... 165 | 1. Go to Settings -> Server-Side -> [Request attributes](https://www.dynatrace.com/blog/request-attributes-simplify-request-searches-filtering/) 166 | 2. Configure tagging for the pattern /api/\* and for the parameter text on /api/echo?echo= 167 | Try it out and then perform web request analysis based on these tags! 168 | 169 | Here is what you should see if you go to Smartscape. Dynatrace shows the logical Node.js service. The name BeanStalkService_v1 is actually taken from our previously defined custom process group detection. We also see that this service runs on 2 Node.js instances on two different EC2 hosts in two Availability Zones: 170 | ![](./images/lab3_beanstalkloadbalanced.png) 171 | 172 | **Useful Links** 173 | * [What Is AWS Beanstalk](http://docs.aws.amazon.com/elasticbeanstalk/latest/dg/Welcome.html) 174 | * [Dynatrace Blog:Set up custom process group monitoring](https://www.dynatrace.com/blog/set-custom-process-groups-monitoring/) 175 | * [Request Attribute Tagging](https://www.dynatrace.com/blog/request-attributes-simplify-request-searches-filtering/) 176 | * [User Tagging with Dynatrace](https://www.dynatrace.com/blog/automatic-identification-users-based-page-metadata/) 177 | 178 | # Lab 4 Monitor LAMP Stack configured through CloudFormation 179 | This lab will teach us how to use a pre-configured CloudFormation stack to configure a classical LAMP stack. We will inject the Dynatrace OneAgent into the User Data portion of the EC2 instance launch by changing the CloudFormation template. This will allow us to create multipl stacks of the same LAMP stack including Dynatrace OneAgent monitoring 180 | 181 | **Step-by-Step-Guide** 182 | 1. Logon to AWS and navigate to the [CloudFormation Service](https://us-east-2.console.aws.amazon.com/cloudformation/home) 183 | 2. **Create a new Stack**: Select LAMP Stack and then click on *View/Edit template* 184 | ![](./images/lab4_createlampstack.png) 185 | 3. We are going to add one new parameter: _DynatraceOneAgentLink_ which users can later provide. Simply add the following code snipped to the parameters in the JSON Editor 186 | ``` 187 | "DynatraceOneAgentLink": { 188 | "Description": "Dynatrace OneAgent Download", 189 | "Type": "String", 190 | "MaxLength": "256", 191 | "ConstraintDescription": "Full Download Link to your Dynatrace OneAgent. Get this from your Settings -> Deploy screen in your Dynatrace SaaS/Managed console" 192 | }, 193 | ``` 194 | 4. Now we are going to add a similar User Data startup script as we did when instrumenting a regular EC2 Instance launch. Scroll down to the "UserData" Property Definition. Right after the line "yum update -y aws-cfn-bootstrap\n" we will add the following code.: 195 | ``` 196 | "# Install Dynatrace OneAgent\n", 197 | "cd /home/ec2-user\n", 198 | "wget -O Dynatrace-OneAgent-Linux.sh ", 199 | { 200 | "Ref": "DynatraceOneAgentLink" 201 | }, 202 | "\n", 203 | "/bin/sh Dynatrace-OneAgent-Linux.sh APP_LOG_CONTENT_ACCESS=1\n", 204 | ``` 205 | 5. **Click on "Validate Template"** in the toolbar to make sure you have no typos. **PROBLEMS??** If you dont waste too much time feel free to copy/paste the [complete template from here!](/LAMPCloudFormationSample/LAMPTemplateWITHDynatraceOneAgent) 206 | 6. Now we have a CloudFormation script that will launch a LAMP Stack but that will also install a Dynatrace OneAgent where the actual download link is configurable through _DynatraceOneAgentLink_. 207 | 7. **Click on Create Stack** in the toolbar. This will get you back to the previous screen with your new template already uploaded to S3 208 | 8. **Click on Next** 209 | 9. Now we have to fill out all the parameters - including our _DynatraceOneAgentLink_. For the Dynatrace One Agent Link make sure to copy the complete path INCLUDING the " (quotes). Please also choose a good name for the stack and provide any type of passwords for the database properties. When done **Click Next** 210 | ![](./images/lab4_configurestack.png) 211 | 10. **Options**: Here you could define additonal tags that would automatically be picked up by Dynatrace OneAgent. Feel free to define a tag and explore that option. Once done **Click Next** 212 | 11. **Review**: Review your settings - then **Click Create** 213 | 12. You will end up in the Stack List. TIP: if your Stack doesnt show up click the Refresh button! It will take a while until everything is fully created! 214 | 13. Once the environment is in status *CREATE_COMPLETE* select the entry and find the URL to your enviornment in the Output tab in the bottom. Open that URL. You will see that PHP returns its standard page. 215 | 14. **Dynatrace**: Now move over to Dynatrace and explore the data collected. If you click on Technology you should see Apache and MySQL show up. Click on Apache, expand the bottom list of process groups and click on Proces Group Details. From there you can navigate further to the actual process group and explore more about the data captured: 216 | ![](./images/lab4_apacheprocessgroup.png) 217 | Navigating to the Smartscape actually shows you how Dynatrace OneAgent really automatically detects every single process on that EC2 Linux instance including MySql and some other native processes 218 | ![](./images/lab4_lampsmartscape.png) 219 | 220 | **Optional Step: MySQL Monitoring** 221 | As the LAMP stack comes with MySQL we can easily setup [MySQL Monitoring with Dynatrace](https://www.dynatrace.com/technologies/database/mysql-monitoring/mysql-performance/). 222 | Follow these steps 223 | 1. Click on Technologies and find the MySQL tile (notice the tile is light blue which means no deep monitoring in the moment) 224 | 2. Click on the tile and navigate your way through the process groups until you end up on your MySQL Process Group. 225 | 3. Follow the instructions to enable MySQL Monitoring. You will be able to specify username and password for Dynatrace to query your MySQL Database 226 | 4. Once you are done you will see MySQL Metrics in your MySQL Process Group. Explore the _MySQL metrics_ as well as in _Further details_ 227 | ![](./images/lab4_mysql.png) 228 | 229 | **Useful Links** 230 | * [AWS CloudFormation documentation](https://aws.amazon.com/documentation/cloudformation/) 231 | 232 | # Lab 5 AWS ECS Container Monitoring 233 | 234 | If you are new to ECS and want to get a quick start I recommend walking through the sample application deployment wizard. This wizard will create 235 | 1. Your First ECS Cluster 236 | 2. A EC2 Launch Configuration 237 | 3. A Auto Scaling Group using that Launch Configuration 238 | 4. A Task that runs a sample web site in a container 239 | 240 | In order to get Dynatrace Monitoring into that wizard generated scenario I found the easiest to modify the EC2 Launch Configuration and adding the Dynatrace OneAgent Installation steps to the User Data confiugration. As AWS doesnt allow to edit an existing Launch Configuration we have to copy it, modify it and then change the Auto Scaling group to point to our new Launch Configuration. 241 | Here are the steps involved 242 | 1. Make a copy of the Wizard generated Launch Configuration 243 | 2. Edit the User Data portion and add the OneAgent Installation steps. *ATTENTION:* The default AMI that is used for ECS EC2 Container Instances doesnt come with wget but it comes with curl. I also noticed I have to execute the install script with sudo in order for the installation script to run as root. Here is the code snippet that should work: 244 | ``` 245 | #!/bin/bash 246 | curl -O Dynatrace-OneAgent-Linux.sh https://YOUR.FULL.DYNATRACE.ONEAGENT.DOWNLOADLINK 247 | sudo /bin/sh Dynatrace-OneAgent-Linux.sh APP_LOG_CONTENT_ACCESS=1 INFRA_ONLY=0 248 | ``` 249 | 3. Edit the Auto Scaling Group and configure it to use your new EC2 Launch Configuration 250 | 4. Terminate the current EC2 Instances that were created previously. The Auto Scaling Group will make sure to launch new ones but now using your new Launch Configuration 251 | 252 | THATS IT :-) 253 | 254 | # Lab 6 AWS CodeDeploy - Blue / Green Deployment 255 | 256 | Similar to the ECS Lab I suggest you use the wizard that will create all configuration entries to deploy an app using a Blue/Green Deployment model. And just as we did in the ECS Lab I think the best way to inject the Dynatrace OneAgent is to duplicate the EC2 Launch Configuration, add the OneAgent Installation steps and then use this new Launch Configuration for the Auto Scaling Group that the wizard also created. That should do the trick! 257 | 258 | Here is a screenshot of my User Data configuration for the edited Launch Configuration. You can see the OneAgent installation procedure I added just before the AWS CodeDeploy Agent gets installed 259 | ![](./images/lab6_bluegreen_launchconfiguration_userdata.png) 260 | 261 | # Lab 7 AWS Lambda Zombie Workshop 262 | This lab from Amazon promotes Servless technology. It is often used on AWS Servless Meetups and Hackathons. 263 | Please follow the instructions on the [AWS Lambda Zombie Workshop GitHub Repo](https://github.com/awslabs/aws-lambda-zombie-workshop). 264 | For the Dynatrace lab we do not need to go through the full excercise. Just the initial deployment of the app and inintial configuration steps are sufficient to get the app up& running. 265 | 266 | Once the application is deployed you will see that Dynatrace automatically monitors those resources used by this application: DynamoDB and Lambdas (through our AWS Monitoring Integration) 267 | 268 | **Enable Real User Monitoring** 269 | In order to enable Real User Monitoring we have to manually inject the Dynatrace JavaScript Tag because the HTML pages are static files delivered through S3. 270 | Follow these steps to get this accomplished 271 | 1. Go to S3 and browse to the index.html page in the zombiestack S3 bucket 272 | 2. Download that index.html page 273 | 3. In Dynatrace setup agentless monitoring for a new Zombie App. Copy that JavaScript snippet 274 | 4. Edit the local index.html page and add the JavaScript snippet in the of the html file 275 | 5. Upload the modified index.html file 276 | From now on, every time you access the Zombie Web Application the Dynatrace JavaScript Agent will be loaded. This means that you have automatic real end user monitoring! 277 | ![](./images/lab5_endusermonitoring.png) 278 | 279 | # Lab 8 Monitoring AWS Lambda Functions 280 | 281 | If you want to monitor your AWS Lambda functions please follow the instructions for [How do I integrate Node.js Lambda functions](https://www.dynatrace.com/support/help/cloud-platforms/amazon-web-services/how-do-i-integrate-nodejs-lambda-functions/) 282 | 283 | In case you do not yet have a Lambda function that you can monitor feel free to setup a Lambda function with a respective API Gateway configuration based on the following very simply Lambda Node.js source code 284 | 285 | ```js 286 | /** 287 | * This is a very simply lambda function that simply executes random HTTP Requests to a randomly selected group of URLs 288 | * With the Dynatrace OneAgent injected you can end-to-end trace these calls 289 | * 290 | */ 291 | exports.handler = (event, context, callback) => { 292 | // TODO implement 293 | executeRequest("http://www.dynatrace.com"); 294 | executeRequest("http://www.amazon.com"); 295 | executeRequest("http://www.google.com"); 296 | }; 297 | 298 | var executeRequest = function(url, callback) { 299 | var https = require("https"); 300 | var fullUrl = require("url").parse(url); 301 | 302 | var request_options = { 303 | host: fullUrl.host, 304 | path: fullUrl.path, 305 | method: 'GET', 306 | }; 307 | 308 | // Set up the request 309 | var get_req = https.request(request_options, function(res) { 310 | var responseBody = ""; 311 | res.setEncoding('utf8'); 312 | res.on('data', function (chunk) { 313 | responseBody += chunk; 314 | }); 315 | res.on('end', function() { 316 | console.log(url + ": StatusCode = " + res.statusCode + " ContentLength: " + responseBody.length); 317 | //callback(null, null); 318 | }); 319 | }); 320 | 321 | // post the data 322 | get_req.end(); 323 | 324 | } 325 | ``` 326 | 327 | To enable Dynatrace Lambda Monitoring follow instructions based on [How do I integrate Node.js Lambda functions](https://www.dynatrace.com/support/help/cloud-platforms/amazon-web-services/how-do-i-integrate-nodejs-lambda-functions/) 328 | If you have instrumented your Lambda and then execute it via the endpoint of your API Gateway you will see that Dynatrace captures PurePaths as shown below: 329 | 330 | ![](./images/lab8_LambdaFunctionPurePath.PNG) 331 | 332 | For more information on Lambda support (Node.js, Java, ...) please have a look at our website and blog where our team constantly announces new and updated technology support for [Lambda and other Serverless technologies](https://www.dynatrace.com/news/tag/serverless/). 333 | -------------------------------------------------------------------------------- /TestingScripts/nodejsbeanstalktest.js: -------------------------------------------------------------------------------- 1 | var page = require('webpage').create(), 2 | system = require('system'), 3 | t, address; 4 | 5 | // ====================================================================== 6 | // Usage 7 | // ====================================================================== 8 | if (system.args.length === 1) { 9 | console.log('Usage: nodejsbeanstalktest.js [ ]'); 10 | phantom.exit(); 11 | } 12 | 13 | // ====================================================================== 14 | // Helper Functions 15 | // ====================================================================== 16 | function random (low, high) { 17 | var randomResult = Math.round(Number(Math.random() * (high - low))) + low; 18 | if(randomResult > high) randomResult = high; 19 | return randomResult; 20 | } 21 | 22 | function clickOnElementById(id) { 23 | page.evaluateJavaScript("function() { var ev=document.createEvent('MouseEvent');ev.initMouseEvent('click',true,true,window, null, 0, 0, 0, 0,false,false,false,false,0,null); document.getElementById('" + id + "').dispatchEvent(ev); }"); 24 | } 25 | 26 | var minWaitFor = 0; 27 | phantom.waitFor = function(callback, maxTime) { 28 | var startTime = Date.now(); 29 | var timeLapsed = 0; 30 | do { 31 | // Clear the event queue while waiting. 32 | // This can be accomplished using page.sendEvent() 33 | this.page.sendEvent('mousemove'); 34 | timeLapsed = (Date.now() - startTime); 35 | } while ((timeLapsed < minWaitFor) || (!callback() && (timeLapsed < maxTime))); 36 | } 37 | 38 | // ====================================================================== 39 | // Prep Work - Setting up our variables 40 | // ====================================================================== 41 | var randomUserNames = ["Andi","Joe","Gabi","Stephan","Joshua","John","Asad","Ted","Karolina","Jilene","Marci","Katie","Laurie","Lynne","Peter","Wayne","Joe","Ted","Susan"]; 42 | var randomEchStrings = ["Just Echo", "Another Echo", "Whats up?", "Hello??", "Somebody out there?"]; 43 | var randomInvokeURLs = ["https://www.amazon.com","http://www.cnn.com","http://www.foxnews.com","https://www.twitter.com","https://www.facebook.com","http://www.orf.at","http://www.dynatrace.com"]; 44 | t = Date.now(); 45 | address = system.args[1]; 46 | var username = (system.args.length > 2) ? system.args[2] : randomUserNames[random(0, randomUserNames.length)]; 47 | var echostring = (system.args.length > 3) ? system.args[3] : randomEchStrings[random(0, randomEchStrings.length)]; 48 | var invokeURL = (system.args.length > 4) ? system.args[4] : randomInvokeURLs[random(0, randomInvokeURLs.length)]; 49 | if(username == null || username == "undefined") username = "Default User"; 50 | if(echostring == null || echostring == "undefined") echostring = "Default Echo"; 51 | if(invokeURL == null || invokeURL == "undefined") invokeURL = "https://aws.amazon.com"; 52 | console.log("Start URL: " + address); 53 | console.log("Username: " + username); 54 | console.log("EchoString: " + echostring); 55 | console.log("InvokeURL: " + invokeURL); 56 | phantom.cookieEnabled = true; 57 | 58 | // ====================================================================== 59 | // Step Finish: Waits until the step is done and then moves to the next or stops the script execution 60 | // ====================================================================== 61 | function stepFinish(nextStep) { 62 | phantom.waitFor(function() {return !page.loading;}, 3000); 63 | var currResultText = page.evaluate(function(id) {return document.getElementById(id).innerText;}, "result"); 64 | console.log("Current Result Text: " + currResultText); 65 | 66 | if(nextStep != null) nextStep(); else { 67 | console.log("DONE!!"); 68 | phantom.exit(); 69 | } 70 | } 71 | 72 | // ====================================================================== 73 | // Step 1: Load the initial page 74 | // ====================================================================== 75 | function step1Open() { 76 | page.loading = true; 77 | page.onResourceRequested = function(request, networkRequest) { 78 | console.log('Request ' + JSON.stringify(request, undefined, 4)); 79 | console.log('Cookies' + JSON.stringify(page.cookies, undefined, 4)); 80 | }; 81 | page.onResourceReceived = function(response) { 82 | // console.log('Receive ' + JSON.stringify(response, undefined, 4)); 83 | }; 84 | page.open(address, function(status) { 85 | if (status !== 'success') { 86 | console.log('FAIL to load the address'); 87 | } else { 88 | t = Date.now() - t; 89 | console.log('Loading ' + system.args[1]); 90 | console.log('Loading time ' + t + ' msec'); 91 | } 92 | page.loading = false; 93 | 94 | console.log('Cookies' + JSON.stringify(page.cookies, undefined, 4)); 95 | 96 | setTimeout(stepFinish, 5000, step2Login); 97 | }); 98 | } 99 | 100 | // ====================================================================== 101 | // Step 2: Login 102 | // ====================================================================== 103 | function step2Login() { 104 | console.log("CLICK ON LOGIN"); 105 | page.evaluateJavaScript("function() { $('#Username').val('" + username + "'); }"); 106 | clickOnElementById("Login"); 107 | 108 | setTimeout(stepFinish, 5000, step3Echo); 109 | } 110 | 111 | // ====================================================================== 112 | // Step 3: Click on Echo 113 | // ====================================================================== 114 | function step3Echo() { 115 | console.log("CLICK ON ECHO"); 116 | page.evaluateJavaScript("function() { $('#SayText').val('" + echostring + "'); }"); 117 | clickOnElementById("Echo"); 118 | 119 | setTimeout(stepFinish, 5000, step4Invoke); 120 | } 121 | 122 | // ====================================================================== 123 | // Step 4: Click on Invoke 124 | // ====================================================================== 125 | function step4Invoke() { 126 | console.log("CLICK ON INVOKE"); 127 | page.evaluateJavaScript("function() { $('#RemoteURL').val('" + invokeURL + "'); }"); 128 | clickOnElementById("Invoke"); 129 | 130 | setTimeout(stepFinish, 5000, null); 131 | } 132 | 133 | 134 | // LAUNCH Script 135 | step1Open(); -------------------------------------------------------------------------------- /TestingScripts/readme.md: -------------------------------------------------------------------------------- 1 | Here you find testing scripts that can be used to generate traffic against the applications we are hosting on AWS 2 | 3 | # Node JS Beanstalk Traffic 4 | The script [nodejsbeanstalktest.js](/nodejsbeanstalktest.js) uses [PhantomJS](http://phantomjs.org/download.html) which is a free head-less browser testing software. 5 | The script has one mandatory and 3 optional parameters 6 | ``` 7 | Usage: nodejsbeanstalktest http://yournodejsbeanstalkurl [username] [echostring] [invokeurl] 8 | ``` 9 | The script will execute the following steps 10 | 1. Open your BeanStalk URL 11 | 2. Enters an Echo String and Clicks the Echo Button 12 | 3. Enters the Remote URL and hits Invoke Button 13 | 4. Eners the Username and hits Login 14 | The script will use your defined parameters. If they are not present the script will use a meaningful random value. 15 | 16 | ## Running consistent load from Windows 17 | The following can be used as a windows batch file to run these tests in an endless loop. Simply fill in your URL and PhantomJS location 18 | ``` 19 | set PHANTOMHOME=C:\phantomjs\phantomjs-2.1.1-windows\bin 20 | set NODEJSURL=http://YOURURL.elasticbeanstalk.com/ 21 | 22 | :again 23 | %PHANTOMHOME%/phantomjs nodejsbeanstalktest.js %NODEJSURL% 24 | goto again 25 | ``` 26 | 27 | ## Running consistent load from Linux 28 | For linux we can do something very similar 29 | ``` 30 | EXPORT PHANTOMHOME=./phantomjs-2.1.1-linux-x86_64/bin/phantomjs 31 | EXPORT NODEJSURL=http://YOURURL.elasticbeanstalk.com/ 32 | 33 | while true 34 | do 35 | echo "Hit CTRL-C to stop"; 36 | sleep 1; 37 | $PHANTOMHOME nodejsbeanstalktest.js $NODEJSURL 38 | done 39 | ``` 40 | If you save this into a bash you can even run it in parallel and with that generate even more load! 41 | 42 | Tip for AWS: 43 | If you want to generate load from AWS I suggest to create an EC2 Linux Instance and use the following script in the User Data section: 44 | ``` 45 | #!/bin/bash 46 | wget https://bitbucket.org/ariya/phantomjs/downloads/phantomjs-2.1.1-linux-x86_64.tar.bz2 47 | tar -xvf phantomjs-2.1.1-linux-x86_64.tar.bz2 48 | wget https://raw.githubusercontent.com/Dynatrace/AWSMonitoringTutorials/master/TestingScripts/nodejsbeanstalktest.js 49 | 50 | export PHANTOMHOME=./phantomjs-2.1.1-linux-x86_64/bin/phantomjs 51 | export NODEJSURL=http://YOURURL.elasticbeanstalk.com/ 52 | 53 | while true 54 | do 55 | echo "Hit CTRL-C to stop"; 56 | sleep 1; 57 | $PHANTOMHOME nodejsbeanstalktest.js $NODEJSURL 58 | done 59 | ``` 60 | -------------------------------------------------------------------------------- /TestingScripts/win_beanstalk.bat: -------------------------------------------------------------------------------- 1 | REM this script will run in an infinite loop and executes the nodejs phantom js script 2 | REM make sure to set the following environment variables: PHANTOMHOME, NODEJSURL 3 | set PHANTOMHOME=C:\phantomjs\phantomjs-2.1.1-windows\bin 4 | set NODEJSURL=http://custom-env.ub2cp9hmpy.us-west-2.elasticbeanstalk.com/ 5 | 6 | :again 7 | %PHANTOMHOME%/phantomjs nodejsbeanstalktest.js %NODEJSURL% 8 | goto again -------------------------------------------------------------------------------- /images/lab1_awsdashboard.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dynatrace/AWSMonitoringTutorials/6e3d8899fb3ece7d6673af3660ca859136c14250/images/lab1_awsdashboard.png -------------------------------------------------------------------------------- /images/lab1_ec2instancelist.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dynatrace/AWSMonitoringTutorials/6e3d8899fb3ece7d6673af3660ca859136c14250/images/lab1_ec2instancelist.PNG -------------------------------------------------------------------------------- /images/lab2_ec2hostmonitor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dynatrace/AWSMonitoringTutorials/6e3d8899fb3ece7d6673af3660ca859136c14250/images/lab2_ec2hostmonitor.png -------------------------------------------------------------------------------- /images/lab2a_ec2imageselection.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dynatrace/AWSMonitoringTutorials/6e3d8899fb3ece7d6673af3660ca859136c14250/images/lab2a_ec2imageselection.PNG -------------------------------------------------------------------------------- /images/lab2a_userdatascript.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dynatrace/AWSMonitoringTutorials/6e3d8899fb3ece7d6673af3660ca859136c14250/images/lab2a_userdatascript.PNG -------------------------------------------------------------------------------- /images/lab3_beanstalkec2instance.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dynatrace/AWSMonitoringTutorials/6e3d8899fb3ece7d6673af3660ca859136c14250/images/lab3_beanstalkec2instance.png -------------------------------------------------------------------------------- /images/lab3_beanstalkloadbalanced.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dynatrace/AWSMonitoringTutorials/6e3d8899fb3ece7d6673af3660ca859136c14250/images/lab3_beanstalkloadbalanced.png -------------------------------------------------------------------------------- /images/lab3_createnodeapp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dynatrace/AWSMonitoringTutorials/6e3d8899fb3ece7d6673af3660ca859136c14250/images/lab3_createnodeapp.png -------------------------------------------------------------------------------- /images/lab3_softwareenv.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dynatrace/AWSMonitoringTutorials/6e3d8899fb3ece7d6673af3660ca859136c14250/images/lab3_softwareenv.PNG -------------------------------------------------------------------------------- /images/lab4_apacheprocessgroup.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dynatrace/AWSMonitoringTutorials/6e3d8899fb3ece7d6673af3660ca859136c14250/images/lab4_apacheprocessgroup.png -------------------------------------------------------------------------------- /images/lab4_configurestack.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dynatrace/AWSMonitoringTutorials/6e3d8899fb3ece7d6673af3660ca859136c14250/images/lab4_configurestack.png -------------------------------------------------------------------------------- /images/lab4_createlampstack.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dynatrace/AWSMonitoringTutorials/6e3d8899fb3ece7d6673af3660ca859136c14250/images/lab4_createlampstack.png -------------------------------------------------------------------------------- /images/lab4_lampsmartscape.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dynatrace/AWSMonitoringTutorials/6e3d8899fb3ece7d6673af3660ca859136c14250/images/lab4_lampsmartscape.png -------------------------------------------------------------------------------- /images/lab4_mysql.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dynatrace/AWSMonitoringTutorials/6e3d8899fb3ece7d6673af3660ca859136c14250/images/lab4_mysql.png -------------------------------------------------------------------------------- /images/lab5_endusermonitoring.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dynatrace/AWSMonitoringTutorials/6e3d8899fb3ece7d6673af3660ca859136c14250/images/lab5_endusermonitoring.png -------------------------------------------------------------------------------- /images/lab6_bluegreen_launchconfiguration_userdata.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dynatrace/AWSMonitoringTutorials/6e3d8899fb3ece7d6673af3660ca859136c14250/images/lab6_bluegreen_launchconfiguration_userdata.png -------------------------------------------------------------------------------- /images/lab8_LambdaFunctionPurePath.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dynatrace/AWSMonitoringTutorials/6e3d8899fb3ece7d6673af3660ca859136c14250/images/lab8_LambdaFunctionPurePath.PNG -------------------------------------------------------------------------------- /images/lab8_createLambdaFunction.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dynatrace/AWSMonitoringTutorials/6e3d8899fb3ece7d6673af3660ca859136c14250/images/lab8_createLambdaFunction.PNG -------------------------------------------------------------------------------- /images/lab8_lambdaExecutionSuccess.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dynatrace/AWSMonitoringTutorials/6e3d8899fb3ece7d6673af3660ca859136c14250/images/lab8_lambdaExecutionSuccess.PNG -------------------------------------------------------------------------------- /images/lab8_lambdaOptionsScreen.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dynatrace/AWSMonitoringTutorials/6e3d8899fb3ece7d6673af3660ca859136c14250/images/lab8_lambdaOptionsScreen.PNG -------------------------------------------------------------------------------- /images/lab8_s3bucketURL.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dynatrace/AWSMonitoringTutorials/6e3d8899fb3ece7d6673af3660ca859136c14250/images/lab8_s3bucketURL.PNG -------------------------------------------------------------------------------- /images/lab8_serverlessIntegration.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dynatrace/AWSMonitoringTutorials/6e3d8899fb3ece7d6673af3660ca859136c14250/images/lab8_serverlessIntegration.PNG -------------------------------------------------------------------------------- /images/labintro_dynatracedeploy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dynatrace/AWSMonitoringTutorials/6e3d8899fb3ece7d6673af3660ca859136c14250/images/labintro_dynatracedeploy.png --------------------------------------------------------------------------------