# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. # SPDX-License-Identifier: Apache-2.0 # AWSTemplateFormatVersion: '2010-09-09' Transform: AWS::Serverless-2016-10-31 Description: AWS Elastic Beanstalk sample application for Service Catalog. (fdp-1qj64b36c) Metadata: Source: https://github.com/aws-samples/aws-service-catalog-reference-architectures/blob/master/elasticbeanstalk/sc-elasticbeanstalk-ra.json AWS::CloudFormation::Interface: ParameterGroups: - Label: default: Elastic Beanstalk Options - Mandatory Parameters: - ApplicationName - SolutionStackName - Label: default: Elastic Beanstalk Options - Network Parameters: - VPCId - EC2SubnetIds - ELBSubnetIds - EC2SecurityGroupId - ELBSecurityGroupId - Label: default: Elastic Beanstalk Options - Update Parameters: - RollingUpdateType - MinInstancesInService - MaxBatchSize - PreferredStartTime - Label: default: Elastic Beanstalk Options - General Parameters: - InstanceTypes - LoadBalancerType - ElasticBeanstalkRole - ClusterMinInstances - ClusterMaxInstances - CloudWatchLogsRetentionInDays - Label: default: Elastic Beanstalk Options - SSL Parameters: - SSLCertificateArn - CLBInstancePort # - Label: # default: Code Source - Optional # Parameters: # - S3Bucket # - S3SourceBundle - Label: default: Static Values Parameters: - GlobalAllowlistBucketPrefix - GlobalAllowlistFolderName Parameters: # Network VPCId: Type: AWS::EC2::VPC::Id Description: The of the VPC that the elastic beanstalk application will be in. EC2SubnetIds: Type: List Description: The id of the one (or more) Subnets that the elastic beanstalk instances will be in. ELBSubnetIds: Type: List Description: The id of the one (or more) Subnets that the elastic beanstalk loadbalancer will be in. EC2SecurityGroupId: Type: String Description: Optional - Provide security groups for the EC2 Instances Default: "" ELBSecurityGroupId: Type: String Description: Optional - Provide security groups for the Loadbalancer Default: "" # Mandatory SolutionStackName: Description: Enter the name of the solution stack. A list of available Solution Stacks can be found here:https://docs.aws.amazon.com/elasticbeanstalk/latest/platforms/platforms-supported.html. Type: String Default: REPLACE_ME_DEFAULT_SOLUTIONSTACKNAME AllowedValues: REPLACE_ME_SOLUTIONSTACKNAME ApplicationName: Type: String Description: The name of the Elastic Beanstalk Application # General LoadBalancerType: Type: String Description: Loadbalancer type Default: application AllowedValues: - application - network - classic ClusterMinInstances: Description: Minimum number of cluster instances for autoscaling Type: Number Default: 1 AllowedValues: - 1 - 2 - 3 - 4 - 5 - 6 - 7 - 8 - 9 ClusterMaxInstances: Description: Maximum number of cluster instances for autoscaling Type: Number Default: 4 AllowedValues: - 1 - 2 - 3 - 4 - 5 - 6 - 7 - 8 - 9 InstanceTypes: Description: Optional - A comma-separated list of instance types you want your environment to use. For example t2.micro,t3.micro Type: String Default: "" ElasticBeanstalkRole: Description: Optional - IAM Role attached to the instance profiles of the Elastic Beanstalk instances. Default containing AWSElasticBeanstalkWebTier, AWSElasticBeanstalkMulticontainerDocker and AWSElasticBeanstalkWorkerTier AWS managed policies. Type: String Default: "" CloudWatchLogsRetentionInDays: Description: Optional - The number of days to keep CloudWatch Logs log events before they expire. Default is 7. Type: String Default: 400 # Update RollingUpdateType: Type: String Description: Configuration Update - Time-based rolling updates apply a PauseTime between batches. Health-based rolling updates wait for new instances to pass health checks before moving on to the next batch. Immutable updates launch a full set of instances in a new Auto Scaling group. Default: "Health" AllowedValues: - "Time" - "Health" - "Immutable" MaxBatchSize: Type: String Description: Optional - Configuration Update - The number of instances included in each batch of the rolling update. Default - One-third of the minimum size of the Auto Scaling group, rounded to the next highest integer. Default: "" MinInstancesInService: Type: String Description: Optional - Configuration Update - The minimum number of instances that must be in service within the Auto Scaling group while other instances are terminated. Default - The minimum size of the Auto Scaling group or one less than the maximum size of the Auto Scaling group, whichever is lower. Default: "" PreferredStartTime: Type: String Description: Managed Updates - Configure a maintenance window for managed actions in UTC Default: "Tue:09:00" # SSL SSLCertificateArn: Type: String Description: Optional - ARN of SSL Certificate uploaded to IAM - The provided certificate is used to terminate the SSL traffic on the LoadBalancer (ALB or CLB). If empty, LoadBalancer listens on Port 80 (HTTP). This value is ignored for Network Load Balancer type. Default: "" CLBInstancePort: Type: String Description: Optional - InstancePort used for Classical Load Balancer. If empty, the default value is used (443 for SSL Termination on Classic Load Blaancer). This field is ignored for other Load Balancer Types. Default: "80" # Code Source # # Don't allow application deployed at creation time to prevent circumvention of ebextensions-validator # S3Bucket: # Type: String # Description: Optional - Enter the name of the S3 bucket that the application source bundle is in. # Default: "" # S3SourceBundle: # Type: String # Description: Optional - Enter name of application bundle within the selected S3 Bucket. Example MyApp.Zip. # Default: "" # Static variables - TODO need to be set appropriatly to provide information about Allowlist bucket and folder for ebextensions-validator GlobalAllowlistBucketPrefix: Type: String Description: Static - bucket name prefix for ebextensions validator allowlist bucket Default: "cf-ebextensions-validator-allowlist" AllowedValues: - "cf-ebextensions-validator-allowlist" GlobalAllowlistFolderName: Type: String Description: Static - global allowlist folder name for ebextensions validator Default: "global" AllowedValues: - "global" Conditions: # # Don't allow application deployed at creation time to prevent circumvention of ebextensions-validator # SampleApplication: !Or # - !Equals [!Ref S3Bucket, ""] # - !Equals [!Ref S3SourceBundle, ""] # NotSampleApplication: !Not [Condition: SampleApplication] ConditionCustomInstanceTypes: !Not [!Equals [!Ref InstanceTypes, ""]] ConditionDefaultElasticBeanstalkRole: !Equals [!Ref ElasticBeanstalkRole, ""] ConditionDefaultMaxBatchSize: !Equals [!Ref MaxBatchSize, ""] ConditionDefaultMinInstancesInService: !Equals [!Ref MinInstancesInService, ""] ConditionDefaultEC2SG: !Equals [!Ref EC2SecurityGroupId, ""] ConditionDefaultELBSG: !Equals [!Ref ELBSecurityGroupId, ""] ConditionSSL: !Not [!Equals [!Ref SSLCertificateArn, ""]] ConditionSSLALB: !And - !Equals [!Ref LoadBalancerType, "application"] - !Condition ConditionSSL ConditionSSLCLB: !And - !Equals [!Ref LoadBalancerType, "classic"] - !Condition ConditionSSL ConditionSSLNLB: !And - !Equals [!Ref LoadBalancerType, "network"] - !Condition ConditionSSL ConditionSSLCLBListener: !And - !Not [!Equals [!Ref CLBInstancePort, ""]] - !Condition ConditionSSLCLB Resources: Application: Type: AWS::ElasticBeanstalk::Application Properties: ApplicationName: !Ref 'ApplicationName' Description: AWS Elastic Beanstalk Sample Service Catalog # ApplicationVersion: # # Don't allow application deployed at creation time to prevent circumvention of ebextensions-validator # Condition: NotSampleApplication # Type: AWS::ElasticBeanstalk::ApplicationVersion # Properties: # ApplicationName: !Ref 'Application' # Description: AWS Elastic Beanstalk Sample Service Catalog Version # SourceBundle: # S3Bucket: !Ref 'S3Bucket' # S3Key: !Ref 'S3SourceBundle' elasticbeanstalkec2role: Condition: ConditionDefaultElasticBeanstalkRole Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Principal: Service: - ec2.amazonaws.com Action: - sts:AssumeRole ManagedPolicyArns: - arn:aws:iam::aws:policy/AWSElasticBeanstalkWebTier - arn:aws:iam::aws:policy/AWSElasticBeanstalkMulticontainerDocker - arn:aws:iam::aws:policy/AWSElasticBeanstalkWorkerTier Path: / ElasticBeanstalkInstanceProfile: Type: AWS::IAM::InstanceProfile Properties: Path: / Roles: - !If - "ConditionDefaultElasticBeanstalkRole" - !Ref 'elasticbeanstalkec2role' - !Ref 'ElasticBeanstalkRole' # elasticbeanstalkmanagedupdatesrole: # Type: AWS::IAM::Role # Properties: # AssumeRolePolicyDocument: # Version: '2012-10-17' # Statement: # - Effect: Allow # Principal: # Service: # - managedupdates.elasticbeanstalk.amazonaws.com # Action: # - sts:AssumeRole # ManagedPolicyArns: # - arn:aws:iam::aws:policy/service-role/AWSElasticBeanstalkService # Path: / sampleConfigurationTemplate: Type: AWS::ElasticBeanstalk::ConfigurationTemplate Properties: ApplicationName: !Ref 'Application' Description: AWS ElasticBeanstalk Sample Configuration Template Service Catalog SolutionStackName: !Ref 'SolutionStackName' OptionSettings: # SSL - Terminate at LoadBlancer # ALB - !If - "ConditionSSLALB" - Namespace: aws:elbv2:listener:443 OptionName: SSLCertificateArns Value: !Ref SSLCertificateArn - !Ref "AWS::NoValue" - !If - "ConditionSSLALB" - Namespace: aws:elbv2:listener:443 OptionName: ListenerEnabled Value: 'true' - !Ref "AWS::NoValue" - !If - "ConditionSSLALB" - Namespace: aws:elbv2:listener:443 OptionName: Protocol Value: HTTPS - !Ref "AWS::NoValue" # CLB - !If - "ConditionSSLCLB" - Namespace: aws:elb:listener:443 OptionName: SSLCertificateId Value: !Ref SSLCertificateArn - !Ref "AWS::NoValue" - !If - "ConditionSSLCLB" - Namespace: aws:elb:listener:443 OptionName: ListenerProtocol Value: HTTPS - !Ref "AWS::NoValue" - !If - "ConditionSSLCLBListener" - Namespace: aws:elb:listener:443 OptionName: InstancePort Value: !Ref CLBInstancePort - !Ref "AWS::NoValue" - Namespace: aws:ec2:vpc OptionName: ELBScheme # Value: internal Value: public - Namespace: aws:ec2:vpc OptionName: VPCId Value: !Ref VPCId - Namespace: aws:ec2:vpc OptionName: Subnets Value: !Join - ',' - !Ref EC2SubnetIds - Namespace: aws:ec2:vpc OptionName: ELBSubnets Value: !Join - ',' - !Ref ELBSubnetIds # SG - !If - "ConditionDefaultEC2SG" - !Ref "AWS::NoValue" - Namespace: aws:autoscaling:launchconfiguration OptionName: SecurityGroups Value: !Ref EC2SecurityGroupId - !If - "ConditionDefaultELBSG" - !Ref "AWS::NoValue" - Namespace: aws:elb:loadbalancer OptionName: SecurityGroups Value: !Ref ELBSecurityGroupId - !If - "ConditionCustomInstanceTypes" - Namespace: aws:ec2:instances OptionName: InstanceTypes Value: !Ref 'InstanceTypes' - !Ref "AWS::NoValue" - Namespace: aws:elasticbeanstalk:environment OptionName: EnvironmentType Value: LoadBalanced - Namespace: aws:elasticbeanstalk:environment OptionName: LoadBalancerType Value: !Ref LoadBalancerType # Managedactions - Namespace: aws:elasticbeanstalk:managedactions OptionName: ManagedActionsEnabled Value: true - Namespace: aws:elasticbeanstalk:managedactions OptionName: PreferredStartTime Value: !Ref PreferredStartTime - Namespace: aws:elasticbeanstalk:managedactions OptionName: ServiceRoleForManagedUpdates Value: "AWSServiceRoleForElasticBeanstalkManagedUpdates" - Namespace: aws:elasticbeanstalk:managedactions:platformupdate OptionName: UpdateLevel Value: "minor" - Namespace: aws:elasticbeanstalk:managedactions:platformupdate OptionName: InstanceRefreshEnabled Value: "true" # Autoscaling - Namespace: aws:autoscaling:asg OptionName: MinSize Value: !Ref 'ClusterMinInstances' - Namespace: aws:autoscaling:asg OptionName: MaxSize Value: !Ref 'ClusterMaxInstances' - Namespace: aws:autoscaling:launchconfiguration OptionName: IamInstanceProfile Value: !Ref 'ElasticBeanstalkInstanceProfile' - Namespace: aws:autoscaling:launchconfiguration OptionName: DisableIMDSv1 Value: true - Namespace: aws:autoscaling:launchconfiguration OptionName: EC2KeyName Value: !Join - "-" - - "CF" - !Select [2, !Split ["-", !Ref "AWS::StackName"]] - !Select [3, !Split ["-", !Ref "AWS::StackName"]] - Namespace: aws:autoscaling:updatepolicy:rollingupdate OptionName: RollingUpdateEnabled Value: true - Namespace: aws:autoscaling:updatepolicy:rollingupdate OptionName: RollingUpdateType Value: !Ref RollingUpdateType - !If - "ConditionDefaultMaxBatchSize" - !Ref "AWS::NoValue" - Namespace: aws:autoscaling:updatepolicy:rollingupdate OptionName: MaxBatchSize Value: !Ref 'MaxBatchSize' - !If - "ConditionDefaultMinInstancesInService" - !Ref "AWS::NoValue" - Namespace: aws:autoscaling:updatepolicy:rollingupdate OptionName: MinInstancesInService Value: !Ref 'MinInstancesInService' # CloudWatchLogs - Namespace: aws:elasticbeanstalk:cloudwatch:logs OptionName: StreamLogs Value: "true" - Namespace: aws:elasticbeanstalk:cloudwatch:logs OptionName: RetentionInDays Value: !Ref CloudWatchLogsRetentionInDays # Health reporting system - Namespace: aws:elasticbeanstalk:cloudwatch:logs:health OptionName: HealthStreamingEnabled Value: "true" - Namespace: aws:elasticbeanstalk:healthreporting:system OptionName: SystemType Value: "enhanced" Environment: Type: AWS::ElasticBeanstalk::Environment Properties: ApplicationName: !Ref 'Application' Description: AWS ElasticBeanstalk Sample Environment # VersionLabel: # # Don't allow application deployed at creation time to prevent circumvention of ebextensions-validator # !If # - "NotSampleApplication" # - !Ref 'ApplicationVersion' # - !Ref "AWS::NoValue" TemplateName: !Ref 'sampleConfigurationTemplate' EnvironmentName: !Sub 'EB-ENV-${ApplicationName}' Tags: - Key: "owner" Value: "cf-sc-manager" stackApplicationDeployment: Type: AWS::CloudFormation::Stack Properties: TemplateURL: 'application_deployment/application_deployment.yaml' TimeoutInMinutes: 5 Parameters: ApplicationName: !Ref "ApplicationName" EnvironmentName: !Sub 'EB-ENV-${ApplicationName}' StackName: !Ref "AWS::StackName" GlobalAllowlistBucket: !Sub '${GlobalAllowlistBucketPrefix}-${AWS::AccountId}' GlobalAllowlistFolderName: !Ref "GlobalAllowlistFolderName" ec2KeyPair: # Create a KeyPair so that the configuration cannot be overwritten by ebextensions - PrivateKey is not saved anywhere and cannot be retrieved Type: 'Custom::EC2KeyPair' Properties: ServiceToken: !GetAtt ec2KeyPairLambda.Arn ec2KeyPairLambdaRole: Type: 'AWS::IAM::Role' Properties: AssumeRolePolicyDocument: Version: 2012-10-17 Statement: - Action: - sts:AssumeRole Effect: Allow Principal: Service: - lambda.amazonaws.com Path: / ManagedPolicyArns: - arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole Policies: - PolicyName: ec2KeyPair PolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Action: - "ec2:CreateKeyPair" - "ec2:DeleteKeyPair*" Resource: !Join - "-" - - !Sub 'arn:${AWS::Partition}:ec2:${AWS::Region}:${AWS::AccountId}:key-pair/CF' - !Select [2, !Split ["-", !Ref "AWS::StackName"]] - !Select [3, !Split ["-", !Ref "AWS::StackName"]] ec2KeyPairLambda: Type: 'AWS::Serverless::Function' Properties: Role: !GetAtt ec2KeyPairLambdaRole.Arn CodeUri: ec2KeyPairDummy Handler: app.lambda_handler Runtime: python3.8 Timeout: 300 Environment: Variables: KeyName: !Join - "-" - - "CF" - !Select [2, !Split ["-", !Ref "AWS::StackName"]] - !Select [3, !Split ["-", !Ref "AWS::StackName"]] Outputs: LoadBalancerURL: Value: !If - "ConditionSSL" - !Sub - https://${endpoint} - endpoint: !GetAtt 'Environment.EndpointURL' - !Sub - http://${endpoint} - endpoint: !GetAtt 'Environment.EndpointURL' ApplicationDeployStateMachineArn: Value: !GetAtt stackApplicationDeployment.Outputs.ApplicationDeploymentStateMachineArn ApplicationName: Value: !Ref 'Application' EnvironmentName: Value: !Sub 'EB-ENV-${Application}'