
ジム通いを再開したりしなかったりしている前田です。
気になったことがあって検証したので、久しぶりにブログを書いてみました。興味のある方はぜひご覧になってみてください。
概要
MGNを用いてADメンバを移行する際、移行前後で同一のネットワークに存在しないよう注意が必要と言われています。
これは、AD内で同一のコンピュータアカウントが衝突し、不具合を引き起こすリスクがあるためです。
本ブログでは、あえてこの衝突を発生させて、どのような事象が起きるのかを検証したいと思います。
略語について
冗長になることを防ぐため、下記の用語は略語で表記します。
| 用語 | 説明 |
|---|---|
| MGN | Application Migration Serviceの略。 |
| AD | Active Directoryの略。 |
| ドメコン | ADのドメインコントローラの略。 |
| ADメンバ | ADドメコン配下に配置されるメンバーサーバーの略。 |
本記事で扱わない内容
- MGNの仕様・使い方
- ネットワーク構成の詳細
- ADの詳細
結論
- 移行直後は移行元、移行先双方でActiveDirectory認証が利用可能だった。
- ドメコンが管理するDNSレコードでは、移行元、移行先どちらかのみが登録された(今回の検証では移行先サーバーが登録された)
- セキュアチャネルのパスワードが更新されると、更新されなかったサーバー側ではセキュアチャネルが破損してActiveDirectory認証が利用できなくなった。
検証環境
- VPCを2つ用意します。
- ADドメコンとADメンバの役割のEC2をそれぞれ用意します。
- MGNを用いてADメンバの移行を実施し、同一ネットワーク上で同じコンピュータアカウントを持つADメンバが存在するようにし、何が起こるのか確認します。

