An Elastic IP address is a fixed public IPv4 address you allocate in AWS and associate with an EC2 instance. Unlike an automatically assigned public IP address, it can remain the endpoint for an application when you replace the instance. This helps when clients cannot resolve a DNS name, firewall rules require a fixed IP address, or changing DNS records would cause delays. section 3.6
To give an existing instance a fixed public address in the AWS Management Console:
- Open EC2 → Elastic IPs, choose Allocate Elastic IP Address, select Amazon’s Pool of IPv4 Addresses, and allocate the address. section 3.6
- Select the new address, choose Actions → Associate Elastic IP Address, select Instance as the resource type, choose your instance, and click Associate. Open the address in a browser to check that the application responds. section 3.6
An Elastic IP can also be associated with a network interface. Attach a second interface to an instance, allocate another Elastic IP, then associate it with that interface and its private IP address. The instance can then be reached through two public addresses. To serve a different website on each, configure the web server using the interfaces’ private IP addresses: the virtual machine does not see its public IP addresses. section 3.7
Keeping an endpoint during instance recovery
Suppose a Jenkins server is replaced after an instance or availability-zone failure. The replacement cannot retain the old private IP address if it starts in another subnet, and autoscaling does not associate an Elastic IP by default. One approach is to allocate an Elastic IP and associate it during the new instance’s bootstrap. Updating DNS or using an Elastic Load Balancer are alternative ways to provide a stable endpoint. section 13.2.4
Listing 13.5 Using an EIP as a static endpoint for a virtual machine
# [...] ElasticIP: Type: 'AWS::EC2::EIP' #1 Properties: Domain: vpc DependsOn: VPCGatewayAttachment IamRole: Type: 'AWS::IAM::Role' #2 Properties: AssumeRolePolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Principal: Service: 'ec2.amazonaws.com' #3 Action: 'sts:AssumeRole' Policies: - PolicyName: ec2 PolicyDocument: Version: '2012-10-17' Statement: - Action: 'ec2:AssociateAddress' #4 Resource: '*' Effect: Allow - PolicyName: ssm #5 PolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Action: - 'ssmmessages:*' - 'ssm:UpdateInstanceInformation' - 'ec2messages:*' Resource: '*' IamInstanceProfile: Type: 'AWS::IAM::InstanceProfile' #6 Properties: Roles: - !Ref IamRole LaunchTemplate: Type: 'AWS::EC2::LaunchTemplate' #7 Properties: LaunchTemplateData: IamInstanceProfile: Name: !Ref IamInstanceProfile #8 ImageId: !FindInMap [RegionMap, !Ref 'AWS::Region', AMI] Monitoring: Enabled: false InstanceType: 't2.micro' NetworkInterfaces: - AssociatePublicIpAddress: true DeviceIndex: 0 Groups: - !Ref SecurityGroup UserData: 'Fn::Base64': !Sub | #!/bin/bash -ex trap '/opt/aws/bin/cfn-signal -e 1 --stack ${AWS::StackName} --resource AutoScalingGroup --region ${AWS::Region}' ERR # Attaching EIP INSTANCE_ID="$(curl -s http://169.254.169.254/latest/meta-data/instance-id)" #9 aws --region ${AWS::Region} ec2 associate-address --instance-id $INSTANCE_ID --allocation-id ${ElasticIP.AllocationId} --allow-reassociation #10 sleep 30 # Installing Jenkins [...] # Mounting EFS volume [...] # Configuring Jenkins [...] # Starting Jenkins systemctl enable jenkins.service systemctl start jenkins.service /opt/aws/bin/cfn-signal -e $? --stack ${AWS::StackName} --resource AutoScalingGroup --region ${AWS::Region} #1 Creates a static public IP address #2 Creates an IAM role granting access to AWS services to the EC2 instance #3 The IAM role can be used only by EC2 instances. #4 The IAM policy allows access to the EC2 API action called AssociateAddress, which is used to associate an Elastic IP with an EC2 instance. #5 The other IAM policy enables access to the Session Manager, enabling you to open a terminal connection with the EC2 instance. #6 An IAM instance profile is needed to be able to attach an IAM role to an EC2 instance. #7 The launch template defines the blueprint for launching the EC2 instance. #8 Attaches the IAM instance profile defined when starting the virtual machine #9 Gets the ID of the running instance from the metadata service (see <a class="url" href="http://mng.bz/deAX">http://mng.bz/deAX</a> for details) #10 The EC2 instance associates the Elastic IP address with itself by using the AWS CLI.
The CloudFormation excerpt shows an AWS::EC2::EIP resource and the ec2:AssociateAddress permission granted to the instance role for bootstrap-time association. section 13.2.4
