Problems when deploying a StackSet to enable AWS Config

0

Hi, I want to deploy a StackSet to enable AWS Config for all accounts in one of my OU. Here's the part of my template to deploy.

Resources:
  DeliveryChannel:
    Type: AWS::Config::DeliveryChannel
    Properties:
      Name:
        Ref: StackSetName
      S3BucketName:
        Ref: CentralLogBucket
      SnsTopicARN:
        Ref: ConfigTopic
      ConfigSnapshotDeliveryProperties:
        DeliveryFrequency: One_Hour

  ConfigurationRecorder:
    Type: AWS::Config::ConfigurationRecorder
    Properties:
      Name:
        Ref: StackSetName
      RoleARN:
        Fn::Sub: arn:${AWS::Partition}:iam::${AWS::AccountId}:role/aws-service-role/config.amazonaws.com/AWSServiceRoleForConfig
      RecordingGroup:
        AllSupported: true
        IncludeGlobalResourceTypes:
          Fn::If:
            - IsVirginiaCondition
            - true
            - false

After I deployed the StackSet to my OU, I noticed that in some accounts AWS Config was working while in others not. I discovered that some accounts were not working because the service linked role AWSServiceRoleForConfig was missing.

Then I modified the template to add the service linked role, and redeployed the StackSet.

Resources:
  # ...
  ConfigServiceLinkedRole:
    Type: AWS::IAM::ServiceLinkedRole
    DeletionPolicy: Retain
    Properties:
      Description: Service linked role for AWS Config
      AWSServiceName: config.amazonaws.com

This time, accounts that already had the service linked role (which were working properly at the first time) failed to create the stack instance with the error message "Service role name AWSServiceRoleForConfig has been taken in this account, please try a different suffix."

I also tried to add suffix to avoid conflict, yet failed with another error message "Custom suffix is not allowed for config.amazonaws.com".

Resources:
  # ...
  ConfigServiceLinkedRole:
    Type: AWS::IAM::ServiceLinkedRole
    DeletionPolicy: Retain
    Properties:
      Description: Service linked role for AWS Config
      AWSServiceName: config.amazonaws.com
      CustomSuffix:
        Fn::Sub: ${StackSetName}_${AWS::Region}

Is there a good way to solve this service linked role problem and deploy the AWS Config settings to all accounts properly?

  • One possible solution might be handle the Service-Linked Role creation and deletion in a custom resource, but this doesn't look like the best way. I want to know if there is a simple solution.

  • The apparently best solution I found is to enable trust access and create a multi-account aggregator to have AWSServiceRoleForConfig automatically created in all accounts in the Organization. However, no matter how I tried, I couldn't have this role created in my Organization.

profile picture
HS
asked 7 months ago608 views
6 Answers
1
Accepted Answer

Hello.

I think it is probably difficult to determine the existence of resources with CloudFormation.
Therefore, it may be a good idea to create code that creates a Lambda using a CloudFormation custom resource and determines whether there is an IAM that you want to create.
If you have an IAM to create, I think the error will no longer occur if you delete it with Lambda.
https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/template-custom-resources-lambda.html

profile picture
EXPERT
answered 7 months ago
profile picture
EXPERT
reviewed a month ago
  • Hmm. OK, thanks for your thoughts. Looking for others' suggestion.

  • Seems that there is no better solution. I'll go for the custom resource.

0

Hello. If the AWSServiceRoleForConfig role doesn't exist in an account where you want to deploy AWS Config, you can create a new service-linked role with a different name. However, you should avoid using a custom suffix for the config.amazonaws.com service. Instead, use a unique name, such as AWSServiceRoleForConfig-StackSetName, to ensure there are no naming conflicts.

Here's an example of how you can modify your CloudFormation template:

ConfigServiceLinkedRole:
  Type: AWS::IAM::ServiceLinkedRole
  DeletionPolicy: Retain
  Properties:
    Description: Service linked role for AWS Config
    AWSServiceName: config.amazonaws.com
    CustomSuffix:
      Fn::Sub: ${StackSetName}-${AWS::Region}

Handle Existing Custom Service-Linked Roles: If you encounter accounts where a custom role with the name AWSServiceRoleForConfig already exists, you may need to handle them differently. You could modify your template to skip creating the service-linked role in those accounts or update the existing role if it doesn't match your desired configuration.

Best regards, Andrii

