SOA_EN

Attaching multiple ACM certificates to ALB to support multiple domains

スポンサーリンク
Attaching multiple ACM certificates to ALB to support multiple domains SOA_EN
スポンサーリンク
スポンサーリンク

SSL-enabled multi-domain configuration

This topic is related to security and compliance, one of the AWS SOA questions, and confirms that multiple ACM certificates can be attached to the ELB.

The goal is to create a configuration for two domains (websites) with one ALB and two EC2 instances, and to obtain an SSL certificate from ACM and attach it to the ALB so that both domains can be accessed using HTTPS.

Environment

Diagram of attaching multiple ACM certificates to ALB to support multiple domains.

Using the virtual host function of Apache, we will configure one EC2 instance for two domains. Then, to increase availability, we will prepare another instance with the same settings and configure it for load balancing using ALB.

There are several types of virtual host functions, but in this case, we will use the port-based virtual host function. The following is the correspondence between the domain name and the port number in the configuration we will build. We will use the domain name obtained from Route 53.

  • awstut.net: 81
  • awstut.link: number 82
Diagram of port numbers and domains.

This time, we will use SSL for the communication between the client and the ALB. For this purpose, we will obtain an SSL certificate for two domains from ACM. Attach the obtained ACM certificate to the ALB.

CloudFormation template files

We will build the above configuration using CloudFormation. The CloudFormation template file is available at the following URL.

awstut-soa/04/002 at main · awstut-an-r/awstut-soa
Contribute to awstut-an-r/awstut-soa development by creating an account on GitHub.

Explanation of points in the template files

Attaching EC2 instances in private subnet to ALB

In this configuration, the EC2 instances to be attached to the ALB are located in a private subnet. The key point is that in order to attach these instances to the ALB, you need to prepare a public subnet and associate it with the ALB. For more details, please refer to the following page

Multi-domain support for ALB

We have defined ALB related resources in soa-04-002-alb.yaml. We will cover the key settings to support multi-domain support for ALB.

Create ALB target group for multi-domain

In order to use the port-based virtual host feature, we will create an ALB target group for each port number.

Resources: # domain1 ALBTargetGroup1: Type: AWS::ElasticLoadBalancingV2::TargetGroup Properties: VpcId: !Ref VPC Name: !Sub "${Prefix}-ALBTargetGroup1" Protocol: HTTP Port: !Ref Port1 HealthCheckProtocol: HTTP HealthCheckPath: / HealthCheckPort: traffic-port HealthyThresholdCount: !Ref HealthyThresholdCount UnhealthyThresholdCount: !Ref UnhealthyThresholdCount HealthCheckTimeoutSeconds: !Ref HealthCheckTimeoutSeconds HealthCheckIntervalSeconds: !Ref HealthCheckIntervalSeconds Matcher: HttpCode: !Ref HttpCode Targets: - Id: !Ref Instance1 - Id: !Ref Instance2 # domain2 ALBTargetGroup2: Type: AWS::ElasticLoadBalancingV2::TargetGroup Properties: VpcId: !Ref VPC Name: !Sub "${Prefix}-ALBTargetGroup2" Protocol: HTTP Port: !Ref Port2 HealthCheckProtocol: HTTP HealthCheckPath: / HealthCheckPort: traffic-port HealthyThresholdCount: !Ref HealthyThresholdCount UnhealthyThresholdCount: !Ref UnhealthyThresholdCount HealthCheckTimeoutSeconds: !Ref HealthCheckTimeoutSeconds HealthCheckIntervalSeconds: !Ref HealthCheckIntervalSeconds Targets: - Id: !Ref Instance1 - Id: !Ref Instance2
Code language: YAML (yaml)

Other than the value of the Port property, the two target groups have the same settings. Set the Port property to 81 for one and 82 for the other; in the Targets property, specify the two instances in both groups. By setting it this way, the ALB will deliver traffic to the two instances regardless of which port the communication is destined for, i.e. which domain the communication is for.

