How do I set an opensearch service password using secretsmanager in CDK?

0

I'm trying to setup an opensearch domain that can be connected to AWS Glue.

I've got that working manually by using fine grained access control and setting a username/password.

I'm trying to replicate this in the CDK but I'm running into an issue where the password doesn't seem to be getting correctly passed. I have the secret created and it looks correct, but when testing by trying to login to the dashboard it doesn't work. I tried resetting the password to the same value as the secret and that works, but I'd like to automate this.

CDK Code

`

OSS_USERNAME='admin'
PASSWORD_FIELD='es.net.http.auth.pass'
oss_creds = secretsmanager.Secret(
    self,
    id='domain-creds',
    generate_secret_string=secretsmanager.SecretStringGenerator(
        secret_string_template=json.dumps({"es.net.http.auth.user": OSS_USERNAME}),
        generate_string_key=PASSWORD_FIELD
    )
)

oss_domain = opensearch.Domain(
    self,
    id='domain'
    version=opensearch.EngineVersion.OPENSEARCH_2_5,
    ebs=opensearch.EbsOptions(
        volume_size=300,
        volume_type=ec2.EbsDeviceVolumeType.GP3
    ),
    node_to_node_encryption=True,
    encryption_at_rest=opensearch.EncryptionAtRestOptions(
        enabled=True
    ),
    enforce_https=True,
    fine_grained_access_control=opensearch.AdvancedSecurityOptions(
        master_user_name=OSS_USERNAME,
        master_user_password=oss_creds.secret_value_from_json(PASSWORD_FIELD)
    )
)

`

1 Answer
0

I tried replicating internally using CDK with almost similar code in Python and was able to access the dashboard with credentials saved in secrets manager. Please find below sample code.

let OSS_USERNAME='admin'
    let PASSWORD_FIELD='es.net.http.auth.pass'
const secret  = new secretsmanager.Secret(
    this,
    'domain-creds', {
      
      generateSecretString : {
        secretStringTemplate: JSON.stringify({"es.net.http.auth.user": OSS_USERNAME}),
        generateStringKey: PASSWORD_FIELD
      },
    }
)

const domain = new opensearchservice.Domain(this , 'domain',{
  version: opensearchservice.EngineVersion.OPENSEARCH_2_5,
  ebs: {
    volumeSize: 300,
    volumeType: ec2.EbsDeviceVolumeType.GP3,
  },
  nodeToNodeEncryption: true,
  encryptionAtRest: {
    enabled: true,
  },
enforceHttps: true,
fineGrainedAccessControl : {
  masterUserName: OSS_USERNAME,
  masterUserPassword : secret.secretValueFromJson(PASSWORD_FIELD)
}

})

Here is the sample Cloudformation template which create FGAC enabled domain for you and fetch master username and password from AWS Secrets manager in case it is helpful for you. Kindly make the necessary changes as per your requirements and organizational security policies.

{
    "Resources": {
        "OS": {
            "Type": "AWS::OpenSearchService::Domain",
            "Properties": {
                "DomainName": "<domain name>",
                "EngineVersion": "Elasticsearch_7.10",
                "ClusterConfig": {
                    "DedicatedMasterEnabled": true,
                    "InstanceCount": "1",
                    "ZoneAwarenessEnabled": false,
                    "InstanceType": "t3.small.search",
                    "DedicatedMasterType": "t3.small.search",
                    "DedicatedMasterCount": "3"
                },
                "EBSOptions": {
                    "EBSEnabled": true,
                    "Iops": "0",
                    "VolumeSize": "20",
                    "VolumeType": "gp2"
                },
                "AdvancedSecurityOptions": {
                    "Enabled": true,
                    "InternalUserDatabaseEnabled": true,
                    "MasterUserOptions": {
                        "MasterUserName": "{{resolve:secretsmanager:******:SecretString:username}}",
                        "MasterUserPassword": "{{resolve:secretsmanager:*******:SecretString:password}}"
                    }
                },
                "AccessPolicies": {
                    "Version": "2012-10-17",
                    "Statement": [
                        {
                            "Effect": "Allow",
                            "Principal": {
                                "AWS": "*"
                            },
                            "Action": "es:*",
                            "Resource": "arn:aws:es:us-east-1:<AWS account id>:domain/<domain name>/*",
      "Condition": {
        "IpAddress": {
                <Add IP address as per your requriments>
        }
}
                        }
                    ]
                },
                "AdvancedOptions": {
                    "rest.action.multi.allow_explicit_index": true,
                    "override_main_response_version": true
                },
                "EncryptionAtRestOptions": {
                    "Enabled": true
                },
                "NodeToNodeEncryptionOptions": {
                    "Enabled": true
                },
                "DomainEndpointOptions": {
                    "EnforceHTTPS": true
                }
            },
            "Metadata": {
                "AWS::CloudFormation::Designer": {
                    "id": "a****"
                }
            }
        }
    }
}

I kindly request you to try above mentioned code in CDK once. If issue still persists, then in order to dive deep into issue, we require details that are non-public information. Please open a support case with AWS using reference[1].

I also request you to check the Cloudformation template shared above in case it is useful for you.

Reference:

[1] https://console.aws.amazon.com/support/home#/case/create

profile pictureAWS
SUPPORT ENGINEER
AkashD
answered a year ago

You are not logged in. Log in to post an answer.

A good answer clearly answers the question and provides constructive feedback and encourages professional growth in the question asker.

Guidelines for Answering Questions