def build_ec2_instance()

in source/idea/idea-administrator/src/ideaadministrator/app/cdk/stacks/directoryservice_stack.py [0:0]


    def build_ec2_instance(self):

        is_public = self.context.config().get_bool('directoryservice.public', False)
        base_os = self.context.config().get_string('directoryservice.base_os', required=True)
        instance_ami = self.context.config().get_string('directoryservice.instance_ami', required=True)
        instance_type = self.context.config().get_string('directoryservice.instance_type', required=True)
        volume_size = self.context.config().get_int('directoryservice.volume_size', 200)
        key_pair_name = self.context.config().get_string('cluster.network.ssh_key_pair', required=True)
        enable_detailed_monitoring = self.context.config().get_bool('directoryservice.ec2.enable_detailed_monitoring', default=False)
        enable_termination_protection = self.context.config().get_bool('directoryservice.ec2.enable_termination_protection', default=False)
        metadata_http_tokens = self.context.config().get_string('directoryservice.ec2.metadata_http_tokens', required=True)
        https_proxy = self.context.config().get_string('cluster.network.https_proxy', required=False, default='')
        no_proxy = self.context.config().get_string('cluster.network.no_proxy', required=False, default='')
        proxy_config = {}
        if Utils.is_not_empty(https_proxy):
            proxy_config = {
                    'http_proxy': https_proxy,
                    'https_proxy': https_proxy,
                    'no_proxy': no_proxy
                    }
        kms_key_id = self.context.config().get_string('cluster.ebs.kms_key_id', required=False, default=None)
        if kms_key_id is not None:
             kms_key_arn = self.get_kms_key_arn(kms_key_id)
             ebs_kms_key = kms.Key.from_key_arn(scope=self.stack, id=f'ebs-kms-key', key_arn=kms_key_arn)
        else:
             ebs_kms_key = kms.Alias.from_alias_name(scope=self.stack, id=f'ebs-kms-key-default', alias_name='alias/aws/ebs')

        if is_public and len(self.cluster.public_subnets) > 0:
            subnet_ids = self.cluster.existing_vpc.get_public_subnet_ids()
        else:
            subnet_ids = self.cluster.existing_vpc.get_private_subnet_ids()

        block_device_name = Utils.get_ec2_block_device_name(base_os)

        user_data = BootstrapUserDataBuilder(
            aws_region=self.aws_region,
            bootstrap_package_uri=self.bootstrap_package_uri,
            install_commands=[
                '/bin/bash openldap-server/setup.sh'
            ],
            base_os=base_os,
            infra_config={
                'LDAP_SERVICE_ACCOUNT_CREDENTIALS_SECRET_ARN': '${__LDAP_SERVICE_ACCOUNT_CREDENTIALS_SECRET_ARN__}',
                'LDAP_TLS_CERTIFICATE_SECRET_ARN': '${__LDAP_TLS_CERTIFICATE_SECRET_ARN__}',
                'LDAP_TLS_PRIVATE_KEY_SECRET_ARN': '${__LDAP_TLS_PRIVATE_KEY_SECRET_ARN__}'
            },
            proxy_config=proxy_config,
            bootstrap_source_dir_path=ideaadministrator.props.bootstrap_source_dir
        ).build()

        substituted_userdata = cdk.Fn.sub(user_data, {
            '__LDAP_SERVICE_ACCOUNT_CREDENTIALS_SECRET_ARN__': self.openldap_credentials.get_credentials_secret_arn(),
            '__LDAP_TLS_CERTIFICATE_SECRET_ARN__': self.openldap_certs.get_att_string('certificate_secret_arn'),
            '__LDAP_TLS_PRIVATE_KEY_SECRET_ARN__': self.openldap_certs.get_att_string('private_key_secret_arn')
        })

        launch_template = ec2.LaunchTemplate(
            self.stack, f'{self.module_id}-lt',
            instance_type=ec2.InstanceType(instance_type),
            machine_image=ec2.MachineImage.generic_linux({
                self.aws_region: instance_ami
                }
            ),
            user_data=ec2.UserData.custom(substituted_userdata),
            key_name=key_pair_name,
            block_devices=[ec2.BlockDevice(
                device_name=block_device_name,
                volume=ec2.BlockDeviceVolume(ebs_device=ec2.EbsDeviceProps(
                    encrypted=True,
                    kms_key=ebs_kms_key,
                    volume_size=volume_size,
                    volume_type=ec2.EbsDeviceVolumeType.GP3
                    )
                )
            )],
            require_imdsv2=True if metadata_http_tokens == "required" else False,
            associate_public_ip_address=is_public
            )

        self.openldap_ec2_instance = ec2.CfnInstance(
            self.stack,
            f'{self.module_id}-instance',
            block_device_mappings=[
                ec2.CfnInstance.BlockDeviceMappingProperty(
                    device_name=block_device_name,
                    ebs=ec2.CfnInstance.EbsProperty(
                        volume_size=volume_size,
                        volume_type='gp3'
                    )
                )
            ],
            disable_api_termination=enable_termination_protection,
            iam_instance_profile=self.openldap_instance_profile.instance_profile_name,
            instance_type=instance_type,
            image_id=instance_ami,
            key_name=key_pair_name,
            launch_template=ec2.CfnInstance.LaunchTemplateSpecificationProperty(
                version=launch_template.latest_version_number,
                launch_template_id=launch_template.launch_template_id),
            network_interfaces=[
                ec2.CfnInstance.NetworkInterfaceProperty(
                    device_index='0',
                    associate_public_ip_address=is_public,
                    group_set=[self.openldap_security_group.security_group_id],
                    subnet_id=subnet_ids[0],
                )
            ],
            user_data=cdk.Fn.base64(substituted_userdata),
            monitoring=enable_detailed_monitoring
        )
        cdk.Tags.of(self.openldap_ec2_instance).add('Name', self.build_resource_name(self.module_id))
        cdk.Tags.of(self.openldap_ec2_instance).add(constants.IDEA_TAG_NODE_TYPE, constants.NODE_TYPE_INFRA)
        self.add_backup_tags(self.openldap_ec2_instance)

        if not enable_detailed_monitoring:
            self.add_nag_suppression(
                construct=self.openldap_ec2_instance,
                suppressions=[IdeaNagSuppression(rule_id='AwsSolutions-EC28', reason='detailed monitoring is a configurable option to save costs')]
            )

        if not enable_termination_protection:
            self.add_nag_suppression(
                construct=self.openldap_ec2_instance,
                suppressions=[IdeaNagSuppression(rule_id='AwsSolutions-EC29', reason='termination protection not supported in CDK L2 construct. enable termination protection via AWS EC2 console after deploying the cluster.')]
            )