Pulumi / Terraform / Cloudformation : enable SSH access to Elastic Beanstalk instances - amazon-web-services

Using the eb CLI, one can enable SSH through eb ssh. This recreates all instances, and I'm assuming it updates the security group ingress rules & adds the correct keys to the instances.
How can one programmatically achieve this (terraform, pulumi, CF ... - I am using Pulumi but any will do) ?

In CloudFormation, for example, in your AWS::ElasticBeanstalk::ConfigurationTemplate you can use OptionSettings to provide EC2KeyName.
For instance;
Resources:
MyConfingTemplate:
Type: AWS::ElasticBeanstalk::ConfigurationTemplate
Properties:
ApplicationName: YourApplicationName
OptionSettings:
- Namespace: aws:autoscaling:launchconfiguration
OptionName: EC2KeyName
Value: <key-pair-name>
SolutionStackName: 64bit Amazon Linux 2 v3.1.0 running Python 3.7
You don't have to modify security groups. They will automatically allow ssh.

Related

Why creating EKS cluster auto-creates security groups I already have in place

I am trying to create an EKS cluster via CloudFormation. I have read all the EKS Security Group guidelines by Amazon and already put in place my security groups as I want clearer more tidy naming and also to be able to define the intricacies between these and some others (BastionHost SG and RDS SG) beforehand.
For the love of God I cannot understand why it keeps creating the Cluster Security Group by itself ignoring the one that I am passing as reference in my template and also the same thing kind of happens in the NodeGroup's remote access security group where I specify my Bastion Host's security group. Instead of accepting it it goes on to create a new security group of its own which has as source the security group of my BastionHost.
Literally confused. Can I overcome this?
Update:
So I am having the 3 security groups that Amazon suggests for my EKS. Let's call them cluster-sg, control-plane-sg, and nodegroup-sg. Also assume that they have been configured as per the guide above adopting the "recommended" inbound/outbound traffic guidelines and not the minimum (although I don't see this playing an important role at this part). Additionally there is the security group of a separate EC2 instance which is my Bastion Host, let's call it bastion-sg.
My CloudFormation template looks like this:
EKSCluster:
Type: 'AWS::EKS::Cluster'
Properties:
Name: 'my-cluster'
Version: '1.17'
ResourcesVpcConfig:
SecurityGroupIds:
- !Ref clusterSG #do I need this cluster-sg here? do I need also nodegroup-sg? do I need both?
SubnetIds:
- !Ref PrivateSubnet1
- !Ref PrivateSubnet2
- !Ref PrivateSubnet3
RoleArn: !GetAtt ClusterInstanceRole.Arn
NodeGroupCluster:
Type: AWS::EKS::Nodegroup
Properties:
ClusterName: !Ref EKSCluster
DiskSize: !Ref ClusterDiskSize
InstanceTypes: !Ref NodeInstanceTypes
ForceUpdateEnabled: false
NodegroupName: 'cluster-nodegroup'
NodeRole: !GetAtt NodeInstanceRole.Arn #this is a resource that I haven't provided
RemoteAccess:
Ec2SshKey: !Ref EC2KeyPair
SourceSecurityGroups:
- !Ref bastionSG
ScalingConfig:
DesiredSize: !Ref DesiredNodeSize
MaxSize: !Ref MaximumNodeSize
MinSize: !Ref MinimumNodeSize
Subnets:
- !Ref PrivateSubnet1
- !Ref PrivateSubnet2
- !Ref PrivateSubnet3
All in all the issue is two-fold:
a) I seem to be missing where to put what in terms of configuration and security groups. i.e. I have 3 security groups recommended by Amazon for the whole cluster but only two places where security groups are accepted.
b) Any combination that I have tried (as per my original post) does not take into consideration the cluster-sg but auto-creates one on its own which is not convenient for my IaaC and auto-deploy philosophy.
I was going through the same issue. The EKS Control Plane is on a separate VPC somewhere within AWS. When we create the EKS Cluster,it automatically will create an ENI with which it will attach a security group which will be used in communication between control plane and worker nodes. This SG for the cluster will always get created no matter what. Now, if you are passing other security groups as the argument for SG in your cloudformation script it will simply attach those security groups as well with the ENI which was created. If you launch a Nodegroup NG-1 and attach it with a different security group, then make sure to provide the SG in the cluster cloudformation script so that it can attach that security group with the ENI and open respective ports so worker nodes can communicate with the cluster.
I created launchtemplate with a dedicated SG and used the same launchtemplate to create an NodeGroup. Also I mentioned the SG of my Launchtemplate in the cluster script in CF so as to make sure that my nodes can communicate with the control plane else the nodegroups will fail to launch.
So in short just remember following points:
-There will always be a security group created by cluster
-ClusterSG or any other SG which you are passing in your cf cluster script will be attached to the ENI created by EKS on launch.
Please refer to the following documentation to get a better understanding.
https://docs.aws.amazon.com/eks/latest/userguide/sec-group-reqs.html