Attaching multiple ACM certificates to ALB

By attaching an ACM certificate to an ALB, the communication between the client and the ALB can be SSL-enabled. for the basics of how to attach an ACM certificate to an ALB, please refer to the following page.

The difference between this configuration and the above page is that we will be attaching multiple certificates.

Resources: ALBListener: Type: AWS::ElasticLoadBalancingV2::Listener Properties: Certificates: - CertificateArn: !Ref Certificate1 DefaultActions: - TargetGroupArn: !Ref ALBTargetGroup1 Type: forward LoadBalancerArn: !Ref ALB Port: !Ref HTTPSPort Protocol: HTTPS ALBListenerCertificates: Type: AWS::ElasticLoadBalancingV2::ListenerCertificate Properties: Certificates: - CertificateArn: !Ref Certificate2 ListenerArn: !Ref ALBListener
Code language: YAML (yaml)

If you want to attach multiple ACM certificates to the ALB, you can create a ListenerCertificate. The point is that the main certificate must be set in the Listener and the other certificates must be set in the ListenerCertificate. Note that you cannot, for example, attach multiple certificates to a Listener, or attach a certificate only to a ListenerCertificate.

Creating Listener Rule Based on Domain Name

Define the rules for how to distribute traffic to the two target groups described above. The key point is to create a rule based on the Host value in the HTTP header, that is, the host name of the request destination.

Resources: # domain1 ALBListenerRule1: Type: AWS::ElasticLoadBalancingV2::ListenerRule Properties: Actions: - Type: forward TargetGroupArn: !Ref ALBTargetGroup1 Conditions: - Field: host-header HostHeaderConfig: Values: - !Ref DomainName1 ListenerArn: !Ref ALBListener Priority: 1 # domain2 ALBListenerRule2: Type: AWS::ElasticLoadBalancingV2::ListenerRule Properties: Actions: - Type: forward TargetGroupArn: !Ref ALBTargetGroup2 Conditions: - Field: host-header HostHeaderConfig: Values: - !Ref DomainName2 ListenerArn: !Ref ALBListener Priority: 2
Code language: YAML (yaml)

Specify the target group in the Actions property.
Set the conditions of the rule in the Conditions property, and set the Field property to “host-header” to check the Host value in the HTTP header. Set the hostname corresponding to the target group in the HostHeaderConfig property.

Register ALB to Route 53 and access it with your own domain

Associate the domain obtained from Route 53 with the ALB. The key point is to register the DNS name of ALB as an alias record. Please refer to the following page for details.

Using Ansible in Private Subnet

We will use Ansible to configure the virtual host function for two EC2 instances. To run Ansible, I recommend using the SSM document AWS-ApplyAnsiblePlaybooks, but be careful when using this SSM document on an instance in a private subnet, as in this configuration. That is, it will fail to install Ansible as a dependency. As a workaround, you can use the SSM document AWS-RunShellScript to install Ansible separately. Please refer to the following page for details

(Reference) Playbook

The following is the Playbook we will be using.

- hosts: all gather_facts: no become: yes tasks: - name: update yum yum: name=* - name: install the latest version of Apache yum: name=httpd state=latest - name: copy httpd.conf copy: src: ./httpd.conf dest: /etc/httpd/conf owner: root group: root mode: '0644' - name: start and enable Apache service: name=httpd state=started enabled=yes - name: make index.html for domain1 shell: mkdir -p /var/www/html/domain1; echo 'domain1' > /var/www/html/domain1/index.html; ec2-metadata -i >> /var/www/html/domain1/index.html - name: make index.html for domain2 shell: mkdir -p /var/www/html/domain2; echo 'domain2' > /var/www/html/domain2/index.html; ec2-metadata -i >> /var/www/html/domain2/index.html
Code language: YAML (yaml)

What you need to do is to install Apache and then replace httpd.conf. This is the one that is configured for virtual hosting. After that, start Apache and prepare index.html in the document root for the two domains.

