How to upload file to an FTP Server from Azure?

Hello Everyone,

I am very new to Octopus Deploy so forgive me for my ignorance. I have an FTP server where I need to upload my Angular Website. The source repo is configured in Azure so at first, I tried deployment using Azure pipelines. My hosting provider is a cheap provider so they are not giving me a lot of options to configure hosting. They have told me that I can upload files using any FTP client that supports passive mode. I want to automate this deployment process, so I would like to use Octopus Deploy to upload files to FTP server. I have just signed up for free tier and created a Cloud instance. The issue I am facing now is that I cannot create a target since I only have the FTP information of the host. Another problem I am facing is that I am not sure which process step to use for my task? Can somone please guide me on how can I deploy my website to a remote FTP server from Azure?

Thanks in advance.

Hi syed_afraz_ali,

Thanks a lot for reaching out. I’m here to work with you until you’re up and running and to answer any you questions you have.

We have a Step Template that you will be able to utilize in your project, which is fairly straightforward and allows you to upload information to your hosts FTP Server.

I don’t have all your hosts details, so I can’t test it out myself, but that step will be the best place to start. After you create a project and when you are adding a step - just type in “ftp” in the search box and you should see the Step Template I am talking about.

The great news is, because you are using Octopus Cloud, you will be able to set the Execution location to “Run once on a Worker”. If you choose the “Default Worker pool”, you won’t need to create a target as one will be dynamically allocated to run the script. You can just fill in the FTP details within the script step itself and deploy.

upload ftp

If you need to check or make some slight modification to the way the code works, you can click on the blue text Upload files by FTP from the image above and see exactly how the script works.

I hope this helps! Let me know how you go and please reach out if you need any more help.

Regards,

Dane

Hello Dane,
Thank you for your help! I was able to make some progress. I was able to upload package from Azure to my Octopus cloud instance. I can see it under library tab. Next, I created a step to upload file to FTP server like you mentioned and tried to create a release but got an error. Here is the log:

Leasing a dynamic worker

August 5th 2020 12:17:55

Info

Worker not ready, waiting 30s

August 5th 2020 12:18:25

Info

Obtained worker lease successfully.

August 5th 2020 12:18:25

Info

Leased worker 20-08-05-0141-jwu6h from pool Default Worker Pool (lease Leases-11858562).

August 5th 2020 12:18:26

Info

The version 13.0.10 of the Calamari.netfx tool has not been extracted, it will be extracted automatically.

August 5th 2020 12:18:44

Info

Version 13.0.10 of the Calamari.netfx tool has been extracted successfully

August 5th 2020 12:18:50

Error

OperationStopped: No value was set for Path to WinSCP .NET Assembly, and it cannot be empty

August 5th 2020 12:18:50

Error

At C:\Octopus\Tentacle\Work\20200805021845-228-5\Script.ps1:26 char:9

August 5th 2020 12:18:50

Error

  • throw "No value was set for $parameterName, and it cannot be …

August 5th 2020 12:18:50

Error

  • 
    

August 5th 2020 12:18:50

Error

at Validate-Parameter, C:\Octopus\Tentacle\Work\20200805021845-228-5\Script.ps1: line 26

August 5th 2020 12:18:50

Error

at , C:\Octopus\Tentacle\Work\20200805021845-228-5\Script.ps1: line 126

August 5th 2020 12:18:50

Error

at , C:\Octopus\Tentacle\Work\20200805021845-228-5\Bootstrap.Script.ps1: line 1679

August 5th 2020 12:18:50

Error

at , : line 1

August 5th 2020 12:18:50

Error

at , : line 1

August 5th 2020 12:18:50

Fatal

The remote script failed with exit code 1

August 5th 2020 12:18:50

Fatal

The action FTP Upload on a Worker failed

Can you please tell me how to install the Winscp assembly on my cloud instance?

Secondly I have a question. How is this step able to figure out which package to deploy? It seems like there is no relation between this step and the package that I have uploaded. What if I want to deploy a specific version of package from library tab?

Thanks
Afraz

Hi Afraz,

Great news that you are progressing!

Can you please tell me how to install the Winscp assembly on my cloud instance?

If you create a step within your project - “Run a Script”. I’ve quickly put together a Powershell script that will install WinSCP (you can specify whatever version you require). It also provides the location of the installed module.

Install-Module -Name WinSCP -RequiredVersion 5.13.7.0 -Force
Import-Module WinSCP
$env:PSModulePath
Get-Module -Name "WinSCP" #Proof that it installed
Get-ChildItem -Path "C:\Program Files\WindowsPowerShell\Modules" | Where-object {$_.Name -eq "WinSCP"}

You will have to put together a couple of checks and balances but hopefully the script will get you started.

Secondly I have a question. How is this step able to figure out which package to deploy? It seems like there is no relation between this step and the package that I have uploaded.

This is a community supplied step template. The script that runs is available to view by clicking on the Upload files by FTP link. The picture I attached to my last reply shows the link and this is the best way to understand the inner workings of a step template.