AWS Code Pipeline fails after adding RDS to Elastic Beanstalk

I have an EBS/Tomcat/Java environment created using the CodeStar template in Jan 2020. Recently I added a RDS within the EBS console following these instructions for creating a dev DB within EBS.
Since adding the RDS, my CodePipeline fails in the CloudFormation step, with the error
Failed Environment update activity. Reason: Configuration validation exception: Missing value for required parameter: AWSEBDBPassword
on my EBS dashboard under recent events.
It seems to be missing a database password or permissions, but I'm not sure how to set that.
If it helps, here's my CodeStar pipeline template file:
AWSTemplateFormatVersion: 2010-09-09
Transform:
- AWS::CodeStar
Conditions:
UseSubnet:
Fn::Not:
- Fn::Equals:
- Ref: SubnetId
- subnet-none
Parameters:
ProjectId:
Type: String
Description: AWS CodeStar project ID used to name project resources and create
roles.
InstanceType:
Type: String
Description: The type of Amazon EC2 Linux instances that will be launched for
this project.
KeyPairName:
Type: String
Description: The name of an existing Amazon EC2 key pair in the region where the
project is created, which you can use to SSH into the new Amazon EC2 Linux instances.
VpcId:
Type: String
Description: The ID of the Amazon Virtual Private Cloud (VPC) used for the new
Amazon EC2 Linux instances.
SubnetId:
Type: String
Description: The name of the VPC subnet used for the new Amazon EC2 Linux instances
launched for this project.
SolutionStackName:
Type: String
Description: The software stack used to launch environments and configure instances
in AWS Elastic Beanstalk.
EBTrustRole:
Type: String
Description: The service role in IAM for AWS Elastic Beanstalk to be created for
this project.
EBInstanceProfile:
Type: String
Description: The IAM role that will be created for the Amazon EC2 Linux instances.
Stage:
Type: String
Description: The name for a project pipeline stage, such as Staging or Prod, for
which resources are provisioned and deployed.
Default: ''
Resources:
EBApplication:
Description: The AWS Elastic Beanstalk application, which is a container used
to deploy the correct application configuration.
Type: AWS::ElasticBeanstalk::Application
Properties:
ApplicationName:
Fn::Sub: ${ProjectId}app${Stage}
Description: The name of the AWS Elastic Beanstalk application to be created
for this project.
EBApplicationVersion:
Description: The version of the AWS Elastic Beanstalk application to be created
for this project.
Type: AWS::ElasticBeanstalk::ApplicationVersion
Properties:
ApplicationName:
Ref: EBApplication
Description: The application version number.
SourceBundle:
S3Bucket: aws-codestar-us-west-2-215674088663-aa5050solnprj3-pipe
S3Key: 810d567534b4cb9ca0ee597128a22b94
EBConfigurationTemplate:
Description: The AWS Elastic Beanstalk configuration template to be created for
this project, which defines configuration settings used to deploy different
versions of an application.
Type: AWS::ElasticBeanstalk::ConfigurationTemplate
Properties:
ApplicationName:
Ref: EBApplication
Description: The name of the sample configuration template.
OptionSettings:
- Namespace: aws:elasticbeanstalk:environment
OptionName: EnvironmentType
Value: SingleInstance
- Namespace: aws:elasticbeanstalk:environment
OptionName: ServiceRole
Value:
Ref: EBTrustRole
- Namespace: aws:elasticbeanstalk:healthreporting:system
OptionName: SystemType
Value: enhanced
SolutionStackName:
Ref: SolutionStackName
EBEnvironment:
Description: The AWS Elastic Beanstalk deployment group where the application
is deployed, which is made up of the Amazon EC2 Linux instances launched for
this project.
Type: AWS::ElasticBeanstalk::Environment
Properties:
ApplicationName:
Ref: EBApplication
EnvironmentName:
Ref: EBApplication
Description: The application to be deployed to the environment.
TemplateName:
Ref: EBConfigurationTemplate
VersionLabel:
Ref: EBApplicationVersion
OptionSettings:
- Namespace: aws:autoscaling:launchconfiguration
OptionName: IamInstanceProfile
Value:
Ref: EBInstanceProfile
- Namespace: aws:autoscaling:launchconfiguration
OptionName: InstanceType
Value:
Ref: InstanceType
- Namespace: aws:autoscaling:launchconfiguration
OptionName: EC2KeyName
Value:
Ref: KeyPairName
- Namespace: aws:ec2:vpc
OptionName: VPCId
Value:
Ref: VpcId
- Fn::If:
- UseSubnet
- Namespace: aws:ec2:vpc
OptionName: Subnets
Value:
Ref: SubnetId
- Ref: AWS::NoValue```

Must You Have a Correct EC2 AMI ID?

I tried launching a Linux Instance with cloud formation Using just a random generated AMI id in my head and it did not work. Must I have the exact id provided by AWS like ami-0b69ea66ff7391e80?
Resources:
Ec2Instance:
Type: AWS::EC2::Instance
Properties:
InstanceType: t2.micro
ImageId: ami- <******> # Amazon Linux AMI in N.Virginia
Tags:
- Key: Name
Value: EC2 Linux
ami-0b69ea66ff7391e80
The Amazon Machine Image (AMI) is a operating system (OS) image to boot the server (EC2 Instance).
The AMI contains the OS (eg Linux or Windows), plus software, applications and any desired data. You can use a pre-provided AMI from AWS (base OS with default software) or the AWS Marketplace with custom software bundled. Even you can create one of your own with software and data pre-installed.
When starting an Amazon EC2 instance, an AMI must be specified. This AMI will then be copied to the boot disk for the instance to start. Thus, if you do not specify an AMI, the instance cannot boot so it will be disallowed.
Resources:
Ec2Instance:
Type: AWS::EC2::Instance
Properties:
InstanceType: t2.micro
ImageId: ami-0b69ea66ff7391e80 # Amazon Linux AMI in N.Virginia
Tags:
- Key: Name
Value: EC2 Linux
Go to your console
Attempt to launch an Instance
Copy the AMI id e.g ami-0b69ea66ff7391e80
and then launch using cloud formation template generated

Elastic Beanstalk Autoscaling Group Lifecycle Hooks

I would like to add lifecycle hooks to my Elastic Beanstalk's autoscaling group. I see how lifecycle hooks can be added to an autoscaling group through cloudformation, but I don't know how this can be done through Elastic Beanstalk.
To create a lifecycle hook on an autoscaling group, you need the autoscaling group's name. This doesn't appear to be possible since the Elastic Beanstalk resource doesn't have an export for the ASG name.
Type: AWS::AutoScaling::LifecycleHook
Properties:
AutoScalingGroupName: String
DefaultResult: String
HeartbeatTimeout: Integer
LifecycleHookName: String
LifecycleTransition: String
NotificationMetadata: String
NotificationTargetARN: String
RoleARN: String
The Elastic Beanstalk doesn't allow defining this configuration either. It does allow defining an sns topic, but adding one doesn't appear to change the configuration in the console, and scaling operations don't appear to be using this topic.
- Namespace: aws:elasticbeanstalk:sns:topics
OptionName: NotificationTopicARN
Value: !ImportValue MyLifecycleHookTopic
How can I add Lifecycle hooks to my Elastic Beanstalk application, so that terminating an environment can go through my graceful shutdown process?
You might be able to use .ebextensions files to further modify settings like these.
Resources:
lifecyclehook:
Type: AWS::AutoScaling::LifecycleHook
Properties:
AutoScalingGroupName: { "Ref" : "AWSEBAutoScalingGroup" }
LifecycleHookName: "autoscaling:EC2_INSTANCE_TERMINATING"
https://github.com/awsdocs/aws-elastic-beanstalk-developer-guide/blob/master/doc_source/environment-resources.md

How do you make your AWS ELB internal in a AWS Cloudformation template?

I am templating an EB app and several environments. I want to ensure that the ELB is set to be internal, but cant find the reference in the Cloudformation documentation.
You can configure an internal Elastic Load Balancer within an Elastic Beanstalk application by setting the ELBScheme property in the EB's aws:ec2:vpc namespace:
Specify internal if you want to create an internal load balancer in your VPC so that your Elastic Beanstalk application cannot be accessed from outside your VPC.
To configure this within a CloudFormation template, add the option to the OptionSettings property of your AWS::ElasticBeanstalk::Environment resource:
Type: AWS::ElasticBeanstalk::Environment
Properties:
ApplicationName: !Ref AppName
SolutionStackName: !Ref SolutionStackName
OptionSettings:
-
Namespace: "aws:ec2:vpc"
OptionName: ELBScheme
Value: internal
It's the "Scheme" parameter: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-elb.html#cfn-ec2-elb-scheme
Accepts either 'internal' or 'internet-facing' as a string.