首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >CDK DnsValidatedCertificate:当托管区域是父帐户的一部分时,可以在链接的AWS帐户中创建证书吗?

CDK DnsValidatedCertificate:当托管区域是父帐户的一部分时,可以在链接的AWS帐户中创建证书吗?
EN

Stack Overflow用户
提问于 2019-09-25 15:25:01
回答 4查看 6.6K关注 0票数 5

我正在尝试使用AWS的云开发工具包为我的网站的一些子域创建SSL证书。问题是,我使用的是AWS组织,相关资源属于不同的AWS帐户。我的域的托管区是我们主帐户的一部分,但是我运行CDK是为了在一个链接帐户中部署一个堆栈。这意味着DnsValidatedCertificate 班级能够请求一个新的证书(在堆栈回滚后仍然可以在ACM中看到它们),但是当它试图创建一个DNS记录以自动验证请求时,它会抛出一个错误。

下面是错误(修改了我的帐号和堆栈名):

代码语言:javascript
复制
 5/6 | 22:44:14 | CREATE_FAILED        | AWS::CloudFormation::CustomResource | SubSubDomainsCertificate/CertificateRequestorResource/Default (SubSubDomainsCertificateCertificateRequestorResourceBC626C85) Failed to create resource. User: arn:aws:sts::123456789012:assumed-role/MyStack-SubSubDomainsCertificateCertificat-16QRI74P8POO2/MyStack-SubSubDomainsCertificateCertificat-BXZ55WHIH1XC is not authorized to access this resource
        new CustomResource (C:\repos\my-project\node_modules\@aws-cdk\aws-cloudformation\lib\custom-resource.ts:92:21)
        \_ new DnsValidatedCertificate (C:\repos\my-project\node_modules\@aws-cdk\aws-certificatemanager\lib\dns-validated-certificate.ts:81:29)
        \_ new MyStack (C:\repos\my-project\.elasticbeanstalk\api-stack.js:91:25)

下面是CDK代码的相关部分(同样,对HZ和域进行了修改):

代码语言:javascript
复制
    // Executed with `cdk deploy --profile profileForLinkedAwsAccount`
    const hostedZone = route53.HostedZone.fromHostedZoneAttributes(
      this,
      'MyDomainHostedZone',
      {
        hostedZoneId: 'Z2ABC1234RYN', // in master AWS account
        zoneName: 'mydomain.com.'
      }
    );
    const certificate = new certificatemanager.DnsValidatedCertificate(
      this,
      'SubSubDomainsCertificate',
      {
        domainName: `*.demo.mydomain.com`,
        hostedZone,
        region: 'us-east-1',
        validationMethod: certificatemanager.ValidationMethod.DNS // ???
      }
    );

那么,是否有任何方法来配置CDK来允许DNS验证自动发生呢?还是我需要作为第二步,使用不同的配置文件?

编辑:根据Michael的建议,我在主AWS帐户中添加了一个名为LinkedAccountCertValidatorRole的角色。下面显示了我在角色和它的信任关系中附加的托管策略。不幸的是,我仍然会犯同样的错误。此外,Advisor选项卡指示此角色从未使用策略。

代码语言:javascript
复制
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": "route53:ChangeResourceRecordSets",
            "Resource": "arn:aws:route53:::hostedzone/Z2ABC1234RYN"
        }
    ]
}
代码语言:javascript
复制
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::123456789012:root"
      },
      "Action": "sts:AssumeRole",
      "Condition": {}
    }
  ]
}
EN

回答 4

Stack Overflow用户

发布于 2019-09-26 07:49:10

为了完整起见,我将在这里发布一个简单的答案:使用证书类而不是DnsValidatedCertificate。我可以让CDK创建一个证书请求,但不让它尝试自动验证子域。这意味着我必须:

  1. 在链接帐户的Amazon证书管理器中查找请求,
  2. 检查(或导出)它要求添加的CNAME记录,以及
  3. 切换到主AWS帐户并在Route53中添加记录。
代码语言:javascript
复制
// Executed with `cdk deploy --profile profileForLinkedAwsAccount`
const certificate = new certificatemanager.Certificate(this, 'SubSubDomainsCertificate', {
  domainName: `*.${SUBDOMAIN}.mydomain.com`,
  validationMethod: ValidationMethod.DNS
});

目前,我已经决定了这个选项,但是最好完全自动化这个过程。

票数 5
EN

Stack Overflow用户

发布于 2019-09-25 15:34:57

我可能是一个痛苦的得到正确的。首先,您创建的角色必须与用户/帐户/组建立信任关系,才能承担该角色。我看不出你在行动中提到过这一点。我不知道CDK是什么,所以我无法弄清楚你在做什么。