セットアップ手順
1.VPC&EC2構築
①下記のCloudFormationテンプレートを実行し、VPCをはじめとしたネットワーク環境とEC2を作成します。
クリックで詳細表示(network.yaml)
AWSTemplateFormatVersion: '2010-09-09' Description: 'AWS MGN AD Conflict Experiment - Network Stack' Parameters: EnvironmentName: Type: String Default: 'mgn-ad-experiment' Description: 'Environment name prefix for resources' Resources: # ======================================== # 移行元VPC (Source VPC) # ======================================== SourceVPC: Type: AWS::EC2::VPC Properties: CidrBlock: 10.0.0.0/24 EnableDnsHostnames: true EnableDnsSupport: true Tags: - Key: Name Value: !Sub '${EnvironmentName}-source-vpc' - Key: Environment Value: !Ref EnvironmentName # 移行元VPC - パブリックサブネット 1a SourcePublicSubnet1a: Type: AWS::EC2::Subnet Properties: VpcId: !Ref SourceVPC CidrBlock: 10.0.0.192/28 AvailabilityZone: !Select [0, !GetAZs ''] MapPublicIpOnLaunch: true Tags: - Key: Name Value: !Sub '${EnvironmentName}-source-public-1a' - Key: Environment Value: !Ref EnvironmentName # 移行元VPC - プライベートサブネット 1a SourcePrivateSubnet1a: Type: AWS::EC2::Subnet Properties: VpcId: !Ref SourceVPC CidrBlock: 10.0.0.0/26 AvailabilityZone: !Select [0, !GetAZs ''] MapPublicIpOnLaunch: false Tags: - Key: Name Value: !Sub '${EnvironmentName}-source-private-1a' - Key: Environment Value: !Ref EnvironmentName # 移行元VPC - プライベートサブネット 1c SourcePrivateSubnet1c: Type: AWS::EC2::Subnet Properties: VpcId: !Ref SourceVPC CidrBlock: 10.0.0.64/26 AvailabilityZone: ap-northeast-1c MapPublicIpOnLaunch: false Tags: - Key: Name Value: !Sub '${EnvironmentName}-source-private-1c' - Key: Environment Value: !Ref EnvironmentName # 移行元VPC - VPCエンドポイント専用サブネット 1a SourceVPCESubnet1a: Type: AWS::EC2::Subnet Properties: VpcId: !Ref SourceVPC CidrBlock: 10.0.0.144/28 AvailabilityZone: !Select [0, !GetAZs ''] MapPublicIpOnLaunch: false Tags: - Key: Name Value: !Sub '${EnvironmentName}-source-vpce-1a' - Key: Environment Value: !Ref EnvironmentName # 移行元VPC - VPCエンドポイント専用サブネット 1c SourceVPCESubnet1c: Type: AWS::EC2::Subnet Properties: VpcId: !Ref SourceVPC CidrBlock: 10.0.0.176/28 AvailabilityZone: ap-northeast-1c MapPublicIpOnLaunch: false Tags: - Key: Name Value: !Sub '${EnvironmentName}-source-vpce-1c' - Key: Environment Value: !Ref EnvironmentName # ======================================== # 移行先VPC (Target VPC) # ======================================== TargetVPC: Type: AWS::EC2::VPC Properties: CidrBlock: 10.0.1.0/24 EnableDnsHostnames: true EnableDnsSupport: true Tags: - Key: Name Value: !Sub '${EnvironmentName}-target-vpc' - Key: Environment Value: !Ref EnvironmentName # 移行先VPC - パブリックサブネット 1a TargetPublicSubnet1a: Type: AWS::EC2::Subnet Properties: VpcId: !Ref TargetVPC CidrBlock: 10.0.1.192/28 AvailabilityZone: !Select [0, !GetAZs ''] MapPublicIpOnLaunch: true Tags: - Key: Name Value: !Sub '${EnvironmentName}-target-public-1a' - Key: Environment Value: !Ref EnvironmentName # 移行先VPC - プライベートサブネット 1a TargetPrivateSubnet1a: Type: AWS::EC2::Subnet Properties: VpcId: !Ref TargetVPC CidrBlock: 10.0.1.0/26 AvailabilityZone: !Select [0, !GetAZs ''] MapPublicIpOnLaunch: false Tags: - Key: Name Value: !Sub '${EnvironmentName}-target-private-1a' - Key: Environment Value: !Ref EnvironmentName # 移行先VPC - MGNステージングサブネット 1c TargetStagingSubnet1c: Type: AWS::EC2::Subnet Properties: VpcId: !Ref TargetVPC CidrBlock: 10.0.1.64/26 AvailabilityZone: ap-northeast-1c MapPublicIpOnLaunch: false Tags: - Key: Name Value: !Sub '${EnvironmentName}-target-staging-1c' - Key: Environment Value: !Ref EnvironmentName # 移行先VPC - VPCエンドポイント専用サブネット 1a TargetVPCESubnet1a: Type: AWS::EC2::Subnet Properties: VpcId: !Ref TargetVPC CidrBlock: 10.0.1.144/28 AvailabilityZone: !Select [0, !GetAZs ''] MapPublicIpOnLaunch: false Tags: - Key: Name Value: !Sub '${EnvironmentName}-target-vpce-1a' - Key: Environment Value: !Ref EnvironmentName # 移行先VPC - VPCエンドポイント専用サブネット 1c TargetVPCESubnet1c: Type: AWS::EC2::Subnet Properties: VpcId: !Ref TargetVPC CidrBlock: 10.0.1.176/28 AvailabilityZone: ap-northeast-1c MapPublicIpOnLaunch: false Tags: - Key: Name Value: !Sub '${EnvironmentName}-target-vpce-1c' - Key: Environment Value: !Ref EnvironmentName # ======================================== # インターネットゲートウェイ - 移行元VPC # ======================================== SourceInternetGateway: Type: AWS::EC2::InternetGateway Properties: Tags: - Key: Name Value: !Sub '${EnvironmentName}-source-igw' - Key: Environment Value: !Ref EnvironmentName SourceIGWAttachment: Type: AWS::EC2::VPCGatewayAttachment Properties: VpcId: !Ref SourceVPC InternetGatewayId: !Ref SourceInternetGateway # NAT Gateway - 移行元VPC SourceNATGatewayEIP: Type: AWS::EC2::EIP DependsOn: SourceIGWAttachment Properties: Domain: vpc Tags: - Key: Name Value: !Sub '${EnvironmentName}-source-nat-eip' - Key: Environment Value: !Ref EnvironmentName SourceNATGateway: Type: AWS::EC2::NatGateway Properties: AllocationId: !GetAtt SourceNATGatewayEIP.AllocationId SubnetId: !Ref SourcePublicSubnet1a Tags: - Key: Name Value: !Sub '${EnvironmentName}-source-nat' - Key: Environment Value: !Ref EnvironmentName # ======================================== # インターネットゲートウェイ - 移行先VPC # ======================================== TargetInternetGateway: Type: AWS::EC2::InternetGateway Properties: Tags: - Key: Name Value: !Sub '${EnvironmentName}-target-igw' - Key: Environment Value: !Ref EnvironmentName TargetIGWAttachment: Type: AWS::EC2::VPCGatewayAttachment Properties: VpcId: !Ref TargetVPC InternetGatewayId: !Ref TargetInternetGateway # NAT Gateway - 移行先VPC TargetNATGatewayEIP: Type: AWS::EC2::EIP DependsOn: TargetIGWAttachment Properties: Domain: vpc Tags: - Key: Name Value: !Sub '${EnvironmentName}-target-nat-eip' - Key: Environment Value: !Ref EnvironmentName TargetNATGateway: Type: AWS::EC2::NatGateway Properties: AllocationId: !GetAtt TargetNATGatewayEIP.AllocationId SubnetId: !Ref TargetPublicSubnet1a Tags: - Key: Name Value: !Sub '${EnvironmentName}-target-nat' - Key: Environment Value: !Ref EnvironmentName # ======================================== # VPC Peering Connection # ======================================== VPCPeeringConnection: Type: AWS::EC2::VPCPeeringConnection Properties: VpcId: !Ref SourceVPC PeerVpcId: !Ref TargetVPC Tags: - Key: Name Value: !Sub '${EnvironmentName}-vpc-peering' - Key: Environment Value: !Ref EnvironmentName # ======================================== # ルートテーブル - 移行元VPC パブリックサブネット # ======================================== SourcePublicRouteTable: Type: AWS::EC2::RouteTable Properties: VpcId: !Ref SourceVPC Tags: - Key: Name Value: !Sub '${EnvironmentName}-source-public-rt' - Key: Environment Value: !Ref EnvironmentName # インターネットへのルート SourcePublicRoute: Type: AWS::EC2::Route DependsOn: SourceIGWAttachment Properties: RouteTableId: !Ref SourcePublicRouteTable DestinationCidrBlock: 0.0.0.0/0 GatewayId: !Ref SourceInternetGateway # パブリックサブネット関連付け SourcePublicSubnet1aRouteTableAssociation: Type: AWS::EC2::SubnetRouteTableAssociation Properties: SubnetId: !Ref SourcePublicSubnet1a RouteTableId: !Ref SourcePublicRouteTable # ======================================== # ルートテーブル - 移行元VPC プライベートサブネット # ======================================== SourcePrivateRouteTable: Type: AWS::EC2::RouteTable Properties: VpcId: !Ref SourceVPC Tags: - Key: Name Value: !Sub '${EnvironmentName}-source-private-rt' - Key: Environment Value: !Ref EnvironmentName # インターネットへのルート (NAT Gateway経由) SourcePrivateInternetRoute: Type: AWS::EC2::Route Properties: RouteTableId: !Ref SourcePrivateRouteTable DestinationCidrBlock: 0.0.0.0/0 NatGatewayId: !Ref SourceNATGateway # 移行先VPCへのルート (VPC Peering経由) SourceToTargetRoute: Type: AWS::EC2::Route Properties: RouteTableId: !Ref SourcePrivateRouteTable DestinationCidrBlock: 10.0.1.0/24 VpcPeeringConnectionId: !Ref VPCPeeringConnection # サブネット関連付け - 1a SourcePrivateSubnet1aRouteTableAssociation: Type: AWS::EC2::SubnetRouteTableAssociation Properties: SubnetId: !Ref SourcePrivateSubnet1a RouteTableId: !Ref SourcePrivateRouteTable # サブネット関連付け - 1c SourcePrivateSubnet1cRouteTableAssociation: Type: AWS::EC2::SubnetRouteTableAssociation Properties: SubnetId: !Ref SourcePrivateSubnet1c RouteTableId: !Ref SourcePrivateRouteTable # ======================================== # ルートテーブル - 移行元VPC VPCEサブネット # ======================================== SourceVPCERouteTable: Type: AWS::EC2::RouteTable Properties: VpcId: !Ref SourceVPC Tags: - Key: Name Value: !Sub '${EnvironmentName}-source-vpce-rt' - Key: Environment Value: !Ref EnvironmentName # VPCEサブネット関連付け - 1a SourceVPCESubnet1aRouteTableAssociation: Type: AWS::EC2::SubnetRouteTableAssociation Properties: SubnetId: !Ref SourceVPCESubnet1a RouteTableId: !Ref SourceVPCERouteTable # VPCEサブネット関連付け - 1c SourceVPCESubnet1cRouteTableAssociation: Type: AWS::EC2::SubnetRouteTableAssociation Properties: SubnetId: !Ref SourceVPCESubnet1c RouteTableId: !Ref SourceVPCERouteTable # ======================================== # ルートテーブル - 移行先VPC パブリックサブネット # ======================================== TargetPublicRouteTable: Type: AWS::EC2::RouteTable Properties: VpcId: !Ref TargetVPC Tags: - Key: Name Value: !Sub '${EnvironmentName}-target-public-rt' - Key: Environment Value: !Ref EnvironmentName # インターネットへのルート TargetPublicRoute: Type: AWS::EC2::Route DependsOn: TargetIGWAttachment Properties: RouteTableId: !Ref TargetPublicRouteTable DestinationCidrBlock: 0.0.0.0/0 GatewayId: !Ref TargetInternetGateway # パブリックサブネット関連付け TargetPublicSubnet1aRouteTableAssociation: Type: AWS::EC2::SubnetRouteTableAssociation Properties: SubnetId: !Ref TargetPublicSubnet1a RouteTableId: !Ref TargetPublicRouteTable # ======================================== # ルートテーブル - 移行先VPC プライベートサブネット # ======================================== TargetPrivateRouteTable: Type: AWS::EC2::RouteTable Properties: VpcId: !Ref TargetVPC Tags: - Key: Name Value: !Sub '${EnvironmentName}-target-private-rt' - Key: Environment Value: !Ref EnvironmentName # インターネットへのルート (NAT Gateway経由) TargetPrivateInternetRoute: Type: AWS::EC2::Route Properties: RouteTableId: !Ref TargetPrivateRouteTable DestinationCidrBlock: 0.0.0.0/0 NatGatewayId: !Ref TargetNATGateway # 移行元VPCへのルート (VPC Peering経由) TargetToSourceRoute: Type: AWS::EC2::Route Properties: RouteTableId: !Ref TargetPrivateRouteTable DestinationCidrBlock: 10.0.0.0/24 VpcPeeringConnectionId: !Ref VPCPeeringConnection # サブネット関連付け - 1a TargetPrivateSubnet1aRouteTableAssociation: Type: AWS::EC2::SubnetRouteTableAssociation Properties: SubnetId: !Ref TargetPrivateSubnet1a RouteTableId: !Ref TargetPrivateRouteTable # サブネット関連付け - ステージング 1c TargetStagingSubnet1cRouteTableAssociation: Type: AWS::EC2::SubnetRouteTableAssociation Properties: SubnetId: !Ref TargetStagingSubnet1c RouteTableId: !Ref TargetPrivateRouteTable # ======================================== # ルートテーブル - 移行先VPC VPCEサブネット # ======================================== TargetVPCERouteTable: Type: AWS::EC2::RouteTable Properties: VpcId: !Ref TargetVPC Tags: - Key: Name Value: !Sub '${EnvironmentName}-target-vpce-rt' - Key: Environment Value: !Ref EnvironmentName # 移行元VPCへのルート (VPC Peering経由) - Route 53 Resolver用 TargetVPCEToSourceRoute: Type: AWS::EC2::Route Properties: RouteTableId: !Ref TargetVPCERouteTable DestinationCidrBlock: 10.0.0.0/24 VpcPeeringConnectionId: !Ref VPCPeeringConnection # VPCEサブネット関連付け - 1a TargetVPCESubnet1aRouteTableAssociation: Type: AWS::EC2::SubnetRouteTableAssociation Properties: SubnetId: !Ref TargetVPCESubnet1a RouteTableId: !Ref TargetVPCERouteTable # VPCEサブネット関連付け - 1c TargetVPCESubnet1cRouteTableAssociation: Type: AWS::EC2::SubnetRouteTableAssociation Properties: SubnetId: !Ref TargetVPCESubnet1c RouteTableId: !Ref TargetVPCERouteTable # ======================================== # セキュリティグループ - ドメインコントローラー # ======================================== DomainControllerSecurityGroup: Type: AWS::EC2::SecurityGroup Properties: GroupName: !Sub '${EnvironmentName}-dc-sg' GroupDescription: 'Security group for Active Directory Domain Controller' VpcId: !Ref SourceVPC SecurityGroupIngress: # DNS - IpProtocol: tcp FromPort: 53 ToPort: 53 CidrIp: 10.0.0.0/24 Description: 'DNS TCP from Source VPC' - IpProtocol: tcp FromPort: 53 ToPort: 53 CidrIp: 10.0.1.0/24 Description: 'DNS TCP from Target VPC' - IpProtocol: udp FromPort: 53 ToPort: 53 CidrIp: 10.0.0.0/24 Description: 'DNS UDP from Source VPC' - IpProtocol: udp FromPort: 53 ToPort: 53 CidrIp: 10.0.1.0/24 Description: 'DNS UDP from Target VPC' # Kerberos - IpProtocol: tcp FromPort: 88 ToPort: 88 CidrIp: 10.0.0.0/24 Description: 'Kerberos TCP from Source VPC' - IpProtocol: tcp FromPort: 88 ToPort: 88 CidrIp: 10.0.1.0/24 Description: 'Kerberos TCP from Target VPC' - IpProtocol: udp FromPort: 88 ToPort: 88 CidrIp: 10.0.0.0/24 Description: 'Kerberos UDP from Source VPC' - IpProtocol: udp FromPort: 88 ToPort: 88 CidrIp: 10.0.1.0/24 Description: 'Kerberos UDP from Target VPC' # RPC - IpProtocol: tcp FromPort: 135 ToPort: 135 CidrIp: 10.0.0.0/24 Description: 'RPC from Source VPC' - IpProtocol: tcp FromPort: 135 ToPort: 135 CidrIp: 10.0.1.0/24 Description: 'RPC from Target VPC' # LDAP - IpProtocol: tcp FromPort: 389 ToPort: 389 CidrIp: 10.0.0.0/24 Description: 'LDAP TCP from Source VPC' - IpProtocol: tcp FromPort: 389 ToPort: 389 CidrIp: 10.0.1.0/24 Description: 'LDAP TCP from Target VPC' - IpProtocol: udp FromPort: 389 ToPort: 389 CidrIp: 10.0.0.0/24 Description: 'LDAP UDP from Source VPC' - IpProtocol: udp FromPort: 389 ToPort: 389 CidrIp: 10.0.1.0/24 Description: 'LDAP UDP from Target VPC' # SMB - IpProtocol: tcp FromPort: 445 ToPort: 445 CidrIp: 10.0.0.0/24 Description: 'SMB from Source VPC' - IpProtocol: tcp FromPort: 445 ToPort: 445 CidrIp: 10.0.1.0/24 Description: 'SMB from Target VPC' # LDAPS - IpProtocol: tcp FromPort: 636 ToPort: 636 CidrIp: 10.0.0.0/24 Description: 'LDAPS from Source VPC' - IpProtocol: tcp FromPort: 636 ToPort: 636 CidrIp: 10.0.1.0/24 Description: 'LDAPS from Target VPC' # Global Catalog - IpProtocol: tcp FromPort: 3268 ToPort: 3269 CidrIp: 10.0.0.0/24 Description: 'Global Catalog from Source VPC' - IpProtocol: tcp FromPort: 3268 ToPort: 3269 CidrIp: 10.0.1.0/24 Description: 'Global Catalog from Target VPC' # Dynamic RPC - IpProtocol: tcp FromPort: 49152 ToPort: 65535 CidrIp: 10.0.0.0/24 Description: 'Dynamic RPC from Source VPC' - IpProtocol: tcp FromPort: 49152 ToPort: 65535 CidrIp: 10.0.1.0/24 Description: 'Dynamic RPC from Target VPC' # RDP (管理用) - IpProtocol: tcp FromPort: 3389 ToPort: 3389 CidrIp: 10.0.0.0/24 Description: 'RDP from Source VPC' SecurityGroupEgress: - IpProtocol: -1 CidrIp: 0.0.0.0/0 Description: 'Allow all outbound traffic' Tags: - Key: Name Value: !Sub '${EnvironmentName}-dc-sg' - Key: Environment Value: !Ref EnvironmentName # ======================================== # セキュリティグループ - メンバーサーバー (移行元) # ======================================== MemberServerSecurityGroup: Type: AWS::EC2::SecurityGroup Properties: GroupName: !Sub '${EnvironmentName}-member-sg' GroupDescription: 'Security group for Member Server' VpcId: !Ref SourceVPC SecurityGroupIngress: # RDP (管理用) - IpProtocol: tcp FromPort: 3389 ToPort: 3389 CidrIp: 10.0.0.0/24 Description: 'RDP from Source VPC' # ICMP (疎通確認用) - IpProtocol: icmp FromPort: -1 ToPort: -1 CidrIp: 10.0.0.0/24 Description: 'ICMP from Source VPC' - IpProtocol: icmp FromPort: -1 ToPort: -1 CidrIp: 10.0.1.0/24 Description: 'ICMP from Target VPC' SecurityGroupEgress: - IpProtocol: -1 CidrIp: 0.0.0.0/0 Description: 'Allow all outbound traffic' Tags: - Key: Name Value: !Sub '${EnvironmentName}-member-sg' - Key: Environment Value: !Ref EnvironmentName # ======================================== # セキュリティグループ - 移行先メンバーサーバー # ======================================== TargetMemberServerSecurityGroup: Type: AWS::EC2::SecurityGroup Properties: GroupName: !Sub '${EnvironmentName}-target-member-sg' GroupDescription: 'Security group for Target Member Server' VpcId: !Ref TargetVPC SecurityGroupIngress: # RDP (管理用) - IpProtocol: tcp FromPort: 3389 ToPort: 3389 CidrIp: 10.0.0.0/24 Description: 'RDP from Source VPC' - IpProtocol: tcp FromPort: 3389 ToPort: 3389 CidrIp: 10.0.1.0/24 Description: 'RDP from Target VPC' # ICMP (疎通確認用) - IpProtocol: icmp FromPort: -1 ToPort: -1 CidrIp: 10.0.0.0/24 Description: 'ICMP from Source VPC' - IpProtocol: icmp FromPort: -1 ToPort: -1 CidrIp: 10.0.1.0/24 Description: 'ICMP from Target VPC' SecurityGroupEgress: - IpProtocol: -1 CidrIp: 0.0.0.0/0 Description: 'Allow all outbound traffic' Tags: - Key: Name Value: !Sub '${EnvironmentName}-target-member-sg' - Key: Environment Value: !Ref EnvironmentName # ======================================== # セキュリティグループ - MGNレプリケーション # ======================================== MGNReplicationSecurityGroup: Type: AWS::EC2::SecurityGroup Properties: GroupName: !Sub '${EnvironmentName}-mgn-replication-sg' GroupDescription: 'Security group for MGN Replication Server' VpcId: !Ref TargetVPC SecurityGroupIngress: # MGNレプリケーショントラフィック - IpProtocol: tcp FromPort: 1500 ToPort: 1500 CidrIp: 10.0.0.0/24 Description: 'MGN Replication from Source VPC' SecurityGroupEgress: - IpProtocol: tcp FromPort: 443 ToPort: 443 CidrIp: 0.0.0.0/0 Description: 'HTTPS for MGN API communication' Tags: - Key: Name Value: !Sub '${EnvironmentName}-mgn-replication-sg' - Key: Environment Value: !Ref EnvironmentName # ======================================== # セキュリティグループ - VPCエンドポイント (移行元VPC) # ======================================== SourceVPCEndpointSecurityGroup: Type: AWS::EC2::SecurityGroup Properties: GroupName: !Sub '${EnvironmentName}-source-vpce-sg' GroupDescription: 'Security group for VPC Endpoints in Source VPC' VpcId: !Ref SourceVPC SecurityGroupIngress: - IpProtocol: tcp FromPort: 443 ToPort: 443 CidrIp: 10.0.0.0/24 Description: 'HTTPS from Source VPC' SecurityGroupEgress: - IpProtocol: -1 CidrIp: 0.0.0.0/0 Description: 'Allow all outbound traffic' Tags: - Key: Name Value: !Sub '${EnvironmentName}-source-vpce-sg' - Key: Environment Value: !Ref EnvironmentName # ======================================== # セキュリティグループ - VPCエンドポイント (移行先VPC) # ======================================== TargetVPCEndpointSecurityGroup: Type: AWS::EC2::SecurityGroup Properties: GroupName: !Sub '${EnvironmentName}-target-vpce-sg' GroupDescription: 'Security group for VPC Endpoints in Target VPC' VpcId: !Ref TargetVPC SecurityGroupIngress: - IpProtocol: tcp FromPort: 443 ToPort: 443 CidrIp: 10.0.1.0/24 Description: 'HTTPS from Target VPC' SecurityGroupEgress: - IpProtocol: -1 CidrIp: 0.0.0.0/0 Description: 'Allow all outbound traffic' Tags: - Key: Name Value: !Sub '${EnvironmentName}-target-vpce-sg' - Key: Environment Value: !Ref EnvironmentName # ======================================== # VPCエンドポイント - 移行元VPC # ======================================== # EC2 VPCエンドポイント SourceEC2Endpoint: Type: AWS::EC2::VPCEndpoint Properties: VpcEndpointType: Interface ServiceName: !Sub 'com.amazonaws.${AWS::Region}.ec2' VpcId: !Ref SourceVPC SubnetIds: - !Ref SourceVPCESubnet1a SecurityGroupIds: - !Ref SourceVPCEndpointSecurityGroup PrivateDnsEnabled: true # MGN VPCエンドポイント SourceMGNEndpoint: Type: AWS::EC2::VPCEndpoint Properties: VpcEndpointType: Interface ServiceName: !Sub 'com.amazonaws.${AWS::Region}.mgn' VpcId: !Ref SourceVPC SubnetIds: - !Ref SourceVPCESubnet1a SecurityGroupIds: - !Ref SourceVPCEndpointSecurityGroup PrivateDnsEnabled: true # S3 Gateway VPCエンドポイント SourceS3GatewayEndpoint: Type: AWS::EC2::VPCEndpoint Properties: VpcEndpointType: Gateway ServiceName: !Sub 'com.amazonaws.${AWS::Region}.s3' VpcId: !Ref SourceVPC RouteTableIds: - !Ref SourcePrivateRouteTable # ======================================== # VPCエンドポイント - 移行先VPC # ======================================== # EC2 VPCエンドポイント TargetEC2Endpoint: Type: AWS::EC2::VPCEndpoint Properties: VpcEndpointType: Interface ServiceName: !Sub 'com.amazonaws.${AWS::Region}.ec2' VpcId: !Ref TargetVPC SubnetIds: - !Ref TargetVPCESubnet1a SecurityGroupIds: - !Ref TargetVPCEndpointSecurityGroup PrivateDnsEnabled: true # MGN VPCエンドポイント TargetMGNEndpoint: Type: AWS::EC2::VPCEndpoint Properties: VpcEndpointType: Interface ServiceName: !Sub 'com.amazonaws.${AWS::Region}.mgn' VpcId: !Ref TargetVPC SubnetIds: - !Ref TargetVPCESubnet1a SecurityGroupIds: - !Ref TargetVPCEndpointSecurityGroup PrivateDnsEnabled: true # S3 Gateway VPCエンドポイント TargetS3GatewayEndpoint: Type: AWS::EC2::VPCEndpoint Properties: VpcEndpointType: Gateway ServiceName: !Sub 'com.amazonaws.${AWS::Region}.s3' VpcId: !Ref TargetVPC RouteTableIds: - !Ref TargetPrivateRouteTable # ======================================== # Route 53 Resolver Endpoint # ======================================== # Route 53 Resolver Outbound Endpoint用のセキュリティグループ ResolverOutboundSecurityGroup: Type: AWS::EC2::SecurityGroup Properties: GroupName: !Sub '${EnvironmentName}-resolver-outbound-sg' GroupDescription: 'Security group for Route 53 Resolver Outbound Endpoint' VpcId: !Ref TargetVPC SecurityGroupEgress: - IpProtocol: udp FromPort: 53 ToPort: 53 CidrIp: 10.0.0.0/24 Description: 'Allow DNS queries to Source VPC (UDP)' - IpProtocol: tcp FromPort: 53 ToPort: 53 CidrIp: 10.0.0.0/24 Description: 'Allow DNS queries to Source VPC (TCP)' Tags: - Key: Name Value: !Sub '${EnvironmentName}-resolver-outbound-sg' - Key: Environment Value: !Ref EnvironmentName # Route 53 Resolver Outbound Endpoint (VPCエンドポイント用サブネットに配置) ResolverOutboundEndpoint: Type: AWS::Route53Resolver::ResolverEndpoint Properties: Name: !Sub '${EnvironmentName}-outbound-endpoint' Direction: OUTBOUND IpAddresses: - SubnetId: !Ref TargetVPCESubnet1a - SubnetId: !Ref TargetVPCESubnet1c SecurityGroupIds: - !Ref ResolverOutboundSecurityGroup Tags: - Key: Name Value: !Sub '${EnvironmentName}-outbound-endpoint' - Key: Environment Value: !Ref EnvironmentName # Resolver Rule: example.local を Domain Controller に転送 ResolverRule: Type: AWS::Route53Resolver::ResolverRule Properties: Name: !Sub '${EnvironmentName}-forward-to-dc' DomainName: 'example.local' RuleType: FORWARD ResolverEndpointId: !Ref ResolverOutboundEndpoint TargetIps: - Ip: '10.0.0.50' Port: 53 Tags: - Key: Name Value: !Sub '${EnvironmentName}-forward-to-dc' - Key: Environment Value: !Ref EnvironmentName # Resolver Rule Association: Target VPC に関連付け ResolverRuleAssociation: Type: AWS::Route53Resolver::ResolverRuleAssociation Properties: Name: !Sub '${EnvironmentName}-rule-association' ResolverRuleId: !Ref ResolverRule VPCId: !Ref TargetVPC # ======================================== # Outputs # ======================================== Outputs: SourceVpcId: Description: 'Source VPC ID' Value: !Ref SourceVPC Export: Name: !Sub '${EnvironmentName}-source-vpc-id' SourcePrivateSubnet1aId: Description: 'Source Private Subnet 1a ID' Value: !Ref SourcePrivateSubnet1a Export: Name: !Sub '${EnvironmentName}-source-private-subnet-1a-id' SourcePrivateSubnet1cId: Description: 'Source Private Subnet 1c ID' Value: !Ref SourcePrivateSubnet1c Export: Name: !Sub '${EnvironmentName}-source-private-subnet-1c-id' TargetVpcId: Description: 'Target VPC ID' Value: !Ref TargetVPC Export: Name: !Sub '${EnvironmentName}-target-vpc-id' TargetPrivateSubnet1aId: Description: 'Target Private Subnet 1a ID' Value: !Ref TargetPrivateSubnet1a Export: Name: !Sub '${EnvironmentName}-target-private-subnet-1a-id' TargetStagingSubnet1cId: Description: 'Target Staging Subnet 1c ID' Value: !Ref TargetStagingSubnet1c Export: Name: !Sub '${EnvironmentName}-target-staging-subnet-1c-id' VPCPeeringConnectionId: Description: 'VPC Peering Connection ID' Value: !Ref VPCPeeringConnection Export: Name: !Sub '${EnvironmentName}-vpc-peering-id' DomainControllerSecurityGroupId: Description: 'Domain Controller Security Group ID' Value: !Ref DomainControllerSecurityGroup Export: Name: !Sub '${EnvironmentName}-dc-sg-id' MemberServerSecurityGroupId: Description: 'Member Server Security Group ID' Value: !Ref MemberServerSecurityGroup Export: Name: !Sub '${EnvironmentName}-member-sg-id' TargetMemberServerSecurityGroupId: Description: 'Target Member Server Security Group ID' Value: !Ref TargetMemberServerSecurityGroup Export: Name: !Sub '${EnvironmentName}-target-member-sg-id' MGNReplicationSecurityGroupId: Description: 'MGN Replication Security Group ID' Value: !Ref MGNReplicationSecurityGroup Export: Name: !Sub '${EnvironmentName}-mgn-replication-sg-id' ResolverOutboundEndpointId: Description: 'Route 53 Resolver Outbound Endpoint ID' Value: !Ref ResolverOutboundEndpoint Export: Name: !Sub '${EnvironmentName}-resolver-outbound-endpoint-id' ResolverRuleId: Description: 'Route 53 Resolver Rule ID' Value: !Ref ResolverRule Export: Name: !Sub '${EnvironmentName}-resolver-rule-id' ResolverOutboundSecurityGroupId: Description: 'Route 53 Resolver Outbound Security Group ID' Value: !Ref ResolverOutboundSecurityGroup Export: Name: !Sub '${EnvironmentName}-resolver-outbound-sg-id'
クリックで詳細表示(compute.yaml)
AWSTemplateFormatVersion: '2010-09-09' Description: 'AWS MGN AD Conflict Experiment - Compute Stack' Parameters: EnvironmentName: Type: String Default: 'mgn-ad-experiment' Description: 'Environment name prefix for resources' LatestWindowsAmiId: Type: AWS::SSM::Parameter::Value<AWS::EC2::Image::Id> Default: '/aws/service/ami-windows-latest/Windows_Server-2022-Japanese-Full-Base' Description: 'Latest Windows Server 2022 AMI ID from SSM Parameter Store' KeyPairName: Type: String Default: '' Description: 'EC2 key pair name for Fleet Manager RDP connection (Optional: leave empty if not using Fleet Manager)' Conditions: HasKeyPair: !Not [!Equals [!Ref KeyPairName, '']] Resources: # ======================================== # IAMロール - SSM管理用 # ======================================== SSMInstanceRole: Type: AWS::IAM::Role Properties: RoleName: !Sub '${EnvironmentName}-ssm-instance-role' AssumeRolePolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Principal: Service: - ec2.amazonaws.com Action: - 'sts:AssumeRole' ManagedPolicyArns: - 'arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore' - 'arn:aws:iam::aws:policy/CloudWatchAgentServerPolicy' Tags: - Key: Name Value: !Sub '${EnvironmentName}-ssm-instance-role' - Key: Environment Value: !Ref EnvironmentName # ======================================== # IAMロール - MGNエージェント用 # ======================================== MGNAgentRole: Type: AWS::IAM::Role Properties: RoleName: !Sub '${EnvironmentName}-mgn-agent-role' AssumeRolePolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Principal: Service: - ec2.amazonaws.com Action: - 'sts:AssumeRole' ManagedPolicyArns: - 'arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore' - 'arn:aws:iam::aws:policy/CloudWatchAgentServerPolicy' - 'arn:aws:iam::aws:policy/AWSApplicationMigrationAgentPolicy' Tags: - Key: Name Value: !Sub '${EnvironmentName}-mgn-agent-role' - Key: Environment Value: !Ref EnvironmentName # ======================================== # インスタンスプロファイル - SSM管理用 # ======================================== SSMInstanceProfile: Type: AWS::IAM::InstanceProfile Properties: InstanceProfileName: !Sub '${EnvironmentName}-ssm-instance-profile' Roles: - !Ref SSMInstanceRole # ======================================== # インスタンスプロファイル - MGNエージェント用 # ======================================== MGNAgentInstanceProfile: Type: AWS::IAM::InstanceProfile Properties: InstanceProfileName: !Sub '${EnvironmentName}-mgn-agent-instance-profile' Roles: - !Ref MGNAgentRole # ======================================== # ドメインコントローラーEC2インスタンス # ======================================== DomainControllerInstance: Type: AWS::EC2::Instance Properties: InstanceType: t3.medium ImageId: !Ref LatestWindowsAmiId IamInstanceProfile: !Ref SSMInstanceProfile KeyName: !If [HasKeyPair, !Ref KeyPairName, !Ref 'AWS::NoValue'] SubnetId: !ImportValue 'Fn::Sub': '${EnvironmentName}-source-private-subnet-1a-id' SecurityGroupIds: - !ImportValue 'Fn::Sub': '${EnvironmentName}-dc-sg-id' PrivateIpAddress: 10.0.0.50 BlockDeviceMappings: - DeviceName: /dev/xvda Ebs: VolumeType: gp3 VolumeSize: 50 DeleteOnTermination: true Encrypted: true Tags: - Key: Name Value: !Sub '${EnvironmentName}-domain-controller' - Key: Environment Value: !Ref EnvironmentName - Key: Role Value: 'DomainController' # ======================================== # メンバーサーバーEC2インスタンス # ======================================== MemberServerInstance: Type: AWS::EC2::Instance Properties: InstanceType: t3.small ImageId: !Ref LatestWindowsAmiId IamInstanceProfile: !Ref MGNAgentInstanceProfile KeyName: !If [HasKeyPair, !Ref KeyPairName, !Ref 'AWS::NoValue'] SubnetId: !ImportValue 'Fn::Sub': '${EnvironmentName}-source-private-subnet-1a-id' SecurityGroupIds: - !ImportValue 'Fn::Sub': '${EnvironmentName}-member-sg-id' PrivateIpAddress: 10.0.0.51 BlockDeviceMappings: - DeviceName: /dev/xvda Ebs: VolumeType: gp3 VolumeSize: 30 DeleteOnTermination: true Encrypted: true Tags: - Key: Name Value: !Sub '${EnvironmentName}-member-server' - Key: Environment Value: !Ref EnvironmentName - Key: Role Value: 'MemberServer' # ======================================== # Outputs # ======================================== Outputs: DomainControllerInstanceId: Description: 'Domain Controller Instance ID' Value: !Ref DomainControllerInstance Export: Name: !Sub '${EnvironmentName}-dc-instance-id' DomainControllerPrivateIP: Description: 'Domain Controller Private IP Address' Value: !GetAtt DomainControllerInstance.PrivateIp Export: Name: !Sub '${EnvironmentName}-dc-private-ip' MemberServerInstanceId: Description: 'Member Server Instance ID' Value: !Ref MemberServerInstance Export: Name: !Sub '${EnvironmentName}-member-instance-id' MemberServerPrivateIP: Description: 'Member Server Private IP Address' Value: !GetAtt MemberServerInstance.PrivateIp Export: Name: !Sub '${EnvironmentName}-member-private-ip' SSMInstanceRoleArn: Description: 'SSM Instance Role ARN' Value: !GetAtt SSMInstanceRole.Arn Export: Name: !Sub '${EnvironmentName}-ssm-instance-role-arn' MGNAgentRoleArn: Description: 'MGN Agent Role ARN' Value: !GetAtt MGNAgentRole.Arn Export: Name: !Sub '${EnvironmentName}-mgn-agent-role-arn'
2.ドメコン設定
①下記スクリプトを実行してADのドメコンを設定します。
クリックで詳細表示
$DomainName = "example.local" $SafeModePassword = "P@ssw0rd123!" # ======================================== # エラー時に停止 $ErrorActionPreference = "Stop" # ログ関数 function Write-Log { param([string]$Message, [string]$Level = "INFO") $timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss" $logMessage = "[$timestamp] [$Level] $Message" Write-Host $logMessage Add-Content -Path "C:\ad-setup.log" -Value $logMessage } Write-Log "========================================" "INFO" Write-Log "Active Directory ドメインコントローラー セットアップ開始" "INFO" Write-Log "========================================" "INFO" Write-Log "ドメイン名: $DomainName" "INFO" # NetBIOS名を生成 $NetBIOSName = ($DomainName -split '\.')[0].ToUpper() Write-Log "NetBIOS名: $NetBIOSName" "INFO" # ステップ1: AD DS役割のインストール確認 Write-Log "ステップ1: AD DS役割のインストール状態を確認中..." "INFO" $addsFeature = Get-WindowsFeature -Name AD-Domain-Services if ($addsFeature.Installed) { Write-Log "AD DS役割は既にインストールされています。" "INFO" } else { Write-Log "AD DS役割をインストール中..." "INFO" try { Install-WindowsFeature -Name AD-Domain-Services -IncludeManagementTools Write-Log "AD DS役割のインストールが完了しました。" "INFO" } catch { Write-Log "AD DS役割のインストールに失敗しました: $_" "ERROR" throw } } # ステップ2: 既存のドメインコントローラーかどうかを確認 Write-Log "ステップ2: 既存のドメインコントローラー状態を確認中..." "INFO" try { $domainRole = (Get-WmiObject -Class Win32_ComputerSystem).DomainRole if ($domainRole -ge 4) { Write-Log "このサーバーは既にドメインコントローラーです。" "WARN" Write-Log "現在のドメイン: $((Get-ADDomain).DNSRoot)" "INFO" Write-Log "セットアップをスキップします。" "INFO" exit 0 } } catch { Write-Log "ドメインコントローラー状態の確認中にエラーが発生しました: $_" "WARN" } # ステップ3: 新しいフォレストとドメインの作成 Write-Log "ステップ3: 新しいフォレストとドメインを作成中..." "INFO" Write-Log "警告: サーバーは自動的に再起動されます。" "WARN" try { # SafeModePasswordをSecureStringに変換 $securePassword = ConvertTo-SecureString $SafeModePassword -AsPlainText -Force # AD DSフォレストのインストール Install-ADDSForest ` -DomainName $DomainName ` -DomainNetbiosName $NetBIOSName ` -SafeModeAdministratorPassword $securePassword ` -InstallDns:$true ` -DomainMode "WinThreshold" ` -ForestMode "WinThreshold" ` -DatabasePath "C:\Windows\NTDS" ` -LogPath "C:\Windows\NTDS" ` -SysvolPath "C:\Windows\SYSVOL" ` -NoRebootOnCompletion:$false ` -Force:$true Write-Log "ドメインコントローラーの昇格が完了しました。" "INFO" Write-Log "サーバーは再起動されます..." "INFO" } catch { Write-Log "ドメインコントローラーの昇格に失敗しました: $_" "ERROR" Write-Log "詳細なエラー情報:" "ERROR" Write-Log $_.Exception.Message "ERROR" throw } Write-Log "========================================" "INFO" Write-Log "セットアップスクリプトが完了しました。" "INFO" Write-Log "再起動後、以下のコマンドでドメインコントローラーの状態を確認してください:" "INFO" Write-Log " Get-ADDomain" "INFO" Write-Log " Get-ADForest" "INFO" Write-Log " Get-DnsServerZone" "INFO" Write-Log "" "INFO" Write-Log "再起動後、ドメイン管理者のパスワードをリセットしてください:" "INFO" Write-Log " Set-ADAccountPassword -Identity Administrator -Reset -NewPassword (ConvertTo-SecureString -AsPlainText 'P@ssw0rd123!' -Force)" "INFO" Write-Log "========================================" "INFO"
②再起動後に、ドメイン管理者のパスワードをリセットします。 (ADメンバがドメイン参加する時に成功させるため。)
Set-ADAccountPassword -Identity Administrator -Reset -NewPassword (ConvertTo-SecureString -AsPlainText 'P@ssw0rd123!' -Force)" "INFO"
ドメインコントローラの役割が与えられていることが確認できます。

