in aws-networkfirewall-firewall/src/main/java/software/amazon/networkfirewall/firewall/UpdateHandler.java [203:253]
private boolean stabilizeFirewallPolicyUpdate(final AssociateFirewallPolicyRequest awsRequest,
final AssociateFirewallPolicyResponse awsResponse, final ProxyClient<NetworkFirewallClient> client,
final ResourceModel model, final CallbackContext callbackContext) {
try {
final DescribeFirewallResponse response = client.injectCredentialsAndInvokeV2(
Translator.translateToDescribeFirewallRequest(model),
client.client()::describeFirewall);
// this can never be empty for active Firewall, but just in case of a bug, we should not mark the update
// as success.
if (response.firewallStatus().syncStates().isEmpty()) {
return false;
}
// Its not enough just for the firewallStatus to be in `READY` and the ConfigurationSyncStateSummary to be
// in `IN_SYNC` because firewall-policy association request is asynchronous. So, there is a
// chance that when we call describe right after associateFirewallPolicy API, the work might not have
// been started. So, the firewall status will be 'READY' and 'IN_SYNC' from the previous policy or
// rule group updates. So, to confirm if the desired firewallPolicy got associated, we have to verify
// the Config SyncStatus of this particular firewall policy ARN we are trying to associate here.
// since same policy is associated to all subnets in a firewall, loop through all AZs under SyncStates key.
for (final Map.Entry<String, SyncState> azSyncState : response.firewallStatus().syncStates().entrySet()) {
final SyncState syncState = azSyncState.getValue();
// check if the desired firewallPolicy ARN is part of the syncStates config Map.
if (syncState.config().containsKey(desiredStateModel.getFirewallPolicyArn())) {
switch (syncState.config().get(desiredStateModel.getFirewallPolicyArn()).syncStatus()) {
case PENDING:
return false;
case IN_SYNC:
// continue to check the status in remaining AZs
continue;
default:
logger.log(String.format("Invalid/Unsupported syncState found while associating firewall"
+ "Policy: %s", desiredStateModel.getFirewallPolicyArn()));
throw new CfnServiceInternalErrorException("FirewallPolicy failed to associate.");
}
} else {
// desired firewallPolicy ARN is not yet added to SyncState, so still not stabilized
return false;
}
}
// after confirming that firewallPolicy is associated to all subnets, check the firewallStatus and
// configurationSyncStateSummary because this policy might have brought in new ruleGroups which also should
// be in sync and that can be verified though the consolidated configurationSyncStateSummary.
return response.firewallStatus().status() == FirewallStatusValue.READY &&
response.firewallStatus().configurationSyncStateSummary() == ConfigurationSyncState.IN_SYNC;
} catch (final Exception e) {
throw new CfnGeneralServiceException("FirewallPolicy failed to associate.");
}
}