(Reference) httpd.conf

The following is a part of httpd.conf with settings for virtual hosts.

#Listen 80 Listen 81 Listen 82 ... NameVirtualHost *:81 NameVirtualHost *:82 ... <VirtualHost *:81> ServerName [domain1] DocumentRoot /var/www/html/domain1 </VirtualHost> <VirtualHost *:82> ServerName [domain2] DocumentRoot /var/www/html/domain2 </VirtualHost> ...
Code language: plaintext (plaintext)

Please check the official Apache website for details.

Allowing communication for two domains with security group

This is a little off topic, but the security group you apply to your EC2 instance is also a key point. Note that the communication will take place on the port number corresponding to the domain.

Resources: InstanceSecurityGroup: Type: AWS::EC2::SecurityGroup Properties: GroupName: !Sub "${Prefix}-InstanceSecurityGroup" GroupDescription: Allow HTTP(81/tcp, 82/tcp) from ALBSecurityGroup. VpcId: !Ref VPC SecurityGroupIngress: - IpProtocol: tcp FromPort: !Ref Port1 ToPort: !Ref Port2 SourceSecurityGroupId: !Ref ALBSecurityGroup
Code language: YAML (yaml)

In the FromPort and ToPort properties, specify the range of port numbers for inbound communication to be allowed. This time, we will set 81 and 82 for each to allow communication for two domains.

Architecting

We will use CloudFormation to build this environment and check the actual behavior.

Preparing Ansible Playbook

Before creating the CloudFormation stack, we will prepare Ansible. Specifically, we will zip up the Playbook and place it in an S3 bucket. Please refer to the following page for specific commands.

Create CloudFormation stacks and check resources in stacks

Create CloudFormation stacks.
Please refer to the following page for information on how to create a stack and check each stack.

After checking the resources in each stack, the information for the main resources created this time is as follows

  • Instance 1: i-02c368c2cf2f4d84f
  • Instance 2: i-0086d086596a27762
  • Domain name 1: awstut.net
  • Domain name 2: awstut.link
  • ACM certificate for awstut.net: 44206de3-9a28-4a69-af54-a0a88f45d317
  • ACM certificate for awstut.link: 0079c615-b747-4780-ac00-a63c5fcdb5bb
  • ALB: soa-04-002-ALB

We will also check the resource creation status from the AWS Management Console. First, check the ACM certificate.

ACM certificates for the two domains have been created.

You can see that the certificates have been created for the two domains.

Next, we will check the Route 53 configuration.

The ALB is associated with domain 1.
The ALB is associated with domain 2.

Commonly, two domains are associated with ALB. The type is “A”, which indicates that it is an alias record.

Check the certificate attached to the ALB.

Two ACM certificates are attached to the ALB.

The certificate for “awstut.net” is set as the default, and the one for “awstut.link” is treated as a sub. This is due to the fact that the certificate attached to the Listener in the CloudFormation template is treated as the default.
Check the two target groups of the ALB.

Two EC2 instances are registered in the ALB target group 1.
Two EC2 instances are registered in the ALB target group 2.

The same two EC2 instances are registered in the two groups. On the other hand, we can also see that the port numbers correspond to the groups. This means that traffic will flow to the two instances regardless of which port number it is directed to.

Multi-domain operation verification (1)

Now that we are ready, let’s access the two domains.
First, we will access “awstut.net”.

Access result 2 for domain 1.
Access result 1 for domain 1.

We were able to access it normally. Each time you access the site, the contents displayed will change. This is because the ALB is distributing traffic to the two EC2 instances in a round-robin fashion.

Multidomain Operation Verification (2)

Now we will access “awstut.link”.

Access result 1 for domain 2.
Access result 2 for domain 2.

We were able to access this site normally as well. We can see that we are accessing the same instance as before.

Summary

By attaching multiple ACM certificates to the ALB, we were able to support multi-domain configuration.

タイトルとURLをコピーしました