3.ADメンバのドメイン参加
①下記コマンドを実行してコンピュータ名を分かりやすく変更します。
Rename-Computer -NewName "MEMBER-01" -DomainCredential (Get-Credential) -Restart -Force
再起動後、コンピュータ名が変更されています。

②下記スクリプトを実行してドメインexample.localに参加します。
クリックで詳細表示
$DomainName = "example.local" $DomainController = "10.0.0.50" $DomainAdmin = "Administrator" $DomainPassword = "P@ssw0rd123!" # エラー時に停止 $ErrorActionPreference = "Stop" # ログ関数 function Write-Log { param([string]$Message, [string]$Level = "INFO") $timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss" $logMessage = "[$timestamp] [$Level] $Message" Write-Host $logMessage Add-Content -Path "C:\domain-join.log" -Value $logMessage } Write-Log "========================================" "INFO" Write-Log "Active Directory ドメイン参加スクリプト開始" "INFO" Write-Log "========================================" "INFO" Write-Log "ドメイン名: $DomainName" "INFO" Write-Log "ドメインコントローラー: $DomainController" "INFO" # NetBIOS名を生成 $NetBIOSName = ($DomainName -split '\.')[0].ToUpper() $DomainAdminFull = "$NetBIOSName\$DomainAdmin" Write-Log "ドメイン管理者: $DomainAdminFull" "INFO" # ステップ1: 既にドメインに参加しているかを確認 Write-Log "ステップ1: 現在のドメイン参加状態を確認中..." "INFO" try { $computerInfo = Get-ComputerInfo $currentDomain = $computerInfo.CsDomain if ($currentDomain -eq $DomainName) { Write-Log "このサーバーは既にドメイン '$DomainName' に参加しています。" "WARN" Write-Log "ドメイン参加をスキップします。" "INFO" exit 0 } elseif ($currentDomain -ne "WORKGROUP") { Write-Log "このサーバーは別のドメイン '$currentDomain' に参加しています。" "WARN" Write-Log "先にドメインから離脱してください。" "ERROR" exit 1 } Write-Log "現在の状態: WORKGROUP (ドメイン未参加)" "INFO" } catch { Write-Log "ドメイン参加状態の確認中にエラーが発生しました: $_" "WARN" } # ステップ2: DNS設定の変更 Write-Log "ステップ2: DNS設定をドメインコントローラーに変更中..." "INFO" try { # アクティブなネットワークアダプターを取得 $adapter = Get-NetAdapter | Where-Object {$_.Status -eq "Up"} | Select-Object -First 1 if ($null -eq $adapter) { Write-Log "アクティブなネットワークアダプターが見つかりません。" "ERROR" throw "No active network adapter found" } $interfaceAlias = $adapter.Name Write-Log "ネットワークアダプター: $interfaceAlias" "INFO" # 現在のDNS設定を確認 $currentDns = Get-DnsClientServerAddress -InterfaceAlias $interfaceAlias -AddressFamily IPv4 Write-Log "現在のDNSサーバー: $($currentDns.ServerAddresses -join ', ')" "INFO" # DNSサーバーをドメインコントローラーに設定 Set-DnsClientServerAddress -InterfaceAlias $interfaceAlias -ServerAddresses $DomainController Write-Log "DNSサーバーを $DomainController に変更しました。" "INFO" # 変更後のDNS設定を確認 Start-Sleep -Seconds 2 $newDns = Get-DnsClientServerAddress -InterfaceAlias $interfaceAlias -AddressFamily IPv4 Write-Log "新しいDNSサーバー: $($newDns.ServerAddresses -join ', ')" "INFO" } catch { Write-Log "DNS設定の変更に失敗しました: $_" "ERROR" throw } # ステップ3: ドメインコントローラーへの接続確認 Write-Log "ステップ3: ドメインコントローラーへの接続を確認中..." "INFO" try { # LDAP接続テスト (ポート389) Write-Log "LDAP接続テスト (ポート389)..." "INFO" $ldapTest = Test-NetConnection -ComputerName $DomainController -Port 389 -WarningAction SilentlyContinue if ($ldapTest.TcpTestSucceeded) { Write-Log "LDAP接続: 成功" "INFO" } else { Write-Log "LDAP接続: 失敗" "ERROR" throw "LDAP connection failed" } # Kerberos接続テスト (ポート88) Write-Log "Kerberos接続テスト (ポート88)..." "INFO" $kerberosTest = Test-NetConnection -ComputerName $DomainController -Port 88 -WarningAction SilentlyContinue if ($kerberosTest.TcpTestSucceeded) { Write-Log "Kerberos接続: 成功" "INFO" } else { Write-Log "Kerberos接続: 失敗" "ERROR" throw "Kerberos connection failed" } # DNS名前解決テスト Write-Log "DNS名前解決テスト..." "INFO" $dnsTest = Resolve-DnsName -Name $DomainName -ErrorAction SilentlyContinue if ($dnsTest) { Write-Log "DNS名前解決: 成功 ($($dnsTest[0].IPAddress))" "INFO" } else { Write-Log "DNS名前解決: 失敗" "WARN" Write-Log "ドメイン参加は続行しますが、問題が発生する可能性があります。" "WARN" } } catch { Write-Log "ドメインコントローラーへの接続確認に失敗しました: $_" "ERROR" Write-Log "ネットワーク接続とセキュリティグループの設定を確認してください。" "ERROR" throw } # ステップ4: ドメイン参加の実行 Write-Log "ステップ4: ドメインに参加中..." "INFO" Write-Log "警告: サーバーは自動的に再起動されます。" "WARN" try { # 認証情報の作成 $securePassword = ConvertTo-SecureString $DomainPassword -AsPlainText -Force $credential = New-Object System.Management.Automation.PSCredential($DomainAdminFull, $securePassword) # ドメイン参加 Add-Computer -DomainName $DomainName -Credential $credential -Restart -Force Write-Log "ドメイン参加が完了しました。" "INFO" Write-Log "サーバーは再起動されます..." "INFO" } catch { Write-Log "ドメイン参加に失敗しました: $_" "ERROR" Write-Log "詳細なエラー情報:" "ERROR" Write-Log $_.Exception.Message "ERROR" # DNS設定を元に戻す(オプション) Write-Log "DNS設定を元に戻しています..." "WARN" try { Set-DnsClientServerAddress -InterfaceAlias $interfaceAlias -ResetServerAddresses Write-Log "DNS設定を元に戻しました。" "INFO" } catch { Write-Log "DNS設定の復元に失敗しました: $_" "WARN" } throw } Write-Log "========================================" "INFO" Write-Log "ドメイン参加スクリプトが完了しました。" "INFO" Write-Log "再起動後、以下のコマンドでドメイン参加を確認してください:" "INFO" Write-Log " Get-ComputerInfo | Select-Object CsDomain, CsDomainRole" "INFO" Write-Log " Test-ComputerSecureChannel -Verbose" "INFO" Write-Log "========================================" "INFO"
③下記コマンドを実行し、メンバーサーバーとして登録されていることが確認できました。
Get-ComputerInfo | Select-Object CsName, CsDomain, CsDomainRole

