Skip to content
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

Allow deployment slot settings #862

Draft
wants to merge 107 commits into
base: master
Choose a base branch
from

Conversation

nargiz
Copy link
Contributor

@nargiz nargiz commented Jan 18, 2022

This PR closes #838

The changes in this PR are as follows:

  • Allows you to specify slot settings for web app/functions using slot_setting and slot_settings

I have read the contributing guidelines and have completed the following:

  • Tested my code end-to-end against a live Azure subscription.
  • Updated the documentation in the docs folder for the affected changes.
  • Written unit tests against the modified code that I have made.
  • Updated the release notes with a new entry for this PR.
  • Checked the coding standards outlined in the contributions guide and ensured my code adheres to them.

If I haven't completed any of the tasks above, I include the reasons why here:

Below is a minimal example configuration that includes the new features, which can be used to deploy to Azure:

let myWebApp = webApp {
    name "test"
    add_slot deploymentSlot

    slot_settings ["my_slot_setting", "sticky value"]
}

@nargiz nargiz changed the title Comp it main Allow deployment slot settings Jan 18, 2022
Copy link
Member

@isaacabraham isaacabraham left a comment

Choose a reason for hiding this comment

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

Thank you very much! I think the core of this looks good, but I'm not sure adding a new keyword is the right way to go (see review comments).

I know that there were some other PRs and issues about slots - @ninjarobot @TheRSP do they relate to this at all?

@@ -323,6 +323,12 @@ type FunctionsConfig =
{ site with AppSettings = None; ConnectionStrings = None }
for (_, slot) in this.CommonWebConfig.Slots |> Map.toSeq do
slot.ToSite site

if this.CommonWebConfig.SlotSettingNames <> Set.empty then
{
Copy link
Member

Choose a reason for hiding this comment

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

Formatting - I actually do prefer this style but the rest of Farmer uses the more common record creation style, could you follow that? Also ; unnecessary and can be removed.

@@ -45,6 +45,8 @@ The Functions builder is used to create Azure Functions accounts. It abstracts t
| publish_as | Specifies whether to publish function as code or as a docker container. |
| add_slot | Adds a deployment slot to the app |
| add_slots | Adds multiple deployment slots to the app |
| slot_setting | Sets a deployment slot setting of the function in the form "key" "value". |
Copy link
Member

Choose a reason for hiding this comment

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

I wonder whether it's possible to piggy back on the existing setting keywords? Also, there's also the secret_setting keyword for adding secure settings - this should probably be migrated as well if we keep with separate keywords.

Copy link
Collaborator

Choose a reason for hiding this comment

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

How does this really differ from including config when adding a slot with add_slot and using the SlotBuilder with addSlot? I see this PR adds slotconfignames when you add these - is the purpose of this just for sticky config?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

To make settings sticky, their names should be specified in webapp(sites) child resource, slotconfignames. We usually add settings in webapp, so the idea was to have slot_setting which adds the setting and creates child resource slotconfignames.

The alternative solution was something similar to this:

let myWebApp = webApp {
    name "test"
    add_slot deploymentSlot

    settings ["my_setting", "test value"
                  "my_slot_setting", "sticky value"]

    slot_setting_names ["my_slot_setting" ]
}

Where slot_setting_names was only marking the settings as sticky by adding slotconfignames, But we thought the current solution with slot_setting will make things clearer.

@@ -540,6 +541,12 @@ type WebAppConfig =
DomainName = customDomain
SslState = SslDisabled }
| NoDomain -> ()

if this.CommonWebConfig.SlotSettingNames <> Set.empty then
{
Copy link
Member

Choose a reason for hiding this comment

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

As above re: record style.

[<CustomOperation "slot_setting">]
member this.AddSlotSetting (state:'T, key, value) =
let current = this.Get state
{ current with Settings = current.Settings.Add(key, LiteralSetting value); SlotSettingNames =current.SlotSettingNames.Add(key) }
Copy link
Member

Choose a reason for hiding this comment

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

Newline for each updated field please.

Copy link
Member

Choose a reason for hiding this comment

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

And space before and after =

@isaacabraham isaacabraham self-requested a review January 23, 2022 00:26
@TheRSP
Copy link
Contributor

TheRSP commented Jan 24, 2022

@isaacabraham this is the only open issue with slots that I'm aware of.
How would you propose this is achieved without the additional keyword? I can imagine a solution using a single-case-DU to tag a value as SlotSticky but I'm not sure this would be clearer?

…-extension

Only turn on "auto" extension for Windows
{ current with Settings = current.Settings.Add(key, LiteralSetting value); SlotSettingNames =current.SlotSettingNames.Add(key) }
|> this.Wrap state
[<CustomOperation "slot_settings">]
member this.AddSlotSettings(state:'T, settings: (string*string) list) =
Copy link
Collaborator

Choose a reason for hiding this comment

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

If this is needed independently of adding slots, it at least should support the same capabilities as the settings in slots by using the Setting type instead of just strings. Then it can be a literal or an ARM expression.

let current = this.Get state
{ current with Settings = current.Settings.Add(key, LiteralSetting value); SlotSettingNames =current.SlotSettingNames.Add(key) }
|> this.Wrap state
[<CustomOperation "slot_settings">]
Copy link
Collaborator

Choose a reason for hiding this comment

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

The convention is to use add_ when adding items to the config, so this should be add_slot_settings.

Copy link
Contributor

@TheRSP TheRSP Mar 16, 2022

Choose a reason for hiding this comment

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

Given that setting[s] doesn't follow that convention, would it be best if operator aligned with setting[s] or with other operators?

@@ -364,4 +364,63 @@ let tests = testList "Functions tests" [
|> Seq.map (fun x-> x.ToObject<{|name:string;value:string|}> ())
Expect.contains appSettings {|name="APPINSIGHTS_INSTRUMENTATIONKEY"; value="[reference(resourceId('shared-group', 'Microsoft.Insights/components', 'theName'), '2014-04-01').InstrumentationKey]"|} "Invalid value for APPINSIGHTS_INSTRUMENTATIONKEY"
}

test "Supports slot settings" {
let functionsApp = functions { name "test"; slot_settings [ "sticky_config", "sticky_config_value"; "another_sticky_config", "another_sticky_config_value" ]}
Copy link
Collaborator

Choose a reason for hiding this comment

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

Could any of these tests be enhanced to make it a practical example that would show usage along with the existing DSL to add_slots?

@isaacabraham
Copy link
Member

@nargiz I'm really sorry this hasn't been looked at for such a long time. We need to get this reviewed and merged in before it drifts too far from the main code base. @TheRSP @ninjarobot what do you both think about this - are there outstanding review issues that need to be resolved?

@ninjarobot
Copy link
Collaborator

I have some comments in the PR just around aligning with the existing DSL and making this fit with the concepts that are already there. It could be my misunderstanding of the intention, but I want to prevent DSL sprawl.

@nargiz nargiz marked this pull request as draft March 16, 2022 11:19
@nargiz
Copy link
Contributor Author

nargiz commented Mar 16, 2022

Sorry, I got a bit confused with the DSL requirements, how slot_settings should be named/represented and distracted with other things. Thanks for reminding me. I will check it by the end of the week.

@martinbryant
Copy link
Contributor

Hi @nargiz - can we look at getting the conflicts dealt with so it can be reviewed? Thanks

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Support deployment slot settings