UNPKG

genericsuite-be-scripts

Version:
404 lines (369 loc) 14.2 kB
AWSTemplateFormatVersion: '2010-09-09' Description: CloudFormation template to deploy FastAPI app with EC2 and ECR, including all necessary resources (VPC, Subnets, Launch Configuration). Parameters: KeyName: Description: Name for the EC2 KeyPair to enable SSH access to the instance Type: AWS::EC2::KeyPair::KeyName EcrRepositoryName: Description: ECR docker images repository name Type: String EcrDockerImageUri: Description: Complete URI of the ECR repository Docker image Type: String EcrDockerImageTag: Description: ECR repository Docker image tag Type: String Default: latest AppName: Description: application name Type: String AppStage: Description: application stage (qa, prod, staging, demo, dev) Type: String AwsRegion: Description: application region Type: String KmsKeyAlias: Type: String Description: The alias of the KMS key to use for EBS encryption S3BucketName1: Description: App S3 Bucket name Type: String AsmSecretsName: Description: Secrets Manager - Secrets set name Type: String AsmEnvsName: Description: Secrets Manager - Environment variables set name Type: String AwsAccountId: Description: AWS account Id Type: String DomainName: Description: Domain name for the ALB Type: String HostedZoneId: Description: The ID of the hosted zone where the domain is managed Type: AWS::Route53::HostedZone::Id DomainStackName: Description: Name of the stack that created the domain resources Type: String DefaultSecurityGroupId: Description: localstack default security group id Type: String Resources: # VPC: # Type: AWS::EC2::VPC # Properties: # CidrBlock: 10.0.0.0/16 # EnableDnsHostnames: true # EnableDnsSupport: true # InstanceTenancy: default # Tags: # - Key: Name # Value: !Sub ${AppName}-${AppStage}-vpc # - Key: App # Value: !Ref AppName # - Key: Stage # Value: !Ref AppStage # Subnet1: # Type: AWS::EC2::Subnet # Properties: # VpcId: !Ref VPC # AvailabilityZone: !Select # - 0 # - !GetAZs '' # CidrBlock: 10.0.1.0/24 # MapPublicIpOnLaunch: true # Tags: # - Key: Name # Value: !Sub ${AppName}-${AppStage}-subnet-1 # - Key: App # Value: !Ref AppName # - Key: Stage # Value: !Ref AppStage # InstanceSecurityGroup: # Type: AWS::EC2::SecurityGroup # Properties: # GroupName: !Sub ${AppName}-${AppStage}-sg-ec2 # GroupDescription: Enable SSH and HTTP access # VpcId: !Ref VPC # # IpPermissions: # # - FromPort: 80, # # IpProtocol: tcp # # IpRanges: # # - CidrIp: 0.0.0.0/0 # # ToPort: 80, # # - FromPort: 22, # # IpProtocol: tcp # # IpRanges: # # - CidrIp: 0.0.0.0/0 # # ToPort: 22, # SecurityGroupIngress: # - IpProtocol: tcp # FromPort: 80 # ToPort: 80 # # SourceSecurityGroupId: !Ref LoadBalancerSecurityGroup # - IpProtocol: tcp # FromPort: 22 # ToPort: 22 # CidrIp: 0.0.0.0/0 # Consider restricting this to your IP range # Tags: # - Key: App # Value: !Ref AppName # - Key: Stage # Value: !Ref AppStage # Ec2InstanceRole: # Type: AWS::IAM::Role # Properties: # RoleName: !Sub ${AppName}-${AppStage}-ec2-instance-role # AssumeRolePolicyDocument: # Version: '2012-10-17' # Statement: # - Effect: Allow # Principal: # Service: # - ec2.amazonaws.com # Action: # - sts:AssumeRole # Path: / # ManagedPolicyArns: # # - arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore # - arn:aws:iam::aws:policy/CloudWatchAgentServerPolicy # # Bingo! this enabled SSM # # - arn:aws:iam::aws:policy/service-role/AmazonEC2RoleforSSM # Policies: # - PolicyName: Ec2InstancePolicy # PolicyDocument: # Version: '2012-10-17' # Statement: # - Effect: Allow # Action: # - ec2:Describe* # Resource: '*' # - PolicyName: Ec2S3AccessPolicy1 # PolicyDocument: # Version: '2012-10-17' # Statement: # - Effect: Allow # Action: # - s3:PutObject # - s3:PutObjectAcl # - s3:GetObject # - s3:GetObjectAcl # - s3:DeleteObject # # Resource: arn:aws:s3:::AWS_S3_CHATBOT_ATTACHMENTS_BUCKET_placeholder/* # # Resource: !Sub arn:aws:s3:::${S3BucketName1}/* # Resource: '*' # - PolicyName: Ec2LogsPolicy # PolicyDocument: # Version: '2012-10-17' # Statement: # - Effect: Allow # Action: # - logs:CreateLogGroup # - logs:CreateLogStream # - logs:PutLogEvents # Resource: arn:*:logs:*:*:* # - PolicyName: Ec2EcrLoginPolicy # PolicyDocument: # Version: '2012-10-17' # Statement: # - Effect: Allow # Action: # - ecr:GetAuthorizationToken # Resource: '*' # - PolicyName: Ec2EcrAccessPolicy # PolicyDocument: # Version: '2012-10-17' # Statement: # - Effect: Allow # Action: # - ecr:BatchCheckLayerAvailability # - ecr:BatchGetImage # - ecr:GetDownloadUrlForLayer # Resource: # # - !Sub arn:aws:ecr:${AwsRegion}:${AwsAccountId}:repository/AWS_ECR_REPOSITORY_NAME_placeholder # - !Sub arn:aws:ecr:${AwsRegion}:${AwsAccountId}:repository/${EcrRepositoryName} # - PolicyName: Ec2SecretsAccessPolicy # PolicyDocument: # Version: '2012-10-17' # Statement: # - Effect: Allow # Action: # - secretsmanager:GetSecretValue # Resource: '*' # # Resource: # # # - arn:aws:secretsmanager:*:*:secret:AWS_SECRETS_MANAGER_SECRETS_NAME_placeholder # # - !Sub arn:aws:secretsmanager:*:*:secret:${AsmSecretsName} # # # - arn:aws:secretsmanager:*:*:secret:AWS_SECRETS_MANAGER_ENVS_NAME_placeholder # # - !Sub arn:aws:secretsmanager:*:*:secret:${AsmEnvsName} # - PolicyName: Ec2KmsAccessPolicy # PolicyDocument: # Version: '2012-10-17' # Statement: # - Effect: Allow # Action: # - kms:Decrypt # - kms:GenerateDataKey* # - kms:CreateGrant # # Resource: !Sub 'arn:aws:kms:${AWS::Region}:${AWS::AccountId}:key/*' # Resource: '*' # # Resource: !Sub 'arn:aws:kms:${AWS::Region}:${AWS::AccountId}:alias/${KmsKeyAlias}' # # Resource: '*' # # Resource: # # # - arn:aws:kms:AWS_REGION_placeholder:AWS_ACCOUNT_ID_placeholder:alias/AWS_KMS_KEY_ALIAS_placeholder # # - !Sub arn:aws:kms:${AwsRegion}:${AwsAccountId}:alias/${KmsKeyAlias} # - PolicyName: Ec2CloudWatchLogsPolicy # PolicyDocument: # Version: '2012-10-17' # Statement: # - Effect: Allow # Action: # - logs:CreateLogGroup # - logs:CreateLogStream # - logs:PutLogEvents # - logs:DescribeLogStreams # Resource: # - !Sub arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:${AppName}-${AppStage}-ec2-logs:* # Ec2InstanceProfile: # Type: AWS::IAM::InstanceProfile # Properties: # InstanceProfileName: !Sub ${AppName}-${AppStage}-ec2-instance-profile # Path: / # Roles: # - !Ref Ec2InstanceRole AppLogGroup: Type: AWS::Logs::LogGroup Properties: LogGroupName: !Sub ${AppName}-${AppStage}-ec2-logs RetentionInDays: 3 # Adjust as needed EC2Instance: Type: AWS::EC2::Instance Properties: # ImageId: ami-0c55b159cbfafe1f0 ImageId: ami-0195204d5dce06d99 # Amazon Linux 2 AMI / 64-bit (x86) # ImageId: ami-003d53c9bb0a387f4 # Amazon Linux 2 AMI / 64-bit (Arm) InstanceType: t2.micro KeyName: !Ref KeyName Count: 1 SecurityGroups: - !Sub ${DefaultSecurityGroupId} # - !Ref InstanceSecurityGroup # # SubnetId: !Ref SubnetId # SubnetId: !Ref Subnet1 # https://aws.amazon.com/blogs/security/get-the-full-benefits-of-imdsv2-and-disable-imdsv1-across-your-aws-infrastructure/ # Enable imdsv2 : --metadata-options “HttpEndpoint=enabled,HttpTokens=required” # MetadataOptions: # HttpTokens: required # HttpEndpoint: enabled BlockDeviceMappings: - DeviceName: /dev/xvda Ebs: VolumeSize: 50 DeleteOnTermination: true VolumeType: gp2 # Encrypted: true # KmsKeyId: !Sub 'arn:aws:kms:${AWS::Region}:${AWS::AccountId}:alias/${KmsKeyAlias}' # IamInstanceProfile: # Name: !Ref Ec2InstanceProfile TagSpecifications: - ResourceType: instance Tags: - Key: Name Value: !Sub ${AppName}-${AppStage}-instance - Key: App Value: !Ref AppName - Key: Stage Value: !Ref AppStage - ResourceType: volume Tags: - Key: Name Value: !Sub ${AppName}-${AppStage}-root-volume - Key: App Value: !Ref AppName - Key: Stage Value: !Ref AppStage UserData: Fn::Base64: !Sub | #!/bin/bash exec > >(tee /var/log/user-data.log|logger -t user-data -s 2>/dev/console) 2>&1 echo "Starting GS instance boot sequence..." echo ">>--> `date` | Run | yum update -y" yum update -y echo ">>--> `date` | Run | yum install aws-cli jq amazon-ssm-agent amazon-cloudwatch-agent -y" yum install aws-cli jq amazon-ssm-agent amazon-cloudwatch-agent -y echo ">>--> `date` | Run | Create CloudWatch agent configuration file" cat <<EOF > /opt/aws/amazon-cloudwatch-agent/bin/config.json { "agent": { "metrics_collection_interval": 60, "run_as_user": "root" }, "logs": { "logs_collected": { "files": { "collect_list": [ { "file_path": "/var/log/user-data.log", "log_group_name": "${AppName}-${AppStage}-ec2-logs", "log_stream_name": "{instance_id}-user-data-logs" }, { "file_path": "/var/log/docker", "log_group_name": "${AppName}-${AppStage}-ec2-logs", "log_stream_name": "{instance_id}-docker-logs" } ] } } }, "metrics": { "metrics_collected": { "disk": { "measurement": [ "used_percent" ], "metrics_collection_interval": 60, "resources": [ "/" ] }, "mem": { "measurement": [ "mem_used_percent" ], "metrics_collection_interval": 60 } } } } EOF /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl -a fetch-config -m ec2 -s -c file:/opt/aws/amazon-cloudwatch-agent/bin/config.json echo ">>--> `date` | Run | amazon-linux-extras install docker -y" amazon-linux-extras install docker -y echo ">>--> `date` | Run | service amazon-ssm-agent start" # systemctl start amazon-ssm-agent echo ">>--> `date` | Run | service docker start" systemctl start docker systemctl enable docker echo ">>--> `date` | Run | aws ecr get-login-password --region ${AWS::Region} | docker login --username AWS --password-stdin ${AwsAccountId}.dkr.ecr.${AWS::Region}.amazonaws.com" aws ecr get-login-password --region ${AWS::Region} | docker login --username AWS --password-stdin ${AwsAccountId}.dkr.ecr.${AWS::Region}.amazonaws.com echo ">>--> `date` | Run | docker pull ${EcrDockerImageUri}:${EcrDockerImageTag}" docker pull ${EcrDockerImageUri}:${EcrDockerImageTag} > /dev/null 2>&1 echo ">>--> `date` | Run | docker run -d -p 80:80 --name gs_app_be -e CLOUD_PROVIDER=aws -e APP_NAME=${AppName} -e APP_STAGE=${AppStage} -e AWS_REGION=${AWS::Region} ${EcrDockerImageUri}:${EcrDockerImageTag}" docker run -d -p 80:80 --name gs_app_be -e CLOUD_PROVIDER=aws -e APP_NAME=${AppName} -e APP_STAGE=${AppStage} -e AWS_REGION=${AWS::Region} ${EcrDockerImageUri}:${EcrDockerImageTag} echo ">>--> `date` | Run | docker ps" if [ "$(docker ps -q -f name=gs_app_be)" ]; then echo "Container is running successfully." else echo "Container failed to start. Check docker logs." docker logs gs_app_be fi echo ">>--> `date` | GS instance boot sequence finished" Outputs: InstancePublicIP: Description: Public IP of our EC2 instance Value: !GetAtt - EC2Instance - PublicIp