④その他、衝突後に備えて取得した情報が下記になります。
※ID5719の、ドメインにおいて認証が失敗したエラーは一時的なものです。
情報取得用スクリプト
# ======================================== # ベースライン情報収集スクリプト # ======================================== $OutputFile = "C:\baseline-info.txt" # ヘッダー "========================================" | Out-File $OutputFile "ベースライン情報(競合前)" | Out-File $OutputFile -Append "収集日時: $(Get-Date)" | Out-File $OutputFile -Append "========================================`n" | Out-File $OutputFile -Append # 1. コンピューター情報 "`n=== 1. コンピューター情報 ===" | Out-File $OutputFile -Append Get-ComputerInfo | Select-Object CsName, CsDomain, CsDomainRole | Out-File $OutputFile -Append # 2. セキュアチャネル "`n=== 2. セキュアチャネル ===" | Out-File $OutputFile -Append "Test-ComputerSecureChannel: $(Test-ComputerSecureChannel)" | Out-File $OutputFile -Append # 3. ネットワーク接続 "`n=== 3. ドメインコントローラーへの接続 ===" | Out-File $OutputFile -Append $ldap = Test-NetConnection -ComputerName 10.0.0.50 -Port 389 -WarningAction SilentlyContinue "LDAP (389): $($ldap.TcpTestSucceeded)" | Out-File $OutputFile -Append $kerberos = Test-NetConnection -ComputerName 10.0.0.50 -Port 88 -WarningAction SilentlyContinue "Kerberos (88): $($kerberos.TcpTestSucceeded)" | Out-File $OutputFile -Append # 4. Kerberosチケット "`n=== 4. Kerberosチケット ===" | Out-File $OutputFile -Append klist | Out-File $OutputFile -Append # 5. イベントログ "`n=== 5. 最近のイベントログ ===" | Out-File $OutputFile -Append Get-EventLog -LogName System -Source "NETLOGON" -Newest 5 | Select-Object TimeGenerated, EventID, Message | Out-File $OutputFile -Append Write-Host "ベースライン情報を $OutputFile に保存しました。" -ForegroundColor Green
========================================
ベースライン情報(競合前)
収集日時: 01/29/2026 06:33:34
========================================
=== 1. コンピューター情報 ===
CsName CsDomain CsDomainRole
------ -------- ------------
MEMBER-01 example.local MemberServer
=== 2. セキュアチャネル ===
Test-ComputerSecureChannel: True
=== 3. ドメインコントローラーへの接続 ===
LDAP (389): True
Kerberos (88): True
=== 4. Kerberosチケット ===
現在のログオン ID: 0:0x57cb9
キャッシュされたチケット: (2)
#0> クライアント: Administrator @ EXAMPLE.LOCAL
サーバー: krbtgt/EXAMPLE.LOCAL @ EXAMPLE.LOCAL
Kerberos チケットの暗号化の種類: AES-256-CTS-HMAC-SHA1-96
チケットのフラグ 0x40e10000 -> forwardable renewable initial pre_authent name_canonicalize
開始時刻: 1/29/2026 6:33:11 (ローカル)
終了時刻: 1/29/2026 16:33:11 (ローカル)
更新期限: 2/5/2026 6:33:11 (ローカル)
セッション キーの種類: AES-256-CTS-HMAC-SHA1-96
キャッシュ フラグ: 0x1 -> PRIMARY
呼び出された Kdc: EC2AMAZ-GLAVESF.example.local
#1> クライアント: Administrator @ EXAMPLE.LOCAL
サーバー: host/member-01.example.local @ EXAMPLE.LOCAL
Kerberos チケットの暗号化の種類: AES-256-CTS-HMAC-SHA1-96
チケットのフラグ 0x40a10000 -> forwardable renewable pre_authent name_canonicalize
開始時刻: 1/29/2026 6:33:11 (ローカル)
終了時刻: 1/29/2026 16:33:11 (ローカル)
更新期限: 2/5/2026 6:33:11 (ローカル)
セッション キーの種類: AES-256-CTS-HMAC-SHA1-96
キャッシュ フラグ: 0
呼び出された Kdc: EC2AMAZ-GLAVESF.example.local
=== 5. 最近のイベントログ ===
TimeGenerated EventID Message
------------- ------- -------
2026/01/29 3:09:08 5719 次の理由のため、このコンピューターはドメイン EXAMPLE のドメイン コントローラーの...
4. ADメンバへのMGNエージェントインストール
※MGN有効化、レプリケーションテンプレート、起動テンプレート、エージェントインストール用IAMユーザの準備などはAWSコンソール側の操作は、長くなるため省略します。
①下記コマンドを実行し、MGNエージェントインストーラをダウンロード。
curl -o .\AwsReplicationWindowsInstaller.exe https://aws-application-migration-service-ap-northeast-1.s3.ap-northeast-1.amazonaws.com/latest/windows/AwsReplicationWindowsInstaller.exe
②下記コマンドを実行し、MGNエージェントをインストール
C:\Users\Administrator.EXAMPLE\AwsReplicationWindowsInstaller.exe --region ap-northeast-1 --aws-access-key-id <エージェントインストール用IAMユーザアクセスキー> --aws-secret-access-key <エージェントインストール用IAMユーザシークレットキー> --no-replication
エージェントインストールが成功しました。

