Skip to content

Adding ProvisionedConcurrency Support for Alias #97

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Conversation

Vandita2020
Copy link
Member

@Vandita2020 Vandita2020 commented Jul 12, 2023

Issue #, if available:

Summary
Adding support to configure ProvisionedConcurrency for alias in ACK.

Description
This PR adds support to configure ProvisionedConcurrency for Lambda function's alias using ACK. To implement this functionality I added ProvisionedConcurrencyConfig as an inline property to alias resource. Thus the user can directly set configurations for Provisioned Concurrency while creating alias. The user can edit the following code to set Provisioned Concurrency along with alias.

apiVersion: lambda.services.k8s.aws/v1alpha1
kind: Alias
metadata:
  name: $ALIAS_NAME
  annotations:
    services.k8s.aws/region: $AWS_REGION
spec:
  name: $ALIAS_NAME
  functionName: $FUNCTION_NAME
  functionVersion: $FUNCTION_VERSION
  description: alias created by ACK lambda-controller e2e tests
  provisionedConcurrencyConfig:
    provisionedConcurrentExecutions: $PROVISIONED_CONCURRENT_EXECUTIONS

This PR includes both implementation code and e2e tests.

Acknowledgement
By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.

@ack-prow
Copy link

ack-prow bot commented Jul 12, 2023

Skipping CI for Draft Pull Request.
If you want CI signal for your change, please convert it to an actual PR.
You can still manually trigger a test run with /test all

@ack-prow ack-prow bot added the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label Jul 12, 2023
@ack-prow ack-prow bot requested review from jljaco and RedbackThomson July 12, 2023 16:26
@Vandita2020 Vandita2020 force-pushed the provisioned_concurrecny_config_alias branch 18 times, most recently from c596c26 to 02f3de0 Compare July 13, 2023 20:23
@Vandita2020
Copy link
Member Author

/test all

@Vandita2020 Vandita2020 marked this pull request as ready for review July 13, 2023 20:59
@ack-prow ack-prow bot removed the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label Jul 13, 2023
@ack-prow ack-prow bot requested a review from a-hilaly July 13, 2023 20:59
Copy link
Member

@a-hilaly a-hilaly left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very good! Thank you @Vandita2020 !
I left few comments inline