profile picture
EXPERT
answered 7 months ago
  • Hehe, thanks for the answer.

    Here's an example of how you can modify your CloudFormation template:

    You just provide the same settings that I've already shown in the question :D

    You could modify your template to skip creating the service-linked role in those accounts or update the existing role

    It is okay if I deploy a single stack, but it won't work if I deploy multiple copies of stacks across multiple accounts and regions with the StackSet.

  • I ran into this exact problem described here.

    The solution of setting a custom suffix to the service-linked role doesn't work. If I set the CustomSuffix property, it fails with the below error:

    "Custom suffix is not allowed for config.amazonaws.com

  • You are saying to avoid using a custom suffix for the config.amazonaws.com service but at the same time, you are setting the CustomSuffix property. Isn't this contradicting?

0

Another way is to deploy one stack set with this role for asccount`s where not found role and after that deploy another stack set with config rule.

profile picture
EXPERT
answered 7 months ago
  • This solution requires a great human effort to scan across all accounts and determine which accounts have the Service-Linked Role and which do not, and to specify all of them as target accounts for each deployment. It is also error-prone due to human errors.

0

But you can deploy a stack set once that creates the role in accounts where it`s not found and the next step is you can delete an account in the stack set where this role is deployed manually or from another way.

profile picture
EXPERT
answered 7 months ago
  • Maybe I do not fully understand your thought, but are you telling me to selectively deploy the StackSet to the accounts that do not have AWSServiceRoleForConfig by excluding accounts that already have this role from the deployment targets?

0

You can do what you suggest also.

profile picture
EXPERT
answered 7 months ago
0

Just modify the YML template to create the role only in One region. You can also manipulate the order in which the regions deployed. Probably a good practice will be to deploy the IAM role only in the first region. But , YES, you will have to cleanup before applying the StackSet to OU's or Accounts.

Some modifications that worked for me below...

By Section

Parameters:
...
ServiceLinkedRoleRegion:
    Type: String
    Description: If specified, the Config service-linked role will only be created if the stack is deployed to this region. !!! You should also set the deployment region us-east-1 as the first region in the list for deployment. Chose us-east-1 for the role to be created. If you chose any other region the deployment will fail.!!!
    Default: us-east-1
    AllowedValues:
      - <DeployToAnyRegion>
      - <DeployToAllRegions>
      - us-east-1
      - us-east-2
      - us-west-1
      - us-west-2
      - ca-central-1
      - eu-central-1
      - eu-west-1
      - eu-west-2
      - eu-west-3
      - eu-north-1
      - ap-northeast-1
      - ap-northeast-2
      - ap-northeast-3
      - ap-southeast-1
      - ap-southeast-2
      - ap-south-1
      - sa-east-1
      - cn-north-1
      - ap-east-1
      - af-south-1
      - me-south-1
      - us-gov-west-1
      - us-gov-east-1
      - us-iso-east-1
      - us-isob-east-1
      - us-east-2
      - us-east-1
      - us-west-1
      - us-west-2
      - ca-central-1
      - eu-central-1
...


Conditions:
...
  CreateConfigSLR:  
    !Equals 
      - !Ref ServiceLinkedRoleRegion
      - !Ref AWS::Region
  #CreateConfigSLR: !Or
  #  - !Equals [ !Ref ServiceLinkedRoleRegion, <DeployToAnyRegion> ]
  #  - !Equals [ !Ref ServiceLinkedRoleRegion, !Ref AWS::Region ]
...

Resources:
...
 ConfigRole:
    Condition: CreateConfigSLR
    Type: AWS::IAM::ServiceLinkedRole
    Properties:
      AWSServiceName: config.amazonaws.com
      Description: Service-Linked Role for AWS Config
      #CustomSuffix: !Ref AWS::Region
      # RoleName: !Sub ConfigServiceLinkedRole-${AWS::Region}

  ConfigRecorder:
    Type: AWS::Config::ConfigurationRecorder
    Properties:
      RecordingGroup:
        AllSupported: !Ref AllSupported
        IncludeGlobalResourceTypes: !Ref IncludeGlobalResourceTypes
        ResourceTypes: !If
          - IsAllSupported
          - !Ref AWS::NoValue
          - !Ref ResourceTypes
      RoleARN:
        Fn::Sub:
          "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/aws-service-role/config.amazonaws.com/AWSServiceRoleForConfig"
...
BBA
answered a month 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