MGNのソースサーバー管理画面にも、ADメンバが表示されています。

5.レプリケーション開始
①レプリケーションを開始

②テストインスタンスを起動

プライベートIPには10.0.1.51を割り当てています。

6.ログイン~情報取得
Fleet Managerからドメインユーザでログインしようとしたところ、意外なことに移行元でも移行先でもログインできました。


移行元、移行先、ドメコンの情報を見ていきたいと思います。
移行元の情報取得
注目したいのはセキュアチャネルのステータスを示す、Test-ComputerSecureChannel: Trueの箇所です。
セキュアチャネルとは、ドメコンとメンバの間で確立する安全な通信パスのことです。
メンバがADに参加するとドメコンから内部的なパスワードが発行され、セキュアチャネルを確立します。
上記のパスワードはドメインユーザが利用するものとは異なり、人間が管理・使用することはありません。パスワードは定期的(デフォルト30日周期)で自動更新されます。
Test-ComputerSecureChannelがTrueとなっているため、ドメコンによる認証は問題ないことが分かります。
========================================
ベースライン情報(競合後)
収集日時: 01/30/2026 09:39:27
========================================
=== 1. コンピューター情報 ===
CsName CsDomain CsDomainRole
------ -------- ------------
MEMBER-01 example.local MemberServer
=== 2. セキュアチャネル ===
Test-ComputerSecureChannel: True
=== 3. ドメインコントローラーへの接続 ===
LDAP (389): True
Kerberos (88): True
=== 4. Kerberosチケット ===
現在のログオン ID: 0:0x57cb9
キャッシュされたチケット: (3)
#0> クライアント: Administrator @ EXAMPLE.LOCAL
サーバー: krbtgt/EXAMPLE.LOCAL @ EXAMPLE.LOCAL
Kerberos チケットの暗号化の種類: AES-256-CTS-HMAC-SHA1-96
チケットのフラグ 0x40e10000 -> forwardable renewable initial pre_authent name_canonicalize
開始時刻: 1/30/2026 9:33:41 (ローカル)
終了時刻: 1/30/2026 19:33:41 (ローカル)
更新期限: 2/6/2026 9:33:41 (ローカル)
セッション キーの種類: AES-256-CTS-HMAC-SHA1-96
キャッシュ フラグ: 0x1 -> PRIMARY
呼び出された Kdc: EC2AMAZ-GLAVESF.example.local
#1> クライアント: Administrator @ EXAMPLE.LOCAL
サーバー: LDAP/EC2AMAZ-GLAVESF.example.local/example.local @ EXAMPLE.LOCAL
Kerberos チケットの暗号化の種類: AES-256-CTS-HMAC-SHA1-96
チケットのフラグ 0x40a50000 -> forwardable renewable pre_authent ok_as_delegate name_canonicalize
開始時刻: 1/30/2026 9:35:30 (ローカル)
終了時刻: 1/30/2026 19:33:41 (ローカル)
更新期限: 2/6/2026 9:33:41 (ローカル)
セッション キーの種類: AES-256-CTS-HMAC-SHA1-96
キャッシュ フラグ: 0
呼び出された Kdc: EC2AMAZ-GLAVESF.example.local
#2> クライアント: Administrator @ EXAMPLE.LOCAL
サーバー: host/member-01.example.local @ EXAMPLE.LOCAL
Kerberos チケットの暗号化の種類: AES-256-CTS-HMAC-SHA1-96
チケットのフラグ 0x40a10000 -> forwardable renewable pre_authent name_canonicalize
開始時刻: 1/30/2026 9:33:41 (ローカル)
終了時刻: 1/30/2026 19:33:41 (ローカル)
更新期限: 2/6/2026 9:33:41 (ローカル)
セッション キーの種類: AES-256-CTS-HMAC-SHA1-96
キャッシュ フラグ: 0
呼び出された Kdc: EC2AMAZ-GLAVESF.example.local
=== 5. 最近のイベントログ ===
TimeGenerated EventID Message
------------- ------- -------
2026/01/29 3:09:08 5719 次の理由のため、このコンピューターはドメイン EXAMPLE のドメイン コントローラーの...
移行先の情報取得
移行先サーバーもTest-ComputerSecureChannel: Trueとなっていました。
移行先においてもセキュアチャネルが確立されているため、移行元、移行先どちらにもドメインユーザでログインできた…というわけですね。
ねこまるの AD フリーク様の記事より、同じコンピュータアカウントがADドメインに参加した時点でどちらかのセキュアチャネルが破損するものと思っていたため、これは意外でした。
ドメイン参加済みのドメイン メンバーのコンピューターで使用されているホスト名と、同じ名前のコンピューターをドメインに参加させた場合、セキュアチャネルの破損が発生します。同じ名前のコンピューターをドメイン参加させたタイミングにて、すでにあるコンピューター アカウントが上書きされ、パスワードも変更されます。そのため、既存のコンピューターとドメイン コントローラーとでパスワードの不整合が発生します。
======================================== ベースライン情報(競合後) 収集日時: 01/30/2026 09:37:18 ======================================== === 1. コンピューター情報 === CsName CsDomain CsDomainRole ------ -------- ------------ MEMBER-01 example.local MemberServer === 2. セキュアチャネル === Test-ComputerSecureChannel: True === 3. ドメインコントローラーへの接続 === LDAP (389): True Kerberos (88): True === 4. Kerberosチケット === 現在のログオン ID: 0:0x2f7402 キャッシュされたチケット: (0) === 5. 最近のイベントログ === TimeGenerated EventID Message ------------- ------- ------- 2026/01/29 3:09:08 5719 次の理由のため、このコンピューターはドメイン EXAMPLE のドメイン コントローラーの...
ドメコンの情報取得
DNSレコードにおいてはMEMBER-01.example.localに10.0.1.51が対応しており、移行先がメンバとして認識されていました。
例えば上記ドメイン名を指定してRDPログインしようとした場合は、意図せず移行先にログインすることになってしまう…などの影響が考えられます。