角色对可以执行的操作具有权限。还有一个信任关系部分,它定义了谁或什么可以承担这个角色。

受信任的关系应该有一个映射到orgs主帐户,比如..。

在主帐户中创建具有附加权限的角色:

代码语言:javascript
复制
My_Role_To_Assume
Assign Permissions in Master:

Trust Relationship(Master Account)
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "",
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::0123456789012:root"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}

在主帐户中创建一个组,并将用户分配给该组。组权限,应该有一个策略文档,显示允许用户承担的角色和子帐户号。

代码语言:javascript
复制
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "sts:AssumeRole"
      ],
      "Resource": [
        "arn:aws:iam::987654321098:role/My_Role_To_Assume",
        "arn:aws:iam::567890123456:role/My_Other_Role_Assume"
      ]
    }
  ]
}

那么,考虑到您希望角色能够访问。使用相同的名称创建一个角色(不必是,但记住这些角色的作用要简单得多)。

代码语言:javascript
复制
My_Role_To_Assume
Assign Permissions for role in sub-account:

Attach Trust Realtionship policy for sub-account role to trust master account:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "",
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::0123456789012:root"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}

您可以调整每个帐户中的权限集,以提供更细粒度的资源控制/访问。通常在主帐户中,除了IAM密码、密钥管理等之外,您可能没有任何权限。

这种方法工作得很好,总体原理是在根级创建信任关系,但是主帐户中的组策略规定了用户/组在子帐户中可以扮演的角色。

由于您使用的是CLI,在创建或更新子帐户中的资源之前,您必须发出aws sts调用来承担此角色。有一些脚本可以为您处理此问题。

示例:

代码语言:javascript
复制
#! /bin/bash
#
# Dependencies:
#   yum install -y jq
#
# Setup:
#   chmod +x ./assume_cloudadmin_role.sh
#
# Execute:
#   source ./assume_cloudadmin_role.sh
#
# Description:
#   Makes assuming an AWS IAM role (+ exporting new temp keys) easier. You're users access key and secret must allow you to assume the role in the sts CLI call.

unset  AWS_SESSION_TOKEN
export AWS_ACCESS_KEY_ID=<place_your_key_here> #Master Account API Key
export AWS_SECRET_ACCESS_KEY=<place_your_secret_here>#Master Account API Secret
export AWS_REGION=us-east-1

temp_role=$(aws sts assume-role \
                    --role-arn "arn:aws:iam::0123456789012:role/My_Role_To_Assume" \
                    --role-session-name "temp_cli_role")

export AWS_ACCESS_KEY_ID=$(echo $temp_role | jq -r .Credentials.AccessKeyId)
export AWS_SECRET_ACCESS_KEY=$(echo $temp_role | jq -r .Credentials.SecretAccessKey)
export AWS_SESSION_TOKEN=$(echo $temp_role | jq -r .Credentials.SessionToken)

env | grep -i AWS_

此调用将设置您的访问密钥和秘密+会话令牌,以在子帐户上执行操作。

希望你能让它发挥作用!

票数 2
EN

Stack Overflow用户

发布于 2021-06-14 07:12:21

在这个答案的日期,随着API的更新,CDK允许这种类型的DNS验证。我已经成功地在预先存在的托管区域中创建了一个包含子域和多个备用域的证书。但是,我没有使用链接帐户,所以我没有检查这个方面是否有效。

DnsValidatedCertificate上,输入属性validation可以接受调用CertificateValidation.fromDnsMultiZone的结果。这个静态成员调用接受一个对象,其键/值对表示证书中的域及其IHostedZone对象。您可以通过调用CDK 53的HostedZone.fromLookup(this, id, { domainName: domain })来获取对托管区域的引用。

把这一切结合在一起:

代码语言:javascript
复制
import { HostedZone } from '@aws-cdk/aws-route53';
import { Certificate, CertificateValidation } from '@aws-cdk/aws-certificatemanager';

// within the stack...
const hzone = HostedZone.fromLookup(this, 'hz', { domainName: 'www.example.com' });
const cert  = new Certificate(this, 'cert', {
  domainName: site,
  validation: CertificateValidation.fromDnsMultiZone({ 'www.example.com': hzone }),
  region: 'us-east-1',
});

注意事项:根据您的DNS配置,您可能必须对上面的代码片段进行一些调整。例如,www.example.com可以是托管区域example.com中的CNAME或记录。在这种情况下,对fromLookup的调用应该使用example.com作为domainName而不是www子域。

此外,此过程还创建一个文件cdk.context.json,该文件保留托管区域引用的DNS查找上下文。下面是一个关于需要将这个文件签入源代码管理的完整的讨论线

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/58101817

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档