AWSTemplateFormatVersion: 2010-09-09 Description: Monolith stack for the Application Modernization Workshop/ Immersion Day Parameters: LatestAmiId: Type: AWS::SSM::Parameter::Value Default: /aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2 Description: Use an AMI of your choosing, we recommend to use the latest available Resources: MonoToMicroVPC: Type: AWS::EC2::VPC Properties: CidrBlock: 10.0.0.0/16 EnableDnsSupport: true EnableDnsHostnames: true InstanceTenancy: default Tags: - Key: Name Value: MonoToMicroVPC MonoToMicroIGW: Type: AWS::EC2::InternetGateway Properties: Tags: - Key: Name Value: MonoToMicroIGW AttachGateway: Type: AWS::EC2::VPCGatewayAttachment Properties: VpcId: !Ref MonoToMicroVPC InternetGatewayId: !Ref MonoToMicroIGW MonoToMicroSubnet1: Type: AWS::EC2::Subnet Properties: VpcId: !Ref MonoToMicroVPC CidrBlock: 10.0.0.0/24 AvailabilityZone: !Select - '0' - !GetAZs Ref: AWS::Region MapPublicIpOnLaunch: true Tags: - Key: Name Value: MonoToMicroSubnet1 MonoToMicroSubnet2: Type: AWS::EC2::Subnet Properties: VpcId: !Ref MonoToMicroVPC CidrBlock: 10.0.1.0/24 AvailabilityZone: !Select - '1' - !GetAZs Ref: AWS::Region MapPublicIpOnLaunch: true Tags: - Key: Name Value: MonoToMicroSubnet2 MonoToMicroPublicRouteTable: Type: AWS::EC2::RouteTable Properties: VpcId: !Ref MonoToMicroVPC Tags: - Key: Name Value: MonoToMicroPublicRoute MonoToMicroPublicRoute: Type: AWS::EC2::Route DependsOn: AttachGateway Properties: RouteTableId: !Ref MonoToMicroPublicRouteTable GatewayId: !Ref MonoToMicroIGW DestinationCidrBlock: 0.0.0.0/0 MonoToMicroPublicSubnetRouteTableAssoc1: Type: AWS::EC2::SubnetRouteTableAssociation Properties: RouteTableId: !Ref MonoToMicroPublicRouteTable SubnetId: !Ref MonoToMicroSubnet1 MonoToMicroPublicSubnetRouteTableAssoc2: Type: AWS::EC2::SubnetRouteTableAssociation Properties: RouteTableId: !Ref MonoToMicroPublicRouteTable SubnetId: !Ref MonoToMicroSubnet2 DBSecurityGroup: Type: AWS::EC2::SecurityGroup Properties: GroupDescription: Open database for access VpcId: !Ref MonoToMicroVPC SecurityGroupIngress: - IpProtocol: tcp FromPort: 3306 ToPort: 3306 SourceSecurityGroupId: !Ref EC2SecurityGroup Tags: - Key: Name Value: MonoToMicroDBSG DBSubnetGroup: Type: AWS::RDS::DBSubnetGroup Properties: DBSubnetGroupDescription: MonoToMicroDBSubnetGroup SubnetIds: - !Ref MonoToMicroSubnet1 - !Ref MonoToMicroSubnet2 EC2SecurityGroup: Type: AWS::EC2::SecurityGroup Properties: GroupDescription: Open App access VpcId: !Ref MonoToMicroVPC SecurityGroupIngress: - IpProtocol: tcp FromPort: 80 ToPort: 80 CidrIp: 0.0.0.0/0 - IpProtocol: tcp FromPort: 443 ToPort: 443 CidrIp: 0.0.0.0/0 SecurityGroupEgress: - IpProtocol: tcp FromPort: 80 ToPort: 80 CidrIp: 0.0.0.0/0 - IpProtocol: tcp FromPort: 443 ToPort: 443 CidrIp: 0.0.0.0/0 Tags: - Key: Name Value: MonoToMicroEC2SG EC2SecurityGroupDBRule: Type: AWS::EC2::SecurityGroupEgress Properties: GroupId: !Ref EC2SecurityGroup IpProtocol: tcp FromPort: 3306 ToPort: 3306 DestinationSecurityGroupId: !Ref DBSecurityGroup InstanceLogGroup: Type: AWS::Logs::LogGroup Properties: RetentionInDays: 7 S3InstanceProfile: Type: AWS::IAM::InstanceProfile Properties: Path: / Roles: - !Ref S3Role S3Policy: Type: AWS::IAM::Policy Properties: PolicyName: !Sub ${AWS::StackName}-S3Policy PolicyDocument: Statement: - Effect: Allow Action: - s3:GetBucketLocation - s3:GetObject - s3:PutObject Resource: - !GetAtt UIBucket.Arn - !GetAtt AssetBucket.Arn - !Join - '' - - !GetAtt UIBucket.Arn - /* - !Join - '' - - !GetAtt AssetBucket.Arn - /* Roles: - !Ref S3Role S3Role: Type: AWS::IAM::Role Properties: RoleName: !Sub ${AWS::StackName}-MonoToMicroRole AssumeRolePolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Principal: Service: - ec2.amazonaws.com Action: - sts:AssumeRole ManagedPolicyArns: - arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore - arn:aws:iam::aws:policy/CloudWatchAgentServerPolicy Path: / DBInstance: Type: AWS::RDS::DBInstance DeletionPolicy: Delete Properties: DBName: MonoToMicroDB DBInstanceIdentifier: !Sub ${AWS::StackName}-MonoToMicroDB Engine: MySQL DBInstanceClass: db.t2.micro Port: 3306 MasterUsername: MonoToMicroUser MasterUserPassword: MonoToMicroPassword VPCSecurityGroups: - !Ref DBSecurityGroup AllocatedStorage: 5 DBSubnetGroupName: !Ref DBSubnetGroup MultiAZ: false Tags: - Key: Name Value: MonoToMicroDB UIBucket: Type: AWS::S3::Bucket Properties: PublicAccessBlockConfiguration: BlockPublicPolicy: false WebsiteConfiguration: ErrorDocument: error.html IndexDocument: index.html UIBucketPolicy: Type: AWS::S3::BucketPolicy Properties: Bucket: !Ref UIBucket PolicyDocument: Version: 2012-10-17 Statement: - Action: ['s3:GetObject'] Effect: Allow Resource: !Sub 'arn:aws:s3:::${UIBucket}/*' Principal: '*' AssetBucket: Type: AWS::S3::Bucket EC2Instance: Type: AWS::EC2::Instance CreationPolicy: ResourceSignal: Count: 1 Timeout: PT30M Metadata: AWS::CloudFormation::Init: configSets: default: - update - install - configure - create-service-files - start-service update: commands: update: command: sudo yum update -y install: packages: rpm: https://s3.amazonaws.com/ec2-downloads-windows/SSMAgent/latest/linux_amd64/amazon-ssm-agent.rpm: [] yum: amazon-cloudwatch-agent: [] git: [] java-11-amazon-corretto-headless: [] mariadb: [] unzip: [] configure: commands: 0-clone-repo: command: >- git clone https://github.com/aws-samples/unishop-monolith-to-microservices.git /home/ec2-user/MonoToMicro 1-create-tables: command: !Sub - sudo mysql -u MonoToMicroUser -h ${DB} -P 3306 -pMonoToMicroPassword < /home/ec2-user/MonoToMicro/MonoToMicroLegacy/database/create_tables.sql - { DB: !GetAtt 'DBInstance.Endpoint.Address' } 2-exportDbEndpoint: command: !Sub - export MONO_TO_MICRO_DB_ENDPOINT=${DB} - { DB: !GetAtt 'DBInstance.Endpoint.Address' } 3-gradle-install-build: command: | cd /home/ec2-user/ sudo wget https://services.gradle.org/distributions/gradle-6.9-bin.zip sudo unzip -d /home/ec2-user/ /home/ec2-user/gradle-6.9-bin.zip export PATH=$PATH:/home/ec2-user/gradle-6.9/bin cd /home/ec2-user/MonoToMicro/MonoToMicroLegacy gradle clean build cd /home/ec2-user/MonoToMicro/MonoToMicroLambda ./gradlew clean shadowJar 4-modify-configuration: command: >- sed -i "s/:\/\/.*\"/:\/\/$(curl -s http://169.254.169.254/latest/meta-data/public-hostname)\"/g" /home/ec2-user/MonoToMicro/MonoToMicroUI/config.json 5-populate-buckets: command: !Sub | AWS_DEFAULT_REGION=${AWS::Region} aws s3 cp /home/ec2-user/MonoToMicro/MonoToMicroUI s3://${UIBucket}/ --recursive aws s3 cp /home/ec2-user/MonoToMicro/MonoToMicroLambda/build/libs s3://${AssetBucket}/ --recursive create-service-files: files: /etc/systemd/system/mono2micro.service: encoding: plain content: | [Unit] Description=Restart Mono2Micro Wants=network.target After=syslog.target network-online.target amazon-cloudwatch-agent.target [Service] Type=simple ExecStart=/home/ec2-user/MonoToMicro/m2minit.sh Restart=on-failure RestartSec=60 KillMode=process [Install] WantedBy=multi-user.target mode: '000644' group: root user: root /home/ec2-user/MonoToMicro/m2minit.sh: encoding: plain content: | #!/bin/bash source /home/ec2-user/MonoToMicro/m2mcfg.sh source /home/ec2-user/MonoToMicro/m2mrun.sh mode: '000555' group: ec2-user user: ec2-user /home/ec2-user/MonoToMicro/m2mcfg.sh: encoding: plain content: !Sub - | #!/bin/bash export Database=${DB} export MONO_TO_MICRO_DB_ENDPOINT=${DB} export AWS_DEFAULT_REGION=${AWS::Region} export UI_RANDOM_NAME=${UIBucket} export ASSETS_RANDOM_NAME=${AssetBucket} export PATH=$PATH:/home/ec2-user/gradle-6.9/bin - { DB: !GetAtt 'DBInstance.Endpoint.Address' } mode: '000555' group: ec2-user user: ec2-user /home/ec2-user/MonoToMicro/m2mrun.sh: encoding: plain content: | #!/bin/bash java -jar /home/ec2-user/MonoToMicro/MonoToMicroLegacy/build/libs/MonoToMicroLegacy-0.0.1-SNAPSHOT.jar &> /home/ec2-user/MonoToMicro/MonoToMicroLegacy/build/libs/app.log & mode: '000555' group: ec2-user user: ec2-user /opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.json: content: !Sub | {"logs": {"logs_collected": {"files": {"collect_list": [{"file_path": "/home/ec2-user/MonoToMicro/MonoToMicroLegacy/build/libs/app.log","log_group_name": "${InstanceLogGroup}","log_stream_name":"${InstanceLogGroup}-app", "timezone": "Local"}]}}}} mode: '000444' group: ec2-user user: ec2-user start-service: commands: 0-start-service: command: | sudo systemctl daemon-reload sudo systemctl enable mono2micro sudo systemctl start mono2micro sudo amazon-cloudwatch-agent-ctl -a fetch-config -s -m ec2 -c file:/opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.json Properties: InstanceType: t3.small ImageId: !Ref LatestAmiId SubnetId: !Ref MonoToMicroSubnet1 SecurityGroupIds: - !Ref EC2SecurityGroup IamInstanceProfile: !Ref S3InstanceProfile UserData: Fn::Base64: !Sub | #!/bin/bash sudo yum install -y aws-cfn-bootstrap /opt/aws/bin/cfn-init -v --stack ${AWS::StackName} --resource EC2Instance --region ${AWS::Region} --configsets default /opt/aws/bin/cfn-signal -e $? --stack ${AWS::StackName} --resource EC2Instance --region ${AWS::Region} Tags: - Key: Name Value: MonoToMicroEC2 PublicDnsNameSSMParam: Type: AWS::SSM::Parameter Properties: Name: UniShopPublicDnsName Value: !Sub - 'http://${Dns}' - { Dns: !GetAtt EC2Instance.PublicDnsName} Type: String Description: Monolith Public DNS Param VpcIdSSMParam: Type: AWS::SSM::Parameter Properties: Name: UniShopVpcId Value: !Ref MonoToMicroVPC Type: String Description: Monolith VPC ID LambdaAssetBucketSSMParam: Type: AWS::SSM::Parameter Properties: Name: LambdaAssetBucketName Type: String Value: !Ref AssetBucket Outputs: PublicDns: Value: !GetAtt - PublicDnsNameSSMParam - Value Description: Server Public DNS VpcId: Value: !GetAtt - VpcIdSSMParam - Value AssetBucket: Value: !Ref AssetBucket Description: S3 Bucket containing the compiled Lambda function UIBucket: Value: !Ref UIBucket Description: S3 Bucket containing the UniShop website WebsiteURL: Value: !GetAtt - UIBucket - WebsiteURL Description: URL for UniShop website hosted on S3