Comment on lines 88 to 97
if desired.ko.Spec.ProvisionedConcurrencyConfig != nil {
if desired.ko.Spec.ProvisionedConcurrencyConfig.ProvisionedConcurrentExecutions != nil {
input.ProvisionedConcurrentExecutions = aws.Int64(*desired.ko.Spec.ProvisionedConcurrencyConfig.ProvisionedConcurrentExecutions)
} else {
input.ProvisionedConcurrentExecutions = aws.Int64(0)
}
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What if the user sets spec.provisionedConcurrencyConfig to nil? we want to input.ProvisionedConcurrentExecutions = aws.Int64(0)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have added the else condition to assign ProvisionedConcurrency value to 0 if user doesn't pass any value.

Comment on lines 121 to 128
if err != nil {
ko.Spec.ProvisionedConcurrencyConfig = nil
} else {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should return an error instead of ignore it

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same thing for L137 below

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This error is ignored intentionally, the error is returned by the API as there is no existing provisionedConcurrency set for the alias, and when it checks the current value in the Console, it doesn't find the configuration, as they are yet not created. So we wanted to ignore that error and instead assign the variable to nil on ACK side before we create it. To make the delta function know that there is a difference in state.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same reason for FunctionEventInvokeConfig

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In this case, can we ignore specifically NotFound errors? i'm thinking about cases where API returns something different than resource doesn't exist

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you please share what is the exact error returned by the API?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

@@ -44,7 +44,7 @@ def lambda_function():
replacements["BUCKET_NAME"] = resources.FunctionsBucket.name
replacements["LAMBDA_ROLE"] = resources.EICRole.arn
replacements["LAMBDA_FILE_NAME"] = LAMBDA_FUNCTION_FILE_ZIP
replacements["RESERVED_CONCURRENT_EXECUTIONS"] = "0"
replacements["RESERVED_CONCURRENT_EXECUTIONS"] = "3"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this needed?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we allocate both reserved concurrency and provisioned concurrency for the same function. Then, the amount of provisioned concurrency cannot exceed the amount of reserved concurrency.

assert deleted

time.sleep(DELETE_WAIT_AFTER_SECONDS)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be nice to add another update to try to delete the provisionedConcurency field and check if the controller sets it to 0

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The min value of provisionedConcurrentExecution needs to be 1, as mentioned here in the provisionedConcurrencyConfigInput type

@@ -78,6 +109,21 @@ func (rm *resourceManager) setResourceAdditionalFields(
exit := rlog.Trace("rm.setResourceAdditionalFields")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

setResourceAdditionalFields is getting huge, can you make shorter by putting some of it's logic into different functions? for example

func (rm *resourceManager) setResourceAdditionalFields(...) error {
    // ...
    ko.Spec.ProvisionnedConcurencyConfig, err = rm.getProvisionedConcurencyConfig(...)
    if err ! = nil {
        return nil
    }
    ko.Spec.FunctionEventInvokeConfig, err = rm.getFunctionInvokeConfig(...)
    if err ! = nil {
        return nil
    }
    // etc....
}

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

@@ -63,7 +63,8 @@ type AliasSpec struct {
FunctionVersion *string `json:"functionVersion"`
// The name of the alias.
// +kubebuilder:validation:Required
Name *string `json:"name"`
Name *string `json:"name"`
ProvisionedConcurrencyConfig *PutProvisionedConcurrencyConfigInput `json:"provisionedConcurrencyConfig,omitempty"`
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we inject some documentation here?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

@Vandita2020 Vandita2020 force-pushed the provisioned_concurrecny_config_alias branch from 02f3de0 to 1814ecf Compare July 17, 2023 23:02
if err != nil {
return nil
}

return nil
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

@Vandita2020 Vandita2020 force-pushed the provisioned_concurrecny_config_alias branch from 305ba44 to e751f64 Compare July 24, 2023 17:17
@ack-prow ack-prow bot added the approved label Jul 24, 2023
Comment on lines 17 to 15
if !delta.DifferentExcept("Spec.ProvisionedConcurrencyConfig"){
return desired, nil
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this should be come if !delta.DifferentExcept("Spec.ProvisionedConcurrencyConfig", "Spec.FunctionEventInvokeConfig") and L7-9 should be removed. Thoughts?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Writing them together makes sense. We just need an if condition to check the changes if any before executing the rest of the Update function.

@Vandita2020 Vandita2020 force-pushed the provisioned_concurrecny_config_alias branch from e751f64 to d090b9e Compare July 24, 2023 18:21
Copy link
Member

@a-hilaly a-hilaly left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great work on this @Vandita2020 ! 🚀
/lgtm

@ack-prow ack-prow bot added the lgtm Indicates that a PR is ready to be merged. label Jul 24, 2023
@ack-prow
Copy link

ack-prow bot commented Jul 24, 2023

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: a-hilaly, Vandita2020

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Needs approval from an approver in each of these files:
  • OWNERS [Vandita2020,a-hilaly]

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@ack-prow ack-prow bot merged commit 00df311 into aws-controllers-k8s:main Jul 24, 2023
ack-prow bot pushed a commit that referenced this pull request Aug 21, 2023
Issue #, if available:
Related PR: #97 

**Summary**
Fixing deletion part for `ProvisionedConcurrency` field.

**Description:**
This PR is related to bug fixes in [previous PR](#97) related to `ProvisionedConcurrency` implementation. When the user deleted the set configurations for Alias resource, the configurations were not deleted from the Console side, instead it used to throw an error. Fixed the bug by introducing a new condition to check if the desired configurations are nil or not, if yes then call the delete API. 

Example of changes for `ProvisionedConcurrency` in Alias resource is given below:

```
if desired.ko.Spec.ProvisionedConcurrencyConfig == nil {
	input_delete := &svcsdk.DeleteProvisionedConcurrencyConfigInput{
		FunctionName: aws.String(*desired.ko.Spec.FunctionName),
		Qualifier:    aws.String(*desired.ko.Spec.Name),
	}
	_, err = rm.sdkapi.DeleteProvisionedConcurrencyConfigWithContext(ctx, input_delete)
	rm.metrics.RecordAPICall("DELETE", "DeleteProvisionedConcurrency", err)
	if err != nil {
		return err
	}
	return nil
}
```

This PR contains implementation code and E2E test to validate the changes. 

**Acknowledgment**
By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.
ack-prow bot pushed a commit that referenced this pull request Aug 23, 2023
Issue #, if available:
Related PR: #92 #93 

**Summary**
Fixing deletion part for `EventInvokeConfig` field.

**Description:**
This PR is related to bug fixes in [previous PR](#97) related to `EventInvokeConfig` implementation. When the user deleted the set configurations for Function/Alias resource, the configurations were not deleted from the Console side, instead it used to throw an error. Fixed the bug by introducing a new condition to check if the desired configurations are nil or not, if yes then call the delete API. 

Example of changes for `EventInvokeConfig` in Alias resource is given below:

```
if r.ko.Spec.FunctionEventInvokeConfig == nil {
	input_delete := &svcsdk.DeleteFunctionEventInvokeConfigInput{
		FunctionName: aws.String(*r.ko.Spec.FunctionName),
		Qualifier:    aws.String(*r.ko.Spec.Name),
	}
	_, err = rm.sdkapi.DeleteFunctionEventInvokeConfigWithContext(ctx, input_delete)
	rm.metrics.RecordAPICall("DELETE", "DeleteFunctionEventInvokeConfig", err)
	if err != nil {
		return nil, err
	}
	return r, nil
}
```

This PR contains implementation code and E2E test to validate the changes. 

**Acknowledgment**
By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
approved lgtm Indicates that a PR is ready to be merged.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants