Hey folks, hit a real snag this week and wanted to share the pain in case anyone's run into this. I'm automating our Lacework agent deployment via CloudFormation for a multi-account setup. The stack provisions the required IAM roles and the agent config, but it keeps failing on creation and then gets stuck during rollback. Super frustrating when you're trying to bake this into a pipeline! 😅
The core error in CloudTrail points to a `ValidationError` on the `LaceworkAccount` parameter. My template snippet looks like this:
```yaml
Parameters:
LaceworkAccount:
Type: String
Default: my-account-name.lacework.net
Resources:
LaceworkExternalID:
Type: AWS::IAM::ManagedPolicy
Properties:
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Action:
- sts:AssumeRole
Resource: '*'
Condition:
StringEquals:
sts:ExternalId:
!Sub 'arn:aws:iam::*:role/${LaceworkAccount}-${AWS::AccountId}'
```
I've double-checked the account name format. Has anyone else had rollback failures with the Lacework CFN template? I'm wondering if it's:
* A region-specific issue (we're deploying in `eu-central-1`).
* A timing or dependency problem where the external ID isn't resolved before the policy tries to use it.
* Something in our SCPs blocking the initial handshake, causing the whole create to fail.
My next step is to break the stack into nested stacks to isolate the failure point. Would love to hear if you've got a more elegant fix or have seen this before. Rollback failures are the worst for CI/CD stability!
-pipelinepilot
Pipeline Pilot
The issue you're seeing is likely not the account name format itself, but how the external ID is being constructed in the condition. Your `!Sub` is creating an ARN pattern for the role, but the `sts:ExternalId` condition expects a plain string identifier, not an ARN.
The external ID should be a unique, non-guessable string you get from Lacework. Your policy document should use it like this in the condition:
```yaml
Condition:
StringEquals:
sts:ExternalId: 'your-actual-external-id-from-lacework'
```
The stack fails on creation because the validation logic for the `LaceworkAccount` parameter likely expects just the subdomain portion (e.g., `my-account-name`), not the full FQDN. The subsequent rollback gets stuck because resources in a `FAILED` state can block cleanup operations. Try overriding the parameter at deployment to use the short name and verify the external ID value separately.
You've identified the correct error source, but the underlying issue is a conflation of two distinct concepts. The `sts:ExternalId` condition expects a static, secret string generated by Lacework during your cloud account integration setup. It is not derived from your account name or ARN pattern.
Your template's condition is attempting to validate a dynamic, constructed ARN, which will never match the fixed external ID token that Lacework's AWS account will provide when it tries to assume the role. This mismatch causes the initial validation failure. The rollback hang is a separate, consequential problem often caused by CloudFormation being unable to delete resources in a `CREATE_FAILED` state due to dependency locks.
You need to obtain the actual external ID from your Lacework console and pass it as a secure parameter, or better, store it in AWS Secrets Manager and reference it via dynamic parameter. The policy condition should then be a direct string equality check against that secret value, not a Sub function.
Data doesn't lie, but folks sometimes do.