実験_セキュアチャネルをリセットしてみる。
前述の通りセキュアチャネルのパスワードは自動更新されますが、その場合どうなるのでしょうか。 試しに移行元においてセキュアチャネルを手動リセットし、何が起こるかを確認したいと思います。
下記コマンドを実行してセキュアチャネルをリセット( = パスワードを更新)します。

移行先サーバーでドメインユーザによるログイン失敗。

移行先サーバーでセキュアチャネルが破損していることが確認できました。
前述の記事に記載されている内容が原因と考えられます。


イベントログにも、同名のコンピュータアカウントが存在することで認証失敗した旨が記載されていました。


ドメコンから見えるMEMBER-01.example.localは移行元サーバー10.0.0.51に変更されていました。

対策
下記のような対策が考えられますが、本ブログでは概要までとし、いずれご紹介できたらと思います。
- 移行後サーバーのドメコンへの通信をNACLやセキュリティグループで制限してカットオーバーインスタンス(移行後サーバー)を起動し、下記いずれかを実行する
- カットオーバーインスタンスにsysprepを実行して、コンピュータアカウントが重複しないようにする。
- 移行元サーバーを停止した後にカットオーバーインスタンスの制限を解除し、ADドメインへ参加する。
結論(再掲)
- 移行直後は移行元、移行先双方でActiveDirectory認証が利用可能だった。
- ドメコンが管理するDNSレコードでは、移行元、移行先どちらかのみが登録された(今回の検証では移行先サーバーが登録された)
- セキュアチャネルのパスワードが更新されると、更新されなかったサーバー側ではセキュアチャネルが破損してActiveDirectory認証が利用できなくなった。
この記事がどなたかの一助になれば幸いです。