public static WindowsImage IdentifyWindowsNT(WindowsInstallProviderInterface installProvider) { WindowsImage report = new WindowsImage(); var fileentries = installProvider.GetFileSystemEntries(); // // We need a few files from the install to gather enough information // These files are: // // - \ntkrnlmp.exe // or \ntoskrnl.exe // - windows\system32\config\software // - windows\system32\config\system // string kernelPath = ""; string shell32Path = ""; string softwareHivePath = ""; string systemHivePath = ""; string userPath = ""; var kernelEntry = fileentries.FirstOrDefault(x => x.EndsWith( @"\ntkrnlmp.exe", StringComparison.InvariantCultureIgnoreCase) && !x.Contains("WinSxS", StringComparison.InvariantCultureIgnoreCase)) ?? fileentries.FirstOrDefault(x => x.EndsWith(@"\ntoskrnl.exe", StringComparison.InvariantCultureIgnoreCase) && !x.Contains("WinSxS", StringComparison.InvariantCultureIgnoreCase)); if (kernelEntry != null) { kernelPath = installProvider.ExpandFile(kernelEntry); } var shell32Entry = fileentries.FirstOrDefault(x => x.EndsWith(@"system32\shell32.dll", StringComparison.InvariantCultureIgnoreCase)); if (shell32Entry != null) { shell32Path = installProvider.ExpandFile(shell32Entry); } var softwareHiveEntry = fileentries.FirstOrDefault(x => x.EndsWith(@"system32\config\software", StringComparison.InvariantCultureIgnoreCase)); if (softwareHiveEntry != null) { softwareHivePath = installProvider.ExpandFile(softwareHiveEntry); } var systemHiveEntry = fileentries.FirstOrDefault(x => x.EndsWith(@"system32\config\system", StringComparison.InvariantCultureIgnoreCase)); if (systemHiveEntry != null) { systemHivePath = installProvider.ExpandFile(systemHiveEntry); } var userEntry = fileentries.FirstOrDefault(x => x.EndsWith(@"\system32\user.exe", StringComparison.InvariantCultureIgnoreCase)); if (userEntry != null) { userPath = installProvider.ExpandFile(userEntry); } #region Version Gathering VersionInfo1 info = new VersionInfo1(); VersionInfo2 info2 = new VersionInfo2(); VersionInfo1 info3 = new VersionInfo1(); if (!string.IsNullOrEmpty(kernelPath)) { Console.WriteLine("Extracting version information from the image 1"); info = ExtractVersionInfo(kernelPath); report.Architecture = info.Architecture; report.BuildType = info.BuildType; if (report.Architecture == MachineType.x86) { var possibleNec98 = fileentries.FirstOrDefault(x => x.Contains(@"system32\hal98", StringComparison.InvariantCultureIgnoreCase)); if (possibleNec98 != null) { report.Architecture = MachineType.nec98; } } } if (!string.IsNullOrEmpty(softwareHivePath) && !string.IsNullOrEmpty(systemHivePath)) { Console.WriteLine("Extracting version information from the image 2"); info2 = ExtractVersionInfo2(softwareHivePath, systemHivePath); } if (!string.IsNullOrEmpty(userPath)) { Console.WriteLine("Extracting version information from the image 3"); info3 = ExtractVersionInfo(userPath); } report.Tag = info2.Tag; report.Licensing = info2.Licensing; report.LanguageCodes = info2.LanguageCodes; if (report.LanguageCodes == null || report.LanguageCodes.Length == 0) { FileVersionInfo infover = FileVersionInfo.GetVersionInfo(kernelPath); if (infover.Language == "Language Neutral") { infover = FileVersionInfo.GetVersionInfo(shell32Path); } var cultures = CultureInfo.GetCultures(CultureTypes.AllCultures); foreach (var culture in cultures) { if (culture.EnglishName == infover.Language) { report.LanguageCodes = new string[] { culture.Name }; break; } } } if (!string.IsNullOrEmpty(kernelPath)) { File.Delete(kernelPath); } WindowsVersion correctVersion = Common.GetGreaterVersion(info.version, info2.version); correctVersion = Common.GetGreaterVersion(correctVersion, info3.version); if (correctVersion != null) { report.MajorVersion = correctVersion.MajorVersion; report.MinorVersion = correctVersion.MinorVersion; report.BuildNumber = correctVersion.BuildNumber; report.DeltaVersion = correctVersion.DeltaVersion; report.BranchName = correctVersion.BranchName; report.CompileDate = correctVersion.CompileDate; } // we have to scan all binaries because early versions of NT // do not report the same versions in all binaries if (report.BuildNumber < 1130) { Console.WriteLine("Determined the reported build number was unreliable. Checking a few more binaries..."); ulong buildwindow = report.BuildNumber + 50; foreach (var binary in installProvider.GetFileSystemEntries()) { if (binary.EndsWith(".dll", StringComparison.InvariantCultureIgnoreCase) || binary.EndsWith(".exe", StringComparison.InvariantCultureIgnoreCase) || binary.EndsWith(".sys", StringComparison.InvariantCultureIgnoreCase)) { string file = ""; try { file = installProvider.ExpandFile(binary); var verinfo = ExtractVersionInfo(file); if (verinfo.version != null && verinfo.version.MajorVersion == report.MajorVersion && verinfo.version.MinorVersion == report.MinorVersion && verinfo.version.BuildNumber < buildwindow && report.BuildNumber < verinfo.version.BuildNumber) // allow a gap of 50 builds max { Console.WriteLine("File with newer version found: " + binary + " => " + verinfo.version.BuildNumber); report.BuildNumber = verinfo.version.BuildNumber; report.DeltaVersion = verinfo.version.DeltaVersion; } } catch { } finally { if (!string.IsNullOrEmpty(file) && File.Exists(file)) { try { File.Delete(file); } catch { }; } }; } } } #endregion #region Edition Gathering bool IsUnstaged = fileentries.Any(x => x.StartsWith(@"packages\", StringComparison.InvariantCultureIgnoreCase)); if (IsUnstaged) { report.Sku = "Unstaged"; Console.WriteLine("Image detected as unstaged, gathering target editions available in the image"); // parse editions report.Editions = GatherUnstagedEditions(installProvider); } else if (fileentries.Contains(@"InstalledRepository\Windows.config")) { var packageFile = installProvider.ExpandFile(@"InstalledRepository\Windows.config"); using (var fileStream = File.OpenRead(packageFile)) using (var streamReader = new StreamReader(fileStream)) { string line = ""; while (!line.Contains("configurationIdentity")) { line = streamReader.ReadLine(); } var editionPackageName = line.Split("name=\"")[1].Split("\"")[0]; var editionName = string.Join("", editionPackageName.Split(" ")[1..^ 0]);
internal AutoScaledInstances( CdkStack stack, CfnParameter targetPlatform, Vpc vpc, bool publicAccess, SecurityGroup albSecurityGroup, SecurityGroup instanceSecurityGroup, Database database = null, Policy policy = null, ApplicationLoadBalancer restApiLoadBalancer = null) { IMachineImage selectedImage; bool targetWindows = false; if (targetWindows) { var userData = UserData.ForWindows(); userData.AddCommands( "New-Item -Path c:\\temp -ItemType Directory -Force", $"Read-S3Object -BucketName aws-codedeploy-{stack.Region}/latest -Key codedeploy-agent.msi -File c:\\temp\\codedeploy-agent.msi", "Start-Process -Wait -FilePath c:\\temp\\codedeploy-agent.msi -WindowStyle Hidden" ); selectedImage = new WindowsImage( WindowsVersion.WINDOWS_SERVER_2019_ENGLISH_CORE_BASE, new WindowsImageProps { UserData = userData } ); } else { var userData = UserData.ForLinux(new LinuxUserDataOptions { Shebang = "#!/bin/bash -xe" }); userData.AddCommands( "exec > >(tee /var/log/user-data.log|logger -t user-data -s 2>/dev/console) 2>&1", "yum install -y aws-cli ruby jq", "yum -y update", "cd /tmp/", $"curl -O https://aws-codedeploy-{stack.Region}.s3.amazonaws.com/latest/install", "chmod +x ./install", "if ./install auto; then", " echo \"CodeDeploy Agent installation completed successfully!\"", " exit 0", "else", " echo \"CodeDeploy Agent installation failed, please investigate.\"", " rm -f /tmp/install", " exit 1", "fi", "rm -rf /tmp/*" ); selectedImage = new AmazonLinuxImage(new AmazonLinuxImageProps { Edition = AmazonLinuxEdition.STANDARD, Virtualization = AmazonLinuxVirt.HVM, Generation = AmazonLinuxGeneration.AMAZON_LINUX_2, Storage = AmazonLinuxStorage.EBS, UserData = userData }); }; var alb = new ApplicationLoadBalancer(stack, $"ApplicationLoadBalancer-{(publicAccess ? "public" : "private")}", new ApplicationLoadBalancerProps { InternetFacing = publicAccess, Vpc = vpc, VpcSubnets = new SubnetSelection { SubnetType = publicAccess ? SubnetType.PUBLIC : SubnetType.PRIVATE }, SecurityGroup = albSecurityGroup, IpAddressType = IpAddressType.IPV4, Http2Enabled = true }); var albTargetGroup = new ApplicationTargetGroup(stack, $"ApplicationTargetGroup-{(publicAccess ? "public" : "private")}", new ApplicationTargetGroupProps { Vpc = vpc, Port = 80, Protocol = ApplicationProtocol.HTTP, TargetType = TargetType.INSTANCE, HealthCheck = new Amazon.CDK.AWS.ElasticLoadBalancingV2.HealthCheck { Timeout = Duration.Seconds(5), Interval = Duration.Seconds(10), HealthyThresholdCount = 2 } }); var albListener = new ApplicationListener(stack, $"ApplicationListener-{(publicAccess ? "public" : "private")}", new ApplicationListenerProps { Port = 80, Protocol = ApplicationProtocol.HTTP, DefaultAction = ListenerAction.Forward(new[] { albTargetGroup }), LoadBalancer = alb }); var asg = new AutoScalingGroup(stack, $"ASG-{(publicAccess ? "public" : "private")}", new AutoScalingGroupProps { Vpc = vpc, MinCapacity = 2, InstanceType = InstanceType.Of(InstanceClass.BURSTABLE3, InstanceSize.MEDIUM), MachineImage = selectedImage, BlockDevices = new[] { new Amazon.CDK.AWS.AutoScaling.BlockDevice() { DeviceName = "/dev/xvda", Volume = Amazon.CDK.AWS.AutoScaling.BlockDeviceVolume.Ebs( targetWindows ? 30: 8, new Amazon.CDK.AWS.AutoScaling.EbsDeviceOptions { VolumeType = Amazon.CDK.AWS.AutoScaling.EbsDeviceVolumeType.GP2, DeleteOnTermination = true } ) } }, AssociatePublicIpAddress = false, VpcSubnets = new SubnetSelection { SubnetType = SubnetType.PRIVATE } }); if (policy != null) { asg.Role.AttachInlinePolicy(policy); } asg.Role.AddToPrincipalPolicy( new PolicyStatement(new PolicyStatementProps { Effect = Effect.ALLOW, Actions = new[] { "ec2:DescribeTags" }, Resources = new[] { "*" } }) ); asg.Role.AddManagedPolicy(ManagedPolicy.FromAwsManagedPolicyName("AmazonSSMManagedInstanceCore")); asg.Role.AddManagedPolicy(ManagedPolicy.FromAwsManagedPolicyName("AWSXRayDaemonWriteAccess")); asg.Role.AddManagedPolicy(ManagedPolicy.FromAwsManagedPolicyName("CloudWatchAgentServerPolicy")); Tag.Add(asg, "Application", stack.StackName); if (publicAccess) { Tag.Add(asg, "ApplicationRole", "Front End"); Tag.Add(asg, "RESTAPIAddress", restApiLoadBalancer.LoadBalancerDnsName); } else { Tag.Add(asg, "ApplicationRole", "REST API"); } if (database != null) { asg.Node.AddDependency(database.DatabaseResource); Tag.Add(asg, "DBSecretArn", database.Password.SecretArn); } // Enable access from the ALB asg.AddSecurityGroup(instanceSecurityGroup); Result = new LoadBalancedInstancesResult { AutoScalingGroup = asg, TargetGroup = albTargetGroup, LoadBalancer = alb }; }
this[int imageIndex] { get { // //Delay the loading of images. // if (imageIndex >= ImageCount) { return null; } if (m_Images == null) { m_Images = new WindowsImage[ImageCount]; } if (m_Images[imageIndex] == null) { m_Images[imageIndex] = new WindowsImage(m_ImageContainerHandle, m_WindowsImageFilePath, imageIndex + 1); } GC.KeepAlive(this); return m_Images[imageIndex]; } set { m_Images[imageIndex] = (value as WindowsImage); } }