Hi and thanks in advance. I’m playing with Azure C...
# azure
c
Hi and thanks in advance. I’m playing with Azure Container Apps and I have a .NET 6 worker (https://docs.microsoft.com/en-us/dotnet/core/extensions/workers) app with a pretty standard DockerFile. Following the C# example on GitHub, https://github.com/pulumi/examples/tree/master/azure-cs-containerapps, the Pulumi stack builds the docker image using https://www.pulumi.com/registry/packages/docker/api-docs/image/ . Then pushes the image into an azure container registry, using always the same tag,
latest
. I expect that if I make a change to the app code this will be detected, and a new docker image is then created (maybe just a few layers). This will trigger a change in the
Template
of the container app, which leads to the creation of a new revision https://docs.microsoft.com/en-us/azure/container-apps/revisions . Imagining to trigger the
pulumi up
from an Azure DevOps pipeline with the Pulumi task, this should be almost perfect for the CI-CD. So which is the problem: seems that Pulumi detects a change in the container app template also if there are no changes (at least not from the point of view of the source code). For example, trying to do a
pulumi preview
leads to the creation of a new docker image that is then pushed to the registry with the latest tag plus an identifier. I think this is the culprit of the change in the container app template. Could you please help me understand this? @tall-librarian-49374 what I’m missing this time 😅? What i would like is an idempotent behavior, I want to create a revision only in case of a real change in the app source code.
t
I think our examples uses 1.0.0 as the version tag.
What is the diff showing exactly? Does it show Image as changed every time?
c
yes @tall-librarian-49374 seems that for some reason the image changes. If I remember correctly Azure ACR allows the tag overwrite, maybe the “latest” tag has a special behavior? I can try with 1.0.0 . If the behavior is the same I aspect to have something like 1.0.0-<random guid> at every new preview or up. But the question is: why the docker provider sees the image as changed?
t
Do you get the same behavior with that stock example of ours without changing anything? I think it was fine for me.
c
I try directly with your sample (but apart form the name of the objects the code is the same)…with mine the behavior is the same also using 1.0.0 tag… 😅 Here the code:
Copy code
var assemblerImageName = $"{projectName}-assembler";
var assemblerImage = new Image(assemblerImageName, new ImageArgs
{
    ImageName = Output.Format($"{containerRegistry.LoginServer}/{assemblerImageName}:1.0.0"),
    Build = new DockerBuild
    {
        Dockerfile = "./../CrazyBike.Assembler/Dockerfile",
        Context = "./.."
    },
    Registry = new ImageRegistry
    {
        Server = containerRegistry.LoginServer,
        Username = adminUsername,
        Password = adminPassword
    }
});

var assemblerName = $"{projectName}-{stackName}-ca-assembler";
var assembler = new App.ContainerApp(assemblerName, new App.ContainerAppArgs
{
    Name = assemblerName,
    ResourceGroupName = resourceGroup.Name,
    ManagedEnvironmentId = kubeEnv.Id,
    Configuration = new App.Inputs.ConfigurationArgs
    {
        Registries =
        {
            new App.Inputs.RegistryCredentialsArgs
            {
                Server = containerRegistry.LoginServer,
                Username = adminUsername,
                PasswordSecretRef = $"{containerRegistryName}-admin-pwd"
            }
        },
        Secrets = 
        {
            new App.Inputs.SecretArgs
            {
                Name = $"{containerRegistryName}-admin-pwd",
                Value = adminPassword
            }
        }
    },
    Template = new App.Inputs.TemplateArgs
    {
        Containers = 
        {
            new App.Inputs.ContainerArgs
            {
                Name = assemblerImageName,
                Image = assemblerImage.ImageName
            }
        }
    }
});
@tall-librarian-49374 if you have time (eventually also during the next days) can we schedule a 10 min call? Maybe I understood something better: if I trigger multiple pulumi up (or preview) from my machine without any source code modification effectively pulumi doesn’t detect changes… If I do the same using the task inside the azure devops pipeline (that runs on an azure pipeline hosted cloud agent --> different every time?) I have the issue…maybe because something changes in the base layers of the docker image --> for example “mcr.microsoft.com/dotnet/sdk:6.0” base image (maybe re-downloaded every time)… I’m just supposing something…I have to investigate it a bit more. If it is true one possible solution could be to try to build the image inside ACR (using a task) instead of locally on the agent??
t
You could also try using RegistryImage instead of Image. I think it may be a bit less clunky. @broad-dog-22463 who is our current expert on docker image who could help Andrea here? Andrea is preparing a Pulumi talk, so we want to make sure it’s a success 🙂
c
@tall-librarian-49374 and @broad-dog-22463 in case you can I would be very happy to have a call with someone. Maybe the BaseImageName does the trick here 😀 …I try…
Hi good morning @tall-librarian-49374 and @broad-dog-22463, trying with the BaseImageName doesn't trigger the any change in the template of the container app...but the problem is that now this is true also when actually e change exists and I really want to update the app wit ha new revision. Today I try to use the azure devops pipeline pulumi task with a self hosted agent (my local pc) --> if my theory is true no changes must be detected on the image base layers...
Good morning @tall-librarian-49374 @broad-dog-22463, I’m trying with
RegistryImage
but following the same configuration that I have for
Image
the docker build doesn’t work
Copy code
Error building docker image: Error response from daemon: Cannot locate specified Dockerfile: /Volumes/bahamut/projects/Conferences/CrazyBike/CrazyBike.Assembler/Dockerfile
and I don’t understand why because
Dockerfile
and
Context
are set in same way as for
Image
(In that case the build works). Opening a command line in the same directory of the pulumi project and trying a
docker build -f
passing the same docker file and context also works…
Copy code
var assemblerContext = $"{buildContext}/CrazyBike.Assembler";
var assemblerImageName = $"{projectName}-assembler";
var assemblerImage = new RegistryImage(assemblerImageName, new RegistryImageArgs
{
    Name = Output.Format($"{containerRegistry.LoginServer}/{assemblerImageName}:latest"),
    Build = new RegistryImageBuildArgs
    {
        Dockerfile = $"{assemblerContext}/Dockerfile",
        Context = buildContext,
        BuildId = GenerateHash(assemblerContext)
    }
}, new CustomResourceOptions
{
    Provider = dockerProvider
});
AssemblerImageName = assemblerImage.Name;
Here attached the structure of the .net solution. In general the documentation about docker resources it’s not so good 😅 . I’m also reading many issues about
RegistryImage
, many of them quite old and still without a solution (for example https://github.com/pulumi/pulumi-docker/issues/132). @faint-table-42725 @white-balloon-205 do you have one?
t
In my example I set the context as
Copy code
build: {
        context: `${cwd}/node-app`,
  },
without the dockerfile option and it works. Dockerfile is inside the
node-app
folder.
c
sorry @tall-librarian-49374 but what is here
${cwd}
?? I understand that stands for current working directory but in C# if it is an interpolated string the parameter resolves to what? The docs example is this and it’s not clear what ‘path’ is:
Copy code
using Pulumi;
using Docker = Pulumi.Docker;

class MyStack : Stack
{
    public MyStack()
    {
        var helloworld = new Docker.RegistryImage("helloworld", new Docker.RegistryImageArgs
        {
            Build = new Docker.Inputs.RegistryImageBuildArgs
            {
                Context = $"{path.Cwd}/absolutePathToContextFolder",
            },
        });
    }
}
Looking at my solution structure
CrazyBike.Infra
is the pulumi project from where the pulumi up runs, I want the solution folder as a build context (from CrazyBike.Infra, that I suppose is the current working directory, that means -->
./..
) and docker files are inside each project (one inside
CrazyBike.Assembler
, one inside
CrazyBike.Shipper
…) As I said using the
Image
in this way it works:
Copy code
var assemblerImageName = $"{projectName}-assembler";
var assemblerImage = new Image(assemblerImageName, new ImageArgs
{
    ImageName = Output.Format($"{containerRegistry.LoginServer}/{assemblerImageName}:latest"),
    Build = new DockerBuild
    {
        Dockerfile = "./../CrazyBike.Assembler/Dockerfile",
        Context = "./.."
    },
    Registry = new ImageRegistry
    {
        Server = containerRegistry.LoginServer,
        Username = adminUsername,
        Password = adminPassword
    }
});
So it means that
Image
and
RegistryImage
behave in different ways with Context and Dockerfile properties… I can’t imagine why it so difficult… 😂
t
That was a TS example and
cwd
is indeed the current working directory
So it means that
Image
and
RegistryImage
behave in different ways with Context and Dockerfile properties
Yeah that is true… they were implemented by different teams at different times. Sorry for all the troubles.
c
@tall-librarian-49374 I tried with
Directory.GetCurrentDirectory
but doesn’t work… I’m looking at this https://github.com/kreuzwerker/terraform-provider-docker/issues/249
I tried removing
**/Dockerfile*
from .
dockerignore
but doesn’t work also… this is the code that uses just the Context
Copy code
Build = new RegistryImageBuildArgs
{
    //Dockerfile = $"{shipperContext}/Dockerfile",
    Context = $"{Directory.GetCurrentDirectory()}/../CrazyBike.Shipper",
    BuildId = GenerateHash(shipperContext)
}
and this what pulumi sees
Copy code
+ docker:index/registryImage:RegistryImage: (create)
        [urn=urn:pulumi:main::crazybike::docker:index/registryImage:RegistryImage::crazybike-shipper]
        [provider=urn:pulumi:main::crazybike::pulumi:providers:docker::azure_acr::2e013c0d-d9fa-47e0-941e-bf2136e955c4]
        build             : {
            buildId   : "6da3b02a81474b5d9e423c827f0901de"
            context   : "/Volumes/bahamut/projects/Conferences/CrazyBike/CrazyBike.Infra/../CrazyBike.Shipper"
            dockerfile: "Dockerfile"
        }
        insecureSkipVerify: false
        keepRemotely      : false
        name              : "<http://crazybikemaincr.azurecr.io/crazybike-shipper:latest|crazybikemaincr.azurecr.io/crazybike-shipper:latest>"
but then it fails with the same error:
Error building docker image: Error response from daemon: Cannot locate specified Dockerfile: Dockerfile
@tall-librarian-49374 doing some other tests seems that the
RegistryImage
supports only the case where the `Dockerfile`is at the root of the build context...quite unbelievable because the docker cli works in a different way (Dockerfile must be inside the context...but maybe within a nested subfolder). Can someone confirm this? In case you have multiple projects and one that is a shared class library referenced by all the other the single project cannot be the docker build context...the only way is to select the solution folder as the context. Correct me if I'm wrong. ... When a native Pulumi docker provider? 😂
t
That could be… I’m not that familiar with it.
When a native Pulumi docker provider?
It’s on our roadmap, I believe. Maybe within a quarter or so.
c
@tall-librarian-49374 do you think I can schedule a short meeting with someone of you expert on that topic or it is pretty impossible? Thank you!
t
I’m currently on vacation and everyone is on crunch for PulumiUP next week. Would end of next week be too late?
c
The end of the next week could be perfect but on Friday I'll be at Global Azure Bootcamp in Turin. On May 9th? Sorry I didn't want to disturb you on vacation! 😭
b
@cold-insurance-72507 can you share a github repo with your code in? I can have a look and see what’s going on
And also what the current problem is? The threads got kinda long so I’m not sure where you’ve actually got to
c
sure @brave-planet-10645 thank you https://github.com/andrekiba/CrazyBike it is still a very work in progress!
in brief: using the Image resource of the docker provider leads to a change in the resource every time you do a pulumi pre or up, also in case of no changes in code. Because the image is the source of an Azure Container App this means a new app revision every time. Most of the problems about the Image are linked here https://github.com/pulumi/pulumi-docker/issues/132 As you can see in the repo I'm playing with RegistryImage also to try to find a solution but also this resource has a lot of problems.
@brave-planet-10645 if you have the possibility to read the thread 😂 everything is explained quite better than my summary
b
@cold-insurance-72507 a lot of the problems you're describing are inherit problems from the docker provider we aim to fix, but won't be able to do so before your talk A customer has created a buildkit based provider, maybe you could try that? https://github.com/MaterializeInc/pulumi-docker-buildkit
c
@billowy-army-68599 I saw that repo and could be good but I'm using C# and that eventually means another project in typescript just to build the images and then pass outputs to the other...I think could be just a little bit messy to show as a solution 😅 At the end the main topic of the talk is to show that pulumi can manage both, the creation of the infrastructure but also the deploy of new versions of the application as soon as the code changes. To do this I have an azure devops pipeline with the pulumi task. Show this could be also good because actually the only way to implement a CI-CD pipeline with Azure Container Apps is through GitHub Actions. https://docs.microsoft.com/en-us/azure/container-apps/github-actions-cli?tabs=bash Having the possibility to manage it in Azure DevOps with just a single task could be a plus and is what I want to show...at least was my idea 😅
@brave-planet-10645 did you have a chance to look at the repo? May we setup a short call tomorrow or Wednesday with someone expert on Docker? I just want to ask what I can do to mitigate the problems that the provider has. Thank you.
b
I looked at the repo and I don’t see anything particularly wrong there. I have seen the issue you’re having before where even though you don’t make any changes, the docker provider does a build with a new commit. Unfortunately it’s an issue with the upstream provider which we have no control over.
c
ok @brave-planet-10645 but there are other problems, so for example try to use the RegistryImage on windows and tell me if are you able to build a context in a correct way... ...seems impossibile because doesn't understand something like C: as full path... Ok I can understand that is an upstream provider problem 😅 but if nothing works just don't use it... I'm sorry but I'm quite frustrated and sincerely the ping-pong "it's not our fault" it is not very constructive...looking at the github issues many are more than one year old...and still without a solution. I need some help here, is someone that can help me?? Thank you for your help.
b
I don’t have access to a Windows machine here. However, I’m looking at the “buy” section of your code in more details. You’re pointing the contact at the
CrazyBike.Buy
code (which is the application code), right? But the docker file is in the
src
folder. Why isn’t it in the
CrazyBike.Buy
folder, because I think that might be one of the problems here?
c
@brave-planet-10645 as mentioned before with @tall-librarian-49374 because seems that the
RegistryImage
is only able to find a dockerfile if it is placed AT THE ROOT of the context 😭 ...and in a real solution that is not a trivial example most of the time the context folder needs to be a parent directory (for example here because I have the CrazyBike.Shared that must be passed into the context). Using the
Image
(not
RegistryImage
) this problem is not present (but there are many others...). So I decided to move dockerfile(s) outside of each project...at the root level.
In the meantime I also ask if there is a way to see a log from the upstream terraform provider to understand what happens... As I said the docker build of the RegistryImage doesn't work on windows butit's not easy to understand why just looking at the final pulumi error
b
Here’s a link to our docs which describe how to get more verbose logs: https://www.pulumi.com/docs/troubleshooting/#verbose-logging
👍 1
c
tried v=9 but the output is the same, maybe because another bug about RegistryImage says that it's not really a pulumi resource and so oit is not possibile to understand what happens 😂
Sorry @brave-planet-10645 can you confirm that the upstream pulumi docker provider is https://github.com/kreuzwerker/terraform-provider-docker and not https://github.com/hashicorp/terraform-provider-docker ?
b
that's correct
👍 1
c
@billowy-army-68599 do you have an idea about the build problem on windows with
RegistryImage
? Thanks!
b
no I'm afraid not, the best I can recommend is opening an issue, we know there are problems with the docker provider that need to be fixed
c
Thanks @billowy-army-68599 I commented this https://github.com/kreuzwerker/terraform-provider-docker/issues/325 @faint-table-42725 I have seen a lot of your comments on
RegistryImage
and your trick about hashing the context https://github.com/pulumi/pulumi-docker/issues/132#issuecomment-812234817, can you maybe help me on this?