CICD for PHP on AWS SunshinePHP 2019 Michael Moussa @michaelmoussa https://joind.in/talk/05470
A presentation at Sunshine PHP 2019 in February 2019 in Miami, FL, USA by Michael Moussa
CICD for PHP on AWS SunshinePHP 2019 Michael Moussa @michaelmoussa https://joind.in/talk/05470
Objective @michaelmoussa https://joind.in/talk/05470
Objective Set up CICD for a non-trivial PHP application running on AWS, and deploy it with zero downtime. @michaelmoussa https://joind.in/talk/05470
CICD? Continuous Integration @michaelmoussa https://joind.in/talk/05470
CICD? Continuous Deployment @michaelmoussa https://joind.in/talk/05470
CICD? Continuous Delivery @michaelmoussa https://joind.in/talk/05470
Getting started Application Load Balancer GitHub.com Autoscaling Group @michaelmoussa https://joind.in/talk/05470
CodeDeploy @michaelmoussa https://joind.in/talk/05470
CodeDeploy • Automates application deployments • • • • • • EC2 instances AWS Lambda ECS (Elastic Container Service) On-premise servers Deploy from GitHub or Amazon S3 Highly customizable @michaelmoussa https://joind.in/talk/05470
CodeDeploy - Example Assumptions • “Hello, world!” application code hosted on GitHub • Autoscaling group (3 instances) with application running • First time setup steps completed: • https://docs.aws.amazon.com/codedeploy/latest/userguide/gettingstarted-codedeploy.html • CodeDeploy Agent installed: • https://docs.aws.amazon.com/codedeploy/latest/userguide/codedeployagent-operations-install.html @michaelmoussa https://joind.in/talk/05470
CodeDeploy - Get started @michaelmoussa https://joind.in/talk/05470
CodeDeploy - Create application @michaelmoussa https://joind.in/talk/05470
CodeDeploy - Create application @michaelmoussa https://joind.in/talk/05470
CodeDeploy - Create application @michaelmoussa https://joind.in/talk/05470
CodeDeploy - Create application @michaelmoussa https://joind.in/talk/05470
CodeDeploy - Deployment type @michaelmoussa https://joind.in/talk/05470
CodeDeploy - Deployment type • • In-place deployment Blue/green deployment @michaelmoussa https://joind.in/talk/05470
CodeDeploy - Deployment type • • In-place deployment Blue/green deployment @michaelmoussa https://joind.in/talk/05470
CodeDeploy - Deployment type • • In-place deployment Blue/green deployment @michaelmoussa https://joind.in/talk/05470
CodeDeploy - Deployment type • • In-place deployment Blue/green deployment @michaelmoussa https://joind.in/talk/05470
CodeDeploy - Deployment type • • In-place deployment Blue/green deployment @michaelmoussa https://joind.in/talk/05470
CodeDeploy - Deployment type • • In-place deployment Blue/green deployment @michaelmoussa https://joind.in/talk/05470
CodeDeploy - Deployment type @michaelmoussa https://joind.in/talk/05470
CodeDeploy - Environment configuration @michaelmoussa https://joind.in/talk/05470
CodeDeploy - Environment configuration @michaelmoussa https://joind.in/talk/05470
CodeDeploy - Deployment settings @michaelmoussa https://joind.in/talk/05470
CodeDeploy - Deployment settings @michaelmoussa https://joind.in/talk/05470
CodeDeploy - Deployment settings @michaelmoussa https://joind.in/talk/05470
CodeDeploy - Deployment settings @michaelmoussa https://joind.in/talk/05470
CodeDeploy - Environment configuration @michaelmoussa https://joind.in/talk/05470
appspec.yml @michaelmoussa https://joind.in/talk/05470
CodeDeploy - appspec.yml version: 0.0 os: linux files: - source: / destination: /var/www/demo-application/ permissions: - object: /var/www/demo-application owner: root group: nginx mode: 750 type: - directory - object: /var/www/demo-application owner: root group: nginx mode: 640 type: - file hooks: BeforeInstall: - location: .aws/codedeploy/hooks/before-install.sh timeout: 300 runas: root @michaelmoussa https://joind.in/talk/05470
CodeDeploy - appspec.yml version: 0.0 os: linux files: - source: / destination: /var/www/demo-application/ permissions: - object: /var/www/demo-application owner: root group: nginx mode: 750 type: - directory - object: /var/www/demo-application owner: root group: nginx mode: 640 type: - file hooks: BeforeInstall: - location: .aws/codedeploy/hooks/before-install.sh timeout: 300 runas: root version: 0.0 @michaelmoussa https://joind.in/talk/05470
CodeDeploy - appspec.yml version: 0.0 os: linux files: - source: / destination: /var/www/demo-application/ permissions: - object: /var/www/demo-application owner: root group: nginx mode: 750 type: - directory - object: /var/www/demo-application owner: root group: nginx mode: 640 type: - file hooks: BeforeInstall: - location: .aws/codedeploy/hooks/before-install.sh timeout: 300 runas: root os: linux @michaelmoussa https://joind.in/talk/05470
CodeDeploy - appspec.yml version: 0.0 os: linux files: - source: / destination: /var/www/demo-application/ permissions: - object: /var/www/demo-application owner: root group: nginx mode: 750 type: - directory - object: /var/www/demo-application owner: root group: nginx mode: 640 type: - file hooks: BeforeInstall: https://docs.aws.amazon.com/codedeploy/latest/userguide/ - location: .aws/codedeploy/hooks/before-install.sh timeout: 300 reference-appspec-file-structure-files.html runas: root files: - source: / destination: /var/www/demo-application/ @michaelmoussa https://joind.in/talk/05470
CodeDeploy - appspec.yml version: 0.0 permissions: os: linux files: - object: /var/www/demo-application - source: / owner: root destination: group: /var/www/demo-application/ nginx permissions: mode: 750 - object: /var/www/demo-application owner:type: root group: nginx - directory mode: 750 - object: /var/www/demo-application type: owner: root - directory group: nginx - object: /var/www/demo-application owner:mode: root 640 group:type: nginx mode: 640 - file type: - file hooks: BeforeInstall: https://docs.aws.amazon.com/codedeploy/latest/userguide/ - location: .aws/codedeploy/hooks/before-install.sh timeout: 300 reference-appspec-file-structure-permissions.html runas: root @michaelmoussa https://joind.in/talk/05470
CodeDeploy - appspec.yml version: 0.0 os: linux files: - source: / destination: /var/www/demo-application/ permissions: - object: /var/www/demo-application owner: root hooks: group: nginx mode: 750 BeforeInstall: type: - location: .aws/codedeploy/hooks/before-install.sh - directory - object: /var/www/demo-application timeout: 300 owner: root runas:group: rootnginx mode: 640 type: - file hooks: https://docs.aws.amazon.com/codedeploy/latest/userguide/ BeforeInstall: #!/bin/bash - location: .aws/codedeploy/hooks/before-install.sh timeout: 300/var/www/demo-application/* reference-appspec-file-structure-hooks.html rm -rf runas: root @michaelmoussa https://joind.in/talk/05470
CodeDeploy - appspec.yml version: 0.0 os: linux files: - source: / destination: /var/www/demo-application/ permissions: - object: /var/www/demo-application owner: root hooks: group: nginx mode: 750 BeforeInstall: type: - location: .aws/codedeploy/hooks/before-install.sh - directory - object: /var/www/demo-application timeout: 300 owner: root runas:group: rootnginx mode: 640 type: - file hooks: https://docs.aws.amazon.com/codedeploy/latest/userguide/ BeforeInstall: - location: .aws/codedeploy/hooks/before-install.sh timeout: 300 reference-appspec-file-structure-hooks.html runas: root #!/bin/bash rm -rf /var/www/demo-application/* @michaelmoussa https://joind.in/talk/05470
CodeDeploy - appspec.yml version: 0.0 os: linux files: - source: / destination: /var/www/demo-application/ permissions: - object: /var/www/demo-application owner: root hooks: group: nginx mode: 750 BeforeInstall: type: - location: .aws/codedeploy/hooks/before-install.sh - directory - object: /var/www/demo-application timeout: 300 owner: root runas:group: rootnginx mode: 640 type: - file hooks: https://docs.aws.amazon.com/codedeploy/latest/userguide/ BeforeInstall: - location: .aws/codedeploy/hooks/before-install.sh timeout: 300 reference-appspec-file-structure-hooks.html runas: root @michaelmoussa https://joind.in/talk/05470
CodeDeploy - appspec.yml version: 0.0 os: linux files: - source: / destination: /var/www/demo-application/ permissions: - object: /var/www/demo-application owner: root group: nginx mode: 750 type: - directory - object: /var/www/demo-application owner: root group: nginx mode: 640 type: - file hooks: BeforeInstall: - location: .aws/codedeploy/hooks/before-install.sh timeout: 300 runas: root @michaelmoussa https://joind.in/talk/05470
CodeDeploy - appspec.yml - Event lifecycle @michaelmoussa https://joind.in/talk/05470
CodeDeploy - Deploy application @michaelmoussa https://joind.in/talk/05470
CodeDeploy - Deploy application @michaelmoussa https://joind.in/talk/05470
CodeDeploy - Deploy application @michaelmoussa https://joind.in/talk/05470
CodeDeploy - Deploy application @michaelmoussa https://joind.in/talk/05470
CodeDeploy - Deploy application @michaelmoussa https://joind.in/talk/05470
CodeDeploy - Deploy application @michaelmoussa https://joind.in/talk/05470
Other capabilities @michaelmoussa https://joind.in/talk/05470
CodeDeploy - Other capabilities • SNS Triggers • • • Instance (starts|succeeds|fails|ready) CloudWatch Alarms • • Deployment (start|succeeds|fails|stops|ready|rollback) Stop deployments if metric threshold is breached Automatic Rollback @michaelmoussa https://joind.in/talk/05470
Objective Set up CICD for a non-trivial PHP application running on AWS, and deploy it with zero downtime. @michaelmoussa https://joind.in/talk/05470
Objective Application Load Balancer GitHub.com Autoscaling Group @michaelmoussa https://joind.in/talk/05470
Objective Application Load Balancer CodeDeploy GitHub.com Autoscaling Group @michaelmoussa https://joind.in/talk/05470
Objective Set up CICD for a non-trivial PHP application running on AWS, and deploy it with zero downtime. @michaelmoussa https://joind.in/talk/05470
Objective Set up CICD for a non-trivial PHP application running on AWS, and deploy it with zero downtime. @michaelmoussa https://joind.in/talk/05470
CodeBuild @michaelmoussa https://joind.in/talk/05470
CodeBuild • Fully managed build service • • • • Compiles, tests, and packages code Scales continuously Pay-as-you-go Also highly customizable! @michaelmoussa https://joind.in/talk/05470
CodeBuild - Get started @michaelmoussa https://joind.in/talk/05470
CodeBuild - Get started @michaelmoussa https://joind.in/talk/05470
CodeBuild - Get started @michaelmoussa https://joind.in/talk/05470
CodeBuild - Source @michaelmoussa https://joind.in/talk/05470
CodeBuild - Source @michaelmoussa https://joind.in/talk/05470
CodeBuild - Environment @michaelmoussa https://joind.in/talk/05470
CodeBuild - Environment @michaelmoussa https://joind.in/talk/05470
CodeBuild - Environment @michaelmoussa https://joind.in/talk/05470
CodeBuild - Environment @michaelmoussa https://joind.in/talk/05470
CodeBuild - Environment @michaelmoussa https://joind.in/talk/05470
CodeBuild - Environment @michaelmoussa https://joind.in/talk/05470
CodeBuild - Environment @michaelmoussa https://joind.in/talk/05470
CodeBuild - buildspec.yml @michaelmoussa https://joind.in/talk/05470
CodeBuild - buildspec.yml version: 0.2 phases: install: commands: - yum update -y - amazon-linux-extras install php7.2 -y - yum install git-core php-mbstring php-xml zip unzip php-zip -y - curl -sS https://getcomposer.org/installer -o /tmp/composer-setup.php - php /tmp/composer-setup.php —install-dir=/usr/local/bin —filename=composer pre_build: commands: - composer install —no-interaction build: commands: - composer cs-check - composer test post_build: commands: - composer install —no-dev —optimize-autoloader —prefer-dist —no-interaction artifacts: files: - ‘**/*’ @michaelmoussa https://joind.in/talk/05470
CodeBuild - buildspec.yml version: 0.2 phases: install: commands: - yum update -y - amazon-linux-extras install php7.2 -y - yum install git-core php-mbstring php-xml zip unzip php-zip -y - curl -sS https://getcomposer.org/installer -o /tmp/composer-setup.php - php /tmp/composer-setup.php —install-dir=/usr/local/bin —filename=composer pre_build: commands: - composer install —no-interaction build: commands: - composer cs-check - composer test post_build: commands: - composer install —no-dev —optimize-autoloader —prefer-dist —no-interaction artifacts: files: - ‘**/*’ version: 0.2 @michaelmoussa https://joind.in/talk/05470
CodeBuild - buildspec.yml version: 0.2 phases: install: commands: - yum update -y phases: - amazon-linux-extras install php7.2 -y - yum install git-core php-mbstring php-xml zip unzip php-zip -y install: - curl -sS https://getcomposer.org/installer -o /tmp/composer-setup.php commands: - php /tmp/composer-setup.php —install-dir=/usr/local/bin —filename=composer pre_build: - yum update -y commands: - amazon-linux-extras php7.2 -y - composer installinstall —no-interaction build: - yum install git-core php-mbstring php-xml zip unzip php-zip -y commands: - curl -sS https://getcomposer.org/installer -o /tmp/composer-setup.php - composer cs-check - php /tmp/composer-setup.php - composer test —install-dir=/usr/local/bin —filename=composer post_build: commands: - composer install —no-dev —optimize-autoloader —prefer-dist —no-interaction artifacts: files: - ‘**/*’ @michaelmoussa https://joind.in/talk/05470
CodeBuild - buildspec.yml version: 0.2 phases: install: commands: - yum update -y phases: - amazon-linux-extras install php7.2 -y - yum install git-core php-mbstring php-xml zip unzip php-zip -y install: - curl -sS https://getcomposer.org/installer -o /tmp/composer-setup.php commands: - php /tmp/composer-setup.php —install-dir=/usr/local/bin —filename=composer pre_build: - yum update -y commands: - amazon-linux-extras php7.2 -y - composer installinstall —no-interaction build: - yum install git-core php-mbstring php-xml zip unzip php-zip -y commands: - curl -sS https://getcomposer.org/installer -o /tmp/composer-setup.php - composer cs-check - php /tmp/composer-setup.php - composer test —install-dir=/usr/local/bin —filename=composer post_build: commands: - composer install —no-dev —optimize-autoloader —prefer-dist —no-interaction artifacts: files: - ‘**/*’ @michaelmoussa https://joind.in/talk/05470
CodeBuild - buildspec.yml version: 0.2 phases: install: commands: - yum update -y phases: - amazon-linux-extras install php7.2 -y - yum install git-core php-mbstring php-xml zip unzip php-zip -y install: - curl -sS https://getcomposer.org/installer -o /tmp/composer-setup.php commands: - php /tmp/composer-setup.php —install-dir=/usr/local/bin —filename=composer pre_build: - yum update -y commands: - amazon-linux-extras php7.2 -y - composer installinstall —no-interaction build: - yum install git-core php-mbstring php-xml zip unzip php-zip -y commands: - curl -sS https://getcomposer.org/installer -o /tmp/composer-setup.php - composer cs-check - php /tmp/composer-setup.php - composer test —install-dir=/usr/local/bin —filename=composer post_build: commands: - composer install —no-dev —optimize-autoloader —prefer-dist —no-interaction artifacts: files: - ‘**/*’ @michaelmoussa https://joind.in/talk/05470
CodeBuild - buildspec.yml version: 0.2 phases: install: commands: - yum update -y - amazon-linux-extras install php7.2 -y - yum install git-core php-mbstring php-xml zip unzip php-zip -y - curl -sS https://getcomposer.org/installer -o /tmp/composer-setup.php - php /tmp/composer-setup.php —install-dir=/usr/local/bin —filename=composer pre_build: commands: - composer install —no-interaction build: commands: - composer cs-check - composer test post_build: commands: - composer install —no-dev —optimize-autoloader —prefer-dist —no-interaction artifacts: files: - ‘**/*’ phases: pre_build: commands: - composer install —no-interaction @michaelmoussa https://joind.in/talk/05470
CodeBuild - buildspec.yml version: 0.2 phases: install: commands: - yum update -y - amazon-linux-extras install php7.2 -y - yum install git-core php-mbstring php-xml zip unzip php-zip -y - curl -sS https://getcomposer.org/installer -o /tmp/composer-setup.php - php /tmp/composer-setup.php —install-dir=/usr/local/bin —filename=composer pre_build: commands: - composer install —no-interaction build: commands: - composer cs-check - composer test post_build: commands: - composer install —no-dev —optimize-autoloader —prefer-dist —no-interaction artifacts: files: - ‘**/*’ phases: build: commands: - composer cs-check - composer test @michaelmoussa https://joind.in/talk/05470
CodeBuild - buildspec.yml version: 0.2 phases: install: commands: - yum update -y - amazon-linux-extras install php7.2 -y - yum install git-core php-mbstring php-xml zip unzip php-zip -y phases: - curl -sS https://getcomposer.org/installer -o /tmp/composer-setup.php - php /tmp/composer-setup.php —install-dir=/usr/local/bin —filename=composer pre_build: post_build: commands: - composer install —no-interaction commands: build: - composer commands: install —no-dev —optimize-autoloader —prefer-dist —no-interaction - composer cs-check - composer test post_build: commands: - composer install —no-dev —optimize-autoloader —prefer-dist —no-interaction artifacts: files: - ‘**/*’ @michaelmoussa https://joind.in/talk/05470
CodeBuild - buildspec.yml version: 0.2 phases: install: commands: - yum update -y - amazon-linux-extras install php7.2 -y - yum install git-core php-mbstring php-xml zip unzip php-zip -y - curl -sS https://getcomposer.org/installer -o /tmp/composer-setup.php - php /tmp/composer-setup.php —install-dir=/usr/local/bin —filename=composer pre_build: commands: - composer install —no-interaction build: commands: - composer cs-check - composer test post_build: commands: - composer install —no-dev —optimize-autoloader —prefer-dist —no-interaction artifacts: files: - ‘**/’ artifacts: files: - ‘**/’ @michaelmoussa https://joind.in/talk/05470
CodeBuild - buildspec.yml version: 0.2 phases: install: commands: - yum update -y - amazon-linux-extras install php7.2 -y - yum install git-core php-mbstring php-xml zip unzip php-zip -y - curl -sS https://getcomposer.org/installer -o /tmp/composer-setup.php - php /tmp/composer-setup.php —install-dir=/usr/local/bin —filename=composer pre_build: commands: - composer install —no-interaction build: commands: - composer cs-check - composer test post_build: commands: - composer install —no-dev —optimize-autoloader —prefer-dist —no-interaction artifacts: files: - ‘**/*’ https://docs.aws.amazon.com/codebuild/ latest/userguide/build-spec-ref.html @michaelmoussa https://joind.in/talk/05470
CodeBuild - buildspec.yml version: 0.2 phases: install: commands: - yum update -y - amazon-linux-extras install php7.2 -y - yum install git-core php-mbstring php-xml zip unzip php-zip -y - curl -sS https://getcomposer.org/installer -o /tmp/composer-setup.php - php /tmp/composer-setup.php —install-dir=/usr/local/bin —filename=composer pre_build: commands: - composer install —no-interaction build: commands: - composer cs-check - composer test post_build: commands: - composer install —no-dev —optimize-autoloader —prefer-dist —no-interaction artifacts: files: - ‘**/*’ @michaelmoussa https://joind.in/talk/05470
CodeBuild - Artifacts @michaelmoussa https://joind.in/talk/05470
CodeBuild - Artifacts artifacts: files: - ‘**/*’ name: DemoApplication-$(date +%Y-%m-%d).zip @michaelmoussa https://joind.in/talk/05470
CodeBuild - Artifacts artifacts: files: - ‘**/*’ name: DemoApplication-$(date +%Y-%m-%d).zip @michaelmoussa https://joind.in/talk/05470
CodeBuild - Artifacts @michaelmoussa https://joind.in/talk/05470
CodeBuild - Artifacts @michaelmoussa https://joind.in/talk/05470
CodeBuild - Start build @michaelmoussa https://joind.in/talk/05470
CodeBuild - Start build @michaelmoussa https://joind.in/talk/05470
CodeBuild - Success! @michaelmoussa https://joind.in/talk/05470
CodeBuild - Success! @michaelmoussa https://joind.in/talk/05470
CodeBuild - Artifacts s3://php-codedeploy-example /build-artifacts /41dd4014-e610-43ed-a5d6-551c47570c8d /DemoApplication.zip @michaelmoussa https://joind.in/talk/05470
Other capabilities @michaelmoussa https://joind.in/talk/05470
CodeBuild - Other capabilities • • • • • Dependency caching VPC support Environment variables & secure parameters Build Docker images Larger build instance sizes @michaelmoussa https://joind.in/talk/05470
CodeBuild → CodeDeploy @michaelmoussa https://joind.in/talk/05470
CodeBuild → CodeDeploy Application Load Balancer CodeDeploy GitHub.com Autoscaling Group @michaelmoussa https://joind.in/talk/05470
CodeBuild → CodeDeploy Application Load Balancer Autoscaling Group CodeDeploy CodeBuild GitHub.com S3 @michaelmoussa https://joind.in/talk/05470
CodeBuild → CodeDeploy @michaelmoussa https://joind.in/talk/05470
CodePipeline @michaelmoussa https://joind.in/talk/05470
CodePipeline • Continuous integration & continuous delivery service • • • • Model, visualize, and automate steps AWS & third-party integration support Fully configurable workflow Cheap! @michaelmoussa https://joind.in/talk/05470
CodePipeline @michaelmoussa https://joind.in/talk/05470
CodePipeline Stage @michaelmoussa https://joind.in/talk/05470
CodePipeline Stage Action @michaelmoussa https://joind.in/talk/05470
CodePipeline Stage Stage Action @michaelmoussa https://joind.in/talk/05470
CodePipeline Stage Stage Action Action Action Action @michaelmoussa https://joind.in/talk/05470
CodePipeline Stage Stage Action Action Stage Action Action Stage Action Action Action @michaelmoussa https://joind.in/talk/05470
CodePipeline - Create pipeline @michaelmoussa https://joind.in/talk/05470
CodePipeline - Create pipeline @michaelmoussa https://joind.in/talk/05470
CodePipeline - Create pipeline @michaelmoussa https://joind.in/talk/05470
CodePipeline - Create pipeline @michaelmoussa https://joind.in/talk/05470
CodePipeline - Source location @michaelmoussa https://joind.in/talk/05470
CodePipeline - Source location @michaelmoussa https://joind.in/talk/05470
CodePipeline - Source location @michaelmoussa https://joind.in/talk/05470
CodePipeline - Build provider @michaelmoussa https://joind.in/talk/05470
CodePipeline - Deployment provider @michaelmoussa https://joind.in/talk/05470
CodePipeline @michaelmoussa https://joind.in/talk/05470
CodePipeline @michaelmoussa https://joind.in/talk/05470
CodePipeline @michaelmoussa https://joind.in/talk/05470
CodePipeline @michaelmoussa https://joind.in/talk/05470
CodePipeline @michaelmoussa https://joind.in/talk/05470
Other actions @michaelmoussa https://joind.in/talk/05470
CodePipeline - Other actions - Test • • • • • • Jenkins AWS CodeBuild BlazeMeter Ghost Inspector UI Testing HPE StormRunner Load Runscope API Monitoring @michaelmoussa https://joind.in/talk/05470
CodePipeline - Other actions - Approval @michaelmoussa https://joind.in/talk/05470
CodePipeline - Other actions - Approval @michaelmoussa https://joind.in/talk/05470
CodePipeline - Other actions - Approval @michaelmoussa https://joind.in/talk/05470
CodePipeline - Other actions - Approval @michaelmoussa https://joind.in/talk/05470
CodePipeline - Other actions - Approval @michaelmoussa https://joind.in/talk/05470
CodePipeline - Other actions - Invoke @michaelmoussa https://joind.in/talk/05470
CodePipeline - Other actions - Invoke @michaelmoussa https://joind.in/talk/05470
Putting it all together @michaelmoussa https://joind.in/talk/05470
CodePipeline → CodeBuild → CodeDeploy Application Load Balancer CodeDeploy CodePipeline GitHub.com CodeBuild Autoscaling Group S3 @michaelmoussa https://joind.in/talk/05470
Pull Requests @michaelmoussa https://joind.in/talk/05470
CodeBuild - Pull Requests @michaelmoussa https://joind.in/talk/05470
CodeBuild - Pull Requests https://docs.aws.amazon.com/codebuild/latest/userguide/sample-github-pull-request.html @michaelmoussa https://joind.in/talk/05470
Closing thoughts @michaelmoussa https://joind.in/talk/05470
Thanks! https://joind.in/talk/05470