Option D (network load balancer with target group health checks over HTTPS) is not correct because it requires code change on instances. Actually, the correct solution is to terminate TLS at the ALB and re-encrypt using a self-signed certificate on the EC2 instances, but that requires application support. However, the best option is to use a Network Load Balancer with TLS termination and forward to instances with a self-signed certificate (which doesn't require code change if the app listens on HTTPS).
However, among the options, Option D is most plausible but still flawed. Let me reconsider: The correct answer should be to use a Network Load Balancer with TLS passthrough to instances that have certificates installed. Since the application cannot be changed, use a self-signed certificate on the instances for the internal traffic.
Option B (self-signed certificate on EC2 and ALB re-encrypt) often requires code changes to trust the self-signed cert. Option D is the closest: NLB with TLS listener and target group with HTTPS health check. But the correct answer is actually to use an NLB with TLS listener and target group health checks over HTTPS, but the application must support HTTPS.
Since the problem says no code change, the application likely already listens on HTTPS? Actually, the problem says traffic between ALB and EC2 is HTTP, so the application listens on HTTP. So we need to enable HTTPS on the instances without code change. That's not possible.
The only way is to use a reverse proxy on the instance or use a self-signed certificate that the ALB can trust. But ALB can terminate TLS and re-encrypt to target group with a self-signed certificate if the target group protocol is HTTPS and the ALB trusts the self-signed certificate (by uploading it to ACM as a private certificate?). ACM does not accept self-signed certificates.
So the correct solution is to use a Network Load Balancer with TLS passthrough and install a certificate on the instances. The application must support HTTPS. Since the application currently uses HTTP, the only way is to modify the application to listen on HTTPS.
However, the problem says 'without changing the application code'. So the only feasible solution is to use a reverse proxy like NGINX on the instance in front of the application. That is not listed.
Among the options, Option B is the least bad because you can upload a private CA-signed certificate to ACM and use it on ALB to re-encrypt to instances. But the instances need to have the corresponding certificate. That might require manual installation but not code change.
Option A (NLB with TLS listener and target group protocol TCP) does not encrypt traffic to instances. Option C (CloudFront in front of ALB) adds complexity. Option D is similar to B but uses NLB.
So the best answer is B. Actually, the correct answer is D: use a Network Load Balancer with TLS listener and target group health checks over HTTPS. Wait, NLB does not terminate TLS; it passes through.
So the instances must handle TLS. That requires code change. So B is better because ALB can re-encrypt.
But ALB re-encryption requires the target group protocol to be HTTPS and the ALB to trust the target's certificate. If the target uses a self-signed certificate, ALB will reject it. So you need a certificate signed by a CA that ALB trusts.
That can be a private CA from ACM Private CA. So you can install a certificate from ACM Private CA on the instances. That is a configuration change, not code change.
So B is feasible.