Looking into the script - It looks for a step with the name provided in “Package Step Name”. Once it finds that step, it will attempt to determine the variable “InstallationDirectoryPath” or more precisely: “Octopus.Action[$stepName].Output.Package.InstallationDirectoryPath”.

If you aren’t familiar with variables within Octopus and their usage, start by having a read through this part of our documentation: https://octopus.com/docs/projects/variables

What if I want to deploy a specific version of package from library tab?

This will most likely require some modification to the script. This link here should provide all the information you need to get started, on referencing packages from within a script: https://octopus.com/blog/script-step-packages

Feel free to reach out if you hit any more bottle-necks or problems.

Regards,

Dane

Hi Dane,

Thank you for providing more context. Unfortunately, I am still struggling to get my first deployment done :frowning:

I have added a step to install WInSCP. However, the documentation of Upload FTP Files step states that before this step I need to add “Deploy a Package” step. Which makes sense because like I mentioned above, it was confusing which package will be deployed by this step?

Now the problem is that if I try to add a “Deploy a Package” step, it asks me to select a role, but in my case, there is no role defined. Sorry for being a total newbie but I am struggling to understand how I can make it work. Can you please show me a working example of steps that should upload files to an FTP server?

Thanks,
Afraz

Hi Syed,

I understand completely that Octopus can be a bit daunting at first. I would highly recommend taking a step back to get a simple Deployment working. We have a “Hello World” series available here:

This will give you the building blocks and understanding of a lot of the terms and theory around how to deploy, using Roles, Projects and Environments. This will save you time in the future, when you start working on more advanced deployments. You can also find some good information on other concepts within the documentation, especially if video tutorials are not for you. Here’s a page on the concept of Roles: https://octopus.com/docs/getting-started/octopus-concepts/target-roles

You have indeed pointed out a flaw in the “Upload FTP Files” step template. The fact that the step template cannot deploy a package without it being deployed to a target first is not ideal. The Step template was created before the introduction of the worker concept, which is why it is the way that it is, so it could use an update. We usually leave it up to the community to improve the community step templates. If you want to make changes to the step template, feel free to submit a pull request with the updated code.

If you chose to use this community step, you would need to deploy to a target first. In order to do that, you would need to create a deployment target first.

Pre Step 1: Create a Deployment Target: https://octopus.com/docs/infrastructure/deployment-targets
Step 1: Deploy a Package:
Step 2: Upload Files by FTP

Within the Upload Files by FTP step - you would reference the package from step 1. If you are unsure on how to do this, please check the link at the bottom of this reply (referencing packages).

If we were to ignore the community step, you could use powershell (or whatever language you are familiar with that is supported by Octopus) and deploy via a worker, by running this script:

# create the FtpWebRequest and configure it
$ftp = [System.Net.FtpWebRequest]::Create("ftp://ftphost")
$ftp = [System.Net.FtpWebRequest]$ftp
$ftp.Method = [System.Net.WebRequestMethods+Ftp]::UploadFile
$ftp.Credentials = new-object System.Net.NetworkCredential("anonymous","anonymous@localhost")
$ftp.UseBinary = $true
$ftp.UsePassive = $true
# read in the file to upload as a byte array
$Package = $OctopusParameters["Octopus.Action.Package[NugetTesting.Package].PackageFilePath"]
$content = [System.IO.File]::ReadAllBytes("$Package")
$ftp.ContentLength = $content.Length
# get the request stream, and write the bytes into it
$rs = $ftp.GetRequestStream()
$rs.Write($content, 0, $content.Length)
# be sure to clean up after ourselves
$rs.Close()
$rs.Dispose()

So to be clear - you would only need one step, which would be a “Deploy a Script”.

You would also need to reference the package within the same script step:

If you are unsure of how I determined the package variable to use in the Powershell script, please refer to this guide: https://octopus.com/docs/deployment-examples/custom-scripts/run-a-script-step#referencing-packages.

This is probably as close to a working example as I can provide for you, without knowing the ftp service you are using and it’s capabilities.

Hopefully this helps!

Regards,

Dane

Hi Afraz,

I thought I would provide another update on this one.

One of the Engineering team had a little bit of spare time and gave that community step a spit and polish.

The step has been updated to be able to choose a package from the package store. The PR will still need to be reviewed and then updated - so this may take a day or two, however it is on it’s way.

Thanks for helping to shape Octopus!

Regards,

Dane

Hi Dane,

That’s wonderful! I will definetly give it another shot once the PR is merged to the community step.

I am studying more about Octopus meanwhile and also went through the links that you shared but I think my case is that there are not much options for a uploading to FTP directory. For example you mentioned that I should create a deployment target. I don’t think you can create a deployment target for a FTP directory in Octopus, or maybe I missed something. That is the reason I went for this approach.

A custom script to upload files on the FTP server via PS seems a good option but then I could have done the same thing from the Azure release pipeline. I know Octopus is much more powerful in so many aspects but I was thinking that since uploading files via FTP is a common task, it will be really easy to implement in Octopus. Azure seems to lack this functionality as well!

Having said that, I will definitely give it a try once the community step is updated. I am learning a lot too due to this exercise